merb-core 0.9.13 → 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. data/Rakefile +5 -3
  2. data/lib/merb-core.rb +84 -41
  3. data/lib/merb-core/bootloader.rb +71 -60
  4. data/lib/merb-core/config.rb +31 -17
  5. data/lib/merb-core/controller/abstract_controller.rb +35 -35
  6. data/lib/merb-core/controller/exceptions.rb +14 -9
  7. data/lib/merb-core/controller/merb_controller.rb +22 -20
  8. data/lib/merb-core/controller/mime.rb +5 -5
  9. data/lib/merb-core/controller/mixins/authentication.rb +11 -8
  10. data/lib/merb-core/controller/mixins/conditional_get.rb +7 -7
  11. data/lib/merb-core/controller/mixins/controller.rb +15 -15
  12. data/lib/merb-core/controller/mixins/render.rb +16 -16
  13. data/lib/merb-core/controller/mixins/responder.rb +23 -23
  14. data/lib/merb-core/controller/template.rb +17 -17
  15. data/lib/merb-core/core_ext/hash.rb +2 -2
  16. data/lib/merb-core/core_ext/kernel.rb +19 -18
  17. data/lib/merb-core/dispatch/cookies.rb +13 -0
  18. data/lib/merb-core/dispatch/default_exception/default_exception.rb +12 -1
  19. data/lib/merb-core/dispatch/dispatcher.rb +6 -5
  20. data/lib/merb-core/dispatch/request.rb +56 -52
  21. data/lib/merb-core/dispatch/request_parsers.rb +7 -7
  22. data/lib/merb-core/dispatch/router.rb +14 -14
  23. data/lib/merb-core/dispatch/router/behavior.rb +31 -31
  24. data/lib/merb-core/dispatch/router/cached_proc.rb +13 -1
  25. data/lib/merb-core/dispatch/router/resources.rb +9 -9
  26. data/lib/merb-core/dispatch/router/route.rb +60 -7
  27. data/lib/merb-core/dispatch/session.rb +21 -15
  28. data/lib/merb-core/dispatch/session/container.rb +10 -8
  29. data/lib/merb-core/dispatch/session/cookie.rb +12 -11
  30. data/lib/merb-core/dispatch/session/memcached.rb +4 -2
  31. data/lib/merb-core/dispatch/session/memory.rb +8 -6
  32. data/lib/merb-core/dispatch/session/store_container.rb +6 -5
  33. data/lib/merb-core/dispatch/worker.rb +28 -10
  34. data/lib/merb-core/gem_ext/erubis.rb +4 -2
  35. data/lib/merb-core/logger.rb +3 -22
  36. data/lib/merb-core/plugins.rb +5 -5
  37. data/lib/merb-core/rack.rb +1 -1
  38. data/lib/merb-core/rack/adapter.rb +5 -1
  39. data/lib/merb-core/rack/adapter/abstract.rb +15 -10
  40. data/lib/merb-core/rack/adapter/ebb.rb +4 -2
  41. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -1
  42. data/lib/merb-core/rack/adapter/fcgi.rb +3 -1
  43. data/lib/merb-core/rack/adapter/irb.rb +10 -1
  44. data/lib/merb-core/rack/adapter/mongrel.rb +5 -2
  45. data/lib/merb-core/rack/adapter/runner.rb +3 -1
  46. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +2 -1
  47. data/lib/merb-core/rack/adapter/thin.rb +4 -1
  48. data/lib/merb-core/rack/adapter/thin_turbo.rb +1 -0
  49. data/lib/merb-core/rack/adapter/webrick.rb +8 -34
  50. data/lib/merb-core/rack/application.rb +2 -2
  51. data/lib/merb-core/rack/handler/mongrel.rb +7 -0
  52. data/lib/merb-core/rack/helpers.rb +1 -1
  53. data/lib/merb-core/rack/middleware.rb +7 -1
  54. data/lib/merb-core/rack/middleware/conditional_get.rb +3 -0
  55. data/lib/merb-core/rack/middleware/content_length.rb +2 -0
  56. data/lib/merb-core/rack/middleware/path_prefix.rb +4 -0
  57. data/lib/merb-core/rack/middleware/profiler.rb +3 -1
  58. data/lib/merb-core/rack/middleware/static.rb +7 -1
  59. data/lib/merb-core/rack/middleware/tracer.rb +1 -0
  60. data/lib/merb-core/rack/stream_wrapper.rb +35 -30
  61. data/lib/merb-core/server.rb +17 -16
  62. data/lib/merb-core/tasks/gem_management.rb +1 -1
  63. data/lib/merb-core/tasks/merb.rb +3 -1
  64. data/lib/merb-core/tasks/merb_rake_helper.rb +1 -1
  65. data/lib/merb-core/test.rb +8 -8
  66. data/lib/merb-core/test/helpers.rb +1 -1
  67. data/lib/merb-core/test/helpers/cookie_jar.rb +16 -2
  68. data/lib/merb-core/test/helpers/mock_request_helper.rb +13 -13
  69. data/lib/merb-core/test/helpers/request_helper.rb +1 -1
  70. data/lib/merb-core/test/helpers/route_helper.rb +2 -2
  71. data/lib/merb-core/test/matchers.rb +3 -3
  72. data/lib/merb-core/test/matchers/request_matchers.rb +1 -1
  73. data/lib/merb-core/test/run_spec.rb +1 -1
  74. data/lib/merb-core/test/tasks/spectasks.rb +1 -1
  75. data/lib/merb-core/test/test_ext/hpricot.rb +1 -1
  76. data/lib/merb-core/test/test_ext/rspec.rb +2 -2
  77. data/lib/merb-core/test/test_ext/string.rb +1 -1
  78. data/lib/merb-core/version.rb +1 -1
  79. metadata +8 -22
  80. data/lib/merb-core/test/matchers/view_matchers.rb +0 -231
  81. data/lib/merb-core/test/webrat.rb +0 -37
  82. data/lib/merb-core/vendor/nokogiri/css.rb +0 -6
  83. data/lib/merb-core/vendor/nokogiri/css/generated_parser.rb +0 -653
  84. data/lib/merb-core/vendor/nokogiri/css/generated_tokenizer.rb +0 -159
  85. data/lib/merb-core/vendor/nokogiri/css/node.rb +0 -95
  86. data/lib/merb-core/vendor/nokogiri/css/parser.rb +0 -24
  87. data/lib/merb-core/vendor/nokogiri/css/parser.y +0 -198
  88. data/lib/merb-core/vendor/nokogiri/css/tokenizer.rb +0 -9
  89. data/lib/merb-core/vendor/nokogiri/css/tokenizer.rex +0 -63
  90. data/lib/merb-core/vendor/nokogiri/css/xpath_visitor.rb +0 -159
@@ -1,18 +1,18 @@
1
- # begin
2
- # require "hpricot"
3
- # require 'merb-core/test/test_ext/hpricot'
4
- # rescue
5
- # end
6
-
7
1
  require 'merb-core/test/test_ext/object'
8
2
  require 'merb-core/test/test_ext/string'
9
3
 
10
4
  module Merb; module Test; end; end
11
5
 
12
6
  require 'merb-core/test/helpers'
13
- require 'merb-core/test/webrat'
7
+
8
+ begin
9
+ require 'webrat'
10
+ require 'webrat/merb'
11
+ rescue LoadError => e
12
+ Merb.fatal! "Couldn't load Webrat. You should run: sudo gem install webrat", e
13
+ end
14
14
 
15
15
  if Merb.test_framework.to_s == "rspec"
16
16
  require 'merb-core/test/test_ext/rspec'
17
17
  require 'merb-core/test/matchers'
18
- end
18
+ end
@@ -7,4 +7,4 @@ require "merb-core/test/helpers/mock_request_helper"
7
7
  require "merb-core/test/helpers/route_helper"
8
8
  require "merb-core/test/helpers/request_helper"
9
9
  require "merb-core/test/helpers/multipart_request_helper"
10
- require "merb-core/test/helpers/controller_helper"
10
+ require "merb-core/test/helpers/controller_helper"
@@ -4,8 +4,10 @@ module Merb
4
4
  module Test
5
5
  class Cookie
6
6
 
7
+ # :api: private
7
8
  attr_reader :name, :value
8
9
 
10
+ # :api: private
9
11
  def initialize(raw, default_host)
10
12
  # separate the name / value pair from the cookie options
11
13
  @name_value_raw, options = raw.split(/[;,] */n, 2)
@@ -18,39 +20,48 @@ module Merb
18
20
  @options["domain"] ||= default_host
19
21
  end
20
22
 
23
+ # :api: private
21
24
  def raw
22
25
  @name_value_raw
23
26
  end
24
27
 
28
+ # :api: private
25
29
  def empty?
26
30
  @value.nil? || @value.empty?
27
31
  end
28
32
 
33
+ # :api: private
29
34
  def domain
30
35
  @options["domain"]
31
36
  end
32
-
37
+
38
+ # :api: private
33
39
  def path
34
40
  @options["path"] || "/"
35
41
  end
36
42
 
43
+ # :api: private
37
44
  def expires
38
45
  Time.parse(@options["expires"]) if @options["expires"]
39
46
  end
40
47
 
48
+ # :api: private
41
49
  def expired?
42
50
  expires && expires < Time.now
43
51
  end
44
52
 
53
+ # :api: private
45
54
  def valid?(uri)
46
55
  uri.host =~ Regexp.new("#{Regexp.escape(domain)}$") &&
47
56
  uri.path =~ Regexp.new("^#{Regexp.escape(path)}")
48
57
  end
49
58
 
59
+ # :api: private
50
60
  def matches?(uri)
51
61
  ! expired? && valid?(uri)
52
62
  end
53
63
 
64
+ # :api: private
54
65
  def <=>(other)
55
66
  # Orders the cookies from least specific to most
56
67
  [name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse]
@@ -60,10 +71,12 @@ module Merb
60
71
 
61
72
  class CookieJar
62
73
 
74
+ # :api: private
63
75
  def initialize
64
76
  @jars = {}
65
77
  end
66
78
 
79
+ # :api: private
67
80
  def update(jar, uri, raw_cookies)
68
81
  return unless raw_cookies
69
82
  # Initialize all the the received cookies
@@ -85,6 +98,7 @@ module Merb
85
98
  @jars[jar].sort!
86
99
  end
87
100
 
101
+ # :api: private
88
102
  def for(jar, uri)
89
103
  cookies = {}
90
104
 
@@ -103,4 +117,4 @@ module Merb
103
117
 
104
118
  end
105
119
  end
106
- end
120
+ end
@@ -74,7 +74,7 @@ module Merb
74
74
  # ==== Notes
75
75
  # If you pass a post body, the content-type will be set to URL-encoded.
76
76
  #
77
- # @api public
77
+ # :api: public
78
78
  # @deprecated
79
79
  def fake_request(env = {}, opt = {})
80
80
  if opt[:post_body]
@@ -111,7 +111,7 @@ module Merb
111
111
  # ==== Notes
112
112
  # Does not use routes.
113
113
  #
114
- # @api public
114
+ # :api: public
115
115
  # @deprecated
116
116
  def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
117
117
  params = merge_controller_and_action(controller_klass, action, params)
@@ -125,7 +125,7 @@ module Merb
125
125
  # *controller_classes:: Controller classes to operate on in the context of the block.
126
126
  # &blk:: The context to operate on; optionally accepts the cookie jar as an argument.
127
127
  #
128
- # @api public
128
+ # :api: public
129
129
  # @deprecated
130
130
  def with_cookies(*controller_classes, &blk)
131
131
  cookie_jar = CookieJar.new
@@ -169,7 +169,7 @@ module Merb
169
169
  # ==== Notes
170
170
  # Does not use routes.
171
171
  #
172
- # @api public
172
+ # :api: public
173
173
  # @deprecated
174
174
  def dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk)
175
175
  env["X_HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{username}:#{password}")}"
@@ -178,7 +178,7 @@ module Merb
178
178
  dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
179
179
  end
180
180
 
181
- # @api private
181
+ # :api: private
182
182
  def merge_controller_and_action(controller_klass, action, params)
183
183
  params[:controller] = controller_klass.name.to_const_path
184
184
  params[:action] = action.to_s
@@ -207,7 +207,7 @@ module Merb
207
207
  # ==== Notes
208
208
  # Does not use routes.
209
209
  #
210
- # @api public
210
+ # :api: public
211
211
  # @deprecated
212
212
  def build_request(params = {}, env = {})
213
213
  params = Merb::Parse.params_to_query_string(params)
@@ -232,7 +232,7 @@ module Merb
232
232
  # The controller is yielded to the block provided for actions *prior* to
233
233
  # the action being dispatched.
234
234
  #
235
- # @api public
235
+ # :api: public
236
236
  # @deprecated
237
237
  def get(path, params = {}, env = {}, &block)
238
238
  env[:request_method] = "GET"
@@ -252,7 +252,7 @@ module Merb
252
252
  # The controller is yielded to the block provided for actions *prior* to
253
253
  # the action being dispatched.
254
254
  #
255
- # @api public
255
+ # :api: public
256
256
  # @deprecated
257
257
  def post(path, params = {}, env = {}, &block)
258
258
  env[:request_method] = "POST"
@@ -272,7 +272,7 @@ module Merb
272
272
  # The controller is yielded to the block provided for actions *prior* to
273
273
  # the action being dispatched.
274
274
  #
275
- # @api public
275
+ # :api: public
276
276
  def put(path, params = {}, env = {}, &block)
277
277
  env[:request_method] = "PUT"
278
278
  mock_request(path, params, env, &block)
@@ -291,7 +291,7 @@ module Merb
291
291
  # The controller is yielded to the block provided for actions *prior* to
292
292
  # the action being dispatched.
293
293
  #
294
- # @api public
294
+ # :api: public
295
295
  # @deprecated
296
296
  def delete(path, params = {}, env = {}, &block)
297
297
  env[:request_method] = "DELETE"
@@ -320,7 +320,7 @@ module Merb
320
320
  # ==== Notes
321
321
  # Uses Routes.
322
322
  #
323
- # @api plugin
323
+ # :api: plugin
324
324
  # @deprecated
325
325
  def mock_request(path, params = {}, env= {}, &block)
326
326
  env[:request_method] ||= "GET"
@@ -359,7 +359,7 @@ module Merb
359
359
  # ==== Notes
360
360
  # Does not use routes.
361
361
  #
362
- # @api public
362
+ # :api: public
363
363
  # @deprecated
364
364
  def dispatch_request(request, controller_klass, action, &blk)
365
365
  controller = controller_klass.new(request)
@@ -385,7 +385,7 @@ module Merb
385
385
  # ==== Returns
386
386
  # Hash:: The parameters built based on the matching route.
387
387
  #
388
- # @api plugin
388
+ # :api: plugin
389
389
  # @deprecated
390
390
  def check_request_for_route(request)
391
391
  match = ::Merb::Router.match(request)
@@ -78,4 +78,4 @@ module Merb
78
78
  def response_for(*args) request(*args) end
79
79
  end
80
80
  end
81
- end
81
+ end
@@ -56,7 +56,7 @@ module Merb
56
56
  #
57
57
  # url(:articles, 2008, 10, "test_article")
58
58
  #
59
- # @api public
59
+ # :api: public
60
60
  def url(*args)
61
61
  args << (@request_params || {})
62
62
  Merb::Router.url(*args)
@@ -90,4 +90,4 @@ module Merb
90
90
  end
91
91
  end
92
92
  end
93
- end
93
+ end
@@ -2,12 +2,12 @@ module Merb::Test::Rspec; end
2
2
 
3
3
  require "merb-core/test/matchers/controller_matchers"
4
4
  require "merb-core/test/matchers/route_matchers"
5
- require "merb-core/test/matchers/view_matchers"
6
5
  require "merb-core/test/matchers/request_matchers"
7
6
 
8
7
  Merb::Test::ControllerHelper.send(:include, Merb::Test::Rspec::ControllerMatchers)
9
8
  Merb::Test::RouteHelper.send(:include, Merb::Test::Rspec::RouteMatchers)
10
9
 
11
10
  module Merb::Test::ViewHelper
12
- include Merb::Test::Rspec::ViewMatchers
13
- end
11
+ include ::Webrat::Matchers
12
+ include ::Webrat::HaveTagMatcher
13
+ end
@@ -123,4 +123,4 @@ Spec::Matchers.create(:redirect_to) do
123
123
  "<#{location}>, but it redirected to <#{rack.headers["Location"]}>"
124
124
  end
125
125
  end
126
- end
126
+ end
@@ -37,4 +37,4 @@ def run_spec(spec, base_dir)
37
37
  exit!(failure ? -1 : 0)
38
38
  end
39
39
 
40
- run_spec(ARGV[0], File.expand_path(File.join(File.dirname(__FILE__), "..", "..", ".."))) if ENV["NOW"]
40
+ run_spec(ARGV[0], File.expand_path(File.join(File.dirname(__FILE__), "..", "..", ".."))) if ENV["NOW"]
@@ -75,4 +75,4 @@ namespace :spec do
75
75
  t.rcov = true
76
76
  t.rcov_opts = ["--exclude 'config,spec,#{Gem::path.join(',')}'"]
77
77
  end
78
- end
78
+ end
@@ -29,4 +29,4 @@ class Hpricot::Elem
29
29
  child.is_a?(Hpricot::Text) ? child.content : ((child.respond_to?("inner_text") && child.inner_text) || "")
30
30
  end.join.strip
31
31
  end
32
- end
32
+ end
@@ -40,11 +40,11 @@ module Merb
40
40
  end
41
41
 
42
42
  class ExampleGroup < Spec::Example::ExampleGroup
43
-
44
43
  include ::Merb::Test::Matchers
45
44
  include ::Merb::Test::RouteHelper
46
45
  include ::Merb::Test::ControllerHelper
47
-
46
+ include ::Webrat::Methods
47
+
48
48
  class << self
49
49
  # This is a copy of the method in rspec, so we can have
50
50
  # describe "...", :when => "logged in", and the like
@@ -11,4 +11,4 @@ class String
11
11
 
12
12
  alias_method :matches?, :match?
13
13
 
14
- end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Merb
2
- VERSION = '0.9.13' unless defined?(Merb::VERSION)
2
+ VERSION = '1.0' unless defined?(Merb::VERSION)
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merb-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.13
4
+ version: "1.0"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-03 00:00:00 -08:00
12
+ date: 2008-11-07 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -83,24 +83,24 @@ dependencies:
83
83
  version: "0"
84
84
  version:
85
85
  - !ruby/object:Gem::Dependency
86
- name: hpricot
86
+ name: thor
87
87
  type: :runtime
88
88
  version_requirement:
89
89
  version_requirements: !ruby/object:Gem::Requirement
90
90
  requirements:
91
91
  - - ">="
92
92
  - !ruby/object:Gem::Version
93
- version: "0"
93
+ version: 0.9.7
94
94
  version:
95
95
  - !ruby/object:Gem::Dependency
96
- name: thor
97
- type: :runtime
96
+ name: webrat
97
+ type: :development
98
98
  version_requirement:
99
99
  version_requirements: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 0.9.7
103
+ version: 0.3.1
104
104
  version:
105
105
  description: Merb. Pocket rocket web framework.
106
106
  email: ez@engineyard.com
@@ -220,7 +220,6 @@ files:
220
220
  - lib/merb-core/test/matchers/controller_matchers.rb
221
221
  - lib/merb-core/test/matchers/request_matchers.rb
222
222
  - lib/merb-core/test/matchers/route_matchers.rb
223
- - lib/merb-core/test/matchers/view_matchers.rb
224
223
  - lib/merb-core/test/matchers.rb
225
224
  - lib/merb-core/test/run_spec.rb
226
225
  - lib/merb-core/test/run_specs.rb
@@ -231,20 +230,7 @@ files:
231
230
  - lib/merb-core/test/test_ext/object.rb
232
231
  - lib/merb-core/test/test_ext/rspec.rb
233
232
  - lib/merb-core/test/test_ext/string.rb
234
- - lib/merb-core/test/webrat.rb
235
233
  - lib/merb-core/test.rb
236
- - lib/merb-core/vendor
237
- - lib/merb-core/vendor/nokogiri
238
- - lib/merb-core/vendor/nokogiri/css
239
- - lib/merb-core/vendor/nokogiri/css/generated_parser.rb
240
- - lib/merb-core/vendor/nokogiri/css/generated_tokenizer.rb
241
- - lib/merb-core/vendor/nokogiri/css/node.rb
242
- - lib/merb-core/vendor/nokogiri/css/parser.rb
243
- - lib/merb-core/vendor/nokogiri/css/parser.y
244
- - lib/merb-core/vendor/nokogiri/css/tokenizer.rb
245
- - lib/merb-core/vendor/nokogiri/css/tokenizer.rex
246
- - lib/merb-core/vendor/nokogiri/css/xpath_visitor.rb
247
- - lib/merb-core/vendor/nokogiri/css.rb
248
234
  - lib/merb-core/version.rb
249
235
  - lib/merb-core.rb
250
236
  has_rdoc: true
@@ -264,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
250
  requirements:
265
251
  - - ">="
266
252
  - !ruby/object:Gem::Version
267
- version: "0"
253
+ version: 1.3.0
268
254
  version:
269
255
  requirements:
270
256
  - install the json gem to get faster json parsing
@@ -1,231 +0,0 @@
1
- module Merb::Test::Rspec::ViewMatchers
2
-
3
- class HaveXpath
4
- def initialize(expected, &block)
5
- # Require nokogiri and fall back on rexml
6
- begin
7
- require "nokogiri"
8
- rescue LoadError => e
9
- if require "rexml/document"
10
- require "merb-core/vendor/nokogiri/css"
11
- warn("Standard REXML library is slow. Please consider installing nokogiri.\nUse \"sudo gem install nokogiri\"")
12
- end
13
- end
14
-
15
- @expected = expected
16
- @block = block
17
- end
18
-
19
- def matches?(stringlike)
20
- if defined?(Nokogiri::XML)
21
- matches_nokogiri?(stringlike)
22
- else
23
- matches_rexml?(stringlike)
24
- end
25
- end
26
-
27
- def matches_rexml?(stringlike)
28
- stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
29
-
30
- @document = case stringlike
31
- when REXML::Document
32
- stringlike.root
33
- when REXML::Node
34
- stringlike
35
- when StringIO, String
36
- begin
37
- REXML::Document.new(stringlike.to_s).root
38
- rescue REXML::ParseException => e
39
- if e.message.include?("second root element")
40
- REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
41
- else
42
- raise e
43
- end
44
- end
45
- end
46
-
47
- query.all? do |q|
48
- matched = REXML::XPath.match(@document, q)
49
- matched.any? && (!block_given? || matched.all?(&@block))
50
- end
51
- end
52
-
53
- def matches_nokogiri?(stringlike)
54
- stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
55
-
56
- @document = case stringlike
57
- when Nokogiri::HTML::Document, Nokogiri::XML::NodeSet
58
- stringlike
59
- when StringIO
60
- Nokogiri::HTML(stringlike.string)
61
- else
62
- Nokogiri::HTML(stringlike.to_s)
63
- end
64
- @document.xpath(*query).any?
65
- end
66
-
67
- def query
68
- [@expected].flatten.compact
69
- end
70
-
71
- # ==== Returns
72
- # String:: The failure message.
73
- def failure_message
74
- "expected following text to match xpath #{@expected}:\n#{@document}"
75
- end
76
-
77
- # ==== Returns
78
- # String:: The failure message to be displayed in negative matches.
79
- def negative_failure_message
80
- "expected following text to not match xpath #{@expected}:\n#{@document}"
81
- end
82
- end
83
-
84
- class HaveSelector < HaveXpath
85
-
86
- # ==== Returns
87
- # String:: The failure message.
88
- def failure_message
89
- "expected following text to match selector #{@expected}:\n#{@document}"
90
- end
91
-
92
- # ==== Returns
93
- # String:: The failure message to be displayed in negative matches.
94
- def negative_failure_message
95
- "expected following text to not match selector #{@expected}:\n#{@document}"
96
- end
97
-
98
- def query
99
- Nokogiri::CSS::Parser.parse(*super).map { |ast| ast.to_xpath }
100
- end
101
-
102
- end
103
-
104
- class HaveTag < HaveSelector
105
-
106
- # ==== Returns
107
- # String:: The failure message.
108
- def failure_message
109
- "expected following output to contain a #{tag_inspect} tag:\n#{@document}"
110
- end
111
-
112
- # ==== Returns
113
- # String:: The failure message to be displayed in negative matches.
114
- def negative_failure_message
115
- "expected following output to omit a #{tag_inspect}:\n#{@document}"
116
- end
117
-
118
- def tag_inspect
119
- options = @expected.last.dup
120
- content = options.delete(:content)
121
-
122
- html = "<#{@expected.first}"
123
- options.each do |k,v|
124
- html << " #{k}='#{v}'"
125
- end
126
-
127
- if content
128
- html << ">#{content}</#{@expected.first}>"
129
- else
130
- html << "/>"
131
- end
132
-
133
- html
134
- end
135
-
136
- def query
137
- options = @expected.last.dup
138
- selector = @expected.first.to_s
139
-
140
- selector << ":contains('#{options.delete(:content)}')" if options[:content]
141
-
142
- options.each do |key, value|
143
- selector << "[#{key}='#{value}']"
144
- end
145
-
146
- Nokogiri::CSS::Parser.parse(selector).map { |ast| ast.to_xpath }
147
- end
148
-
149
- end
150
-
151
- class HasContent
152
- def initialize(content)
153
- @content = content
154
- end
155
-
156
- def matches?(element)
157
- element = element.body.to_s if element.respond_to?(:body)
158
- @element = element
159
-
160
- case @content
161
- when String
162
- @element.contains?(@content)
163
- when Regexp
164
- @element.matches?(@content)
165
- end
166
- end
167
-
168
- # ==== Returns
169
- # String:: The failure message.
170
- def failure_message
171
- "expected the following element's content to #{content_message}:\n#{@element.inner_text}"
172
- end
173
-
174
- # ==== Returns
175
- # String:: The failure message to be displayed in negative matches.
176
- def negative_failure_message
177
- "expected the following element's content to not #{content_message}:\n#{@element.inner_text}"
178
- end
179
-
180
- def content_message
181
- case @content
182
- when String
183
- "include \"#{@content}\""
184
- when Regexp
185
- "match #{@content.inspect}"
186
- end
187
- end
188
- end
189
-
190
- # Matches HTML content against a CSS 3 selector.
191
- #
192
- # ==== Parameters
193
- # expected<String>:: The CSS selector to look for.
194
- #
195
- # ==== Returns
196
- # HaveSelector:: A new have selector matcher.
197
- # ---
198
- # @api public
199
- def have_selector(expected)
200
- HaveSelector.new(expected)
201
- end
202
- alias_method :match_selector, :have_selector
203
-
204
- # Matches HTML content against an XPath query
205
- #
206
- # ==== Parameters
207
- # expected<String>:: The XPath query to look for.
208
- #
209
- # ==== Returns
210
- # HaveXpath:: A new have xpath matcher.
211
- # ---
212
- # @api public
213
- def have_xpath(expected)
214
- HaveXpath.new(expected)
215
- end
216
- alias_method :match_xpath, :have_xpath
217
-
218
- def have_tag(name, attributes = {})
219
- HaveTag.new([name, attributes])
220
- end
221
- alias_method :match_tag, :have_tag
222
-
223
- # Matches the contents of an HTML document with
224
- # whatever string is supplied
225
- #
226
- # ---
227
- # @api public
228
- def contain(content)
229
- HasContent.new(content)
230
- end
231
- end