merb-core 0.9.13 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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