merb-core 0.9.13 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -3
- data/lib/merb-core.rb +84 -41
- data/lib/merb-core/bootloader.rb +71 -60
- data/lib/merb-core/config.rb +31 -17
- data/lib/merb-core/controller/abstract_controller.rb +35 -35
- data/lib/merb-core/controller/exceptions.rb +14 -9
- data/lib/merb-core/controller/merb_controller.rb +22 -20
- data/lib/merb-core/controller/mime.rb +5 -5
- data/lib/merb-core/controller/mixins/authentication.rb +11 -8
- data/lib/merb-core/controller/mixins/conditional_get.rb +7 -7
- data/lib/merb-core/controller/mixins/controller.rb +15 -15
- data/lib/merb-core/controller/mixins/render.rb +16 -16
- data/lib/merb-core/controller/mixins/responder.rb +23 -23
- data/lib/merb-core/controller/template.rb +17 -17
- data/lib/merb-core/core_ext/hash.rb +2 -2
- data/lib/merb-core/core_ext/kernel.rb +19 -18
- data/lib/merb-core/dispatch/cookies.rb +13 -0
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +12 -1
- data/lib/merb-core/dispatch/dispatcher.rb +6 -5
- data/lib/merb-core/dispatch/request.rb +56 -52
- data/lib/merb-core/dispatch/request_parsers.rb +7 -7
- data/lib/merb-core/dispatch/router.rb +14 -14
- data/lib/merb-core/dispatch/router/behavior.rb +31 -31
- data/lib/merb-core/dispatch/router/cached_proc.rb +13 -1
- data/lib/merb-core/dispatch/router/resources.rb +9 -9
- data/lib/merb-core/dispatch/router/route.rb +60 -7
- data/lib/merb-core/dispatch/session.rb +21 -15
- data/lib/merb-core/dispatch/session/container.rb +10 -8
- data/lib/merb-core/dispatch/session/cookie.rb +12 -11
- data/lib/merb-core/dispatch/session/memcached.rb +4 -2
- data/lib/merb-core/dispatch/session/memory.rb +8 -6
- data/lib/merb-core/dispatch/session/store_container.rb +6 -5
- data/lib/merb-core/dispatch/worker.rb +28 -10
- data/lib/merb-core/gem_ext/erubis.rb +4 -2
- data/lib/merb-core/logger.rb +3 -22
- data/lib/merb-core/plugins.rb +5 -5
- data/lib/merb-core/rack.rb +1 -1
- data/lib/merb-core/rack/adapter.rb +5 -1
- data/lib/merb-core/rack/adapter/abstract.rb +15 -10
- data/lib/merb-core/rack/adapter/ebb.rb +4 -2
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -1
- data/lib/merb-core/rack/adapter/fcgi.rb +3 -1
- data/lib/merb-core/rack/adapter/irb.rb +10 -1
- data/lib/merb-core/rack/adapter/mongrel.rb +5 -2
- data/lib/merb-core/rack/adapter/runner.rb +3 -1
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +2 -1
- data/lib/merb-core/rack/adapter/thin.rb +4 -1
- data/lib/merb-core/rack/adapter/thin_turbo.rb +1 -0
- data/lib/merb-core/rack/adapter/webrick.rb +8 -34
- data/lib/merb-core/rack/application.rb +2 -2
- data/lib/merb-core/rack/handler/mongrel.rb +7 -0
- data/lib/merb-core/rack/helpers.rb +1 -1
- data/lib/merb-core/rack/middleware.rb +7 -1
- data/lib/merb-core/rack/middleware/conditional_get.rb +3 -0
- data/lib/merb-core/rack/middleware/content_length.rb +2 -0
- data/lib/merb-core/rack/middleware/path_prefix.rb +4 -0
- data/lib/merb-core/rack/middleware/profiler.rb +3 -1
- data/lib/merb-core/rack/middleware/static.rb +7 -1
- data/lib/merb-core/rack/middleware/tracer.rb +1 -0
- data/lib/merb-core/rack/stream_wrapper.rb +35 -30
- data/lib/merb-core/server.rb +17 -16
- data/lib/merb-core/tasks/gem_management.rb +1 -1
- data/lib/merb-core/tasks/merb.rb +3 -1
- data/lib/merb-core/tasks/merb_rake_helper.rb +1 -1
- data/lib/merb-core/test.rb +8 -8
- data/lib/merb-core/test/helpers.rb +1 -1
- data/lib/merb-core/test/helpers/cookie_jar.rb +16 -2
- data/lib/merb-core/test/helpers/mock_request_helper.rb +13 -13
- data/lib/merb-core/test/helpers/request_helper.rb +1 -1
- data/lib/merb-core/test/helpers/route_helper.rb +2 -2
- data/lib/merb-core/test/matchers.rb +3 -3
- data/lib/merb-core/test/matchers/request_matchers.rb +1 -1
- data/lib/merb-core/test/run_spec.rb +1 -1
- data/lib/merb-core/test/tasks/spectasks.rb +1 -1
- data/lib/merb-core/test/test_ext/hpricot.rb +1 -1
- data/lib/merb-core/test/test_ext/rspec.rb +2 -2
- data/lib/merb-core/test/test_ext/string.rb +1 -1
- data/lib/merb-core/version.rb +1 -1
- metadata +8 -22
- data/lib/merb-core/test/matchers/view_matchers.rb +0 -231
- data/lib/merb-core/test/webrat.rb +0 -37
- data/lib/merb-core/vendor/nokogiri/css.rb +0 -6
- data/lib/merb-core/vendor/nokogiri/css/generated_parser.rb +0 -653
- data/lib/merb-core/vendor/nokogiri/css/generated_tokenizer.rb +0 -159
- data/lib/merb-core/vendor/nokogiri/css/node.rb +0 -95
- data/lib/merb-core/vendor/nokogiri/css/parser.rb +0 -24
- data/lib/merb-core/vendor/nokogiri/css/parser.y +0 -198
- data/lib/merb-core/vendor/nokogiri/css/tokenizer.rb +0 -9
- data/lib/merb-core/vendor/nokogiri/css/tokenizer.rex +0 -63
- data/lib/merb-core/vendor/nokogiri/css/xpath_visitor.rb +0 -159
data/lib/merb-core/test.rb
CHANGED
@@ -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
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
388
|
+
# :api: plugin
|
389
389
|
# @deprecated
|
390
390
|
def check_request_for_route(request)
|
391
391
|
match = ::Merb::Router.match(request)
|
@@ -56,7 +56,7 @@ module Merb
|
|
56
56
|
#
|
57
57
|
# url(:articles, 2008, 10, "test_article")
|
58
58
|
#
|
59
|
-
#
|
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
|
13
|
-
|
11
|
+
include ::Webrat::Matchers
|
12
|
+
include ::Webrat::HaveTagMatcher
|
13
|
+
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"]
|
@@ -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
|
data/lib/merb-core/version.rb
CHANGED
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
|
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-
|
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:
|
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:
|
93
|
+
version: 0.9.7
|
94
94
|
version:
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
97
|
-
type: :
|
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.
|
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:
|
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
|