merb-core 0.9.4 → 0.9.5

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 (52) hide show
  1. data/Rakefile +22 -13
  2. data/lib/merb-core/bootloader.rb +3 -2
  3. data/lib/merb-core/config.rb +1 -1
  4. data/lib/merb-core/constants.rb +3 -1
  5. data/lib/merb-core/controller/abstract_controller.rb +25 -39
  6. data/lib/merb-core/controller/exceptions.rb +14 -16
  7. data/lib/merb-core/controller/merb_controller.rb +2 -2
  8. data/lib/merb-core/controller/mime.rb +2 -1
  9. data/lib/merb-core/controller/mixins/render.rb +12 -0
  10. data/lib/merb-core/controller/mixins/responder.rb +31 -7
  11. data/lib/merb-core/core_ext/hash.rb +7 -0
  12. data/lib/merb-core/core_ext/kernel.rb +31 -34
  13. data/lib/merb-core/core_ext.rb +1 -0
  14. data/lib/merb-core/dispatch/default_exception/default_exception.rb +3 -3
  15. data/lib/merb-core/dispatch/dispatcher.rb +128 -135
  16. data/lib/merb-core/dispatch/request.rb +11 -11
  17. data/lib/merb-core/dispatch/router/behavior.rb +6 -6
  18. data/lib/merb-core/dispatch/router.rb +5 -5
  19. data/lib/merb-core/logger.rb +203 -202
  20. data/lib/merb-core/rack/application.rb +19 -5
  21. data/lib/merb-core/rack/middleware/conditional_get.rb +23 -0
  22. data/lib/merb-core/rack/middleware/content_length.rb +18 -0
  23. data/lib/merb-core/rack/middleware/tracer.rb +20 -0
  24. data/lib/merb-core/rack/middleware.rb +1 -7
  25. data/lib/merb-core/rack.rb +19 -16
  26. data/lib/merb-core/test/matchers/route_matchers.rb +1 -0
  27. data/lib/merb-core/test/matchers/view_matchers.rb +36 -0
  28. data/lib/merb-core/test/run_specs.rb +2 -1
  29. data/lib/merb-core/version.rb +1 -1
  30. data/lib/merb-core.rb +39 -33
  31. data/spec/private/config/merb_spec.rb +34 -0
  32. data/spec/private/dispatch/fixture/log/merb_test.log +372 -0
  33. data/spec/private/router/fixture/log/merb_test.log +42 -0
  34. data/spec/public/abstract_controller/controllers/filters.rb +50 -1
  35. data/spec/public/abstract_controller/filter_spec.rb +25 -0
  36. data/spec/public/controller/base_spec.rb +41 -1
  37. data/spec/public/controller/controllers/base.rb +16 -0
  38. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -1
  39. data/spec/public/controller/dispatcher_spec.rb +24 -25
  40. data/spec/public/controller/responder_spec.rb +6 -0
  41. data/spec/public/core_ext/kernel_spec.rb +79 -0
  42. data/spec/public/directory_structure/directory/log/merb_test.log +245 -0
  43. data/spec/public/rack/conditinal_get_middleware_spec.rb +139 -0
  44. data/spec/public/rack/rack_middleware_spec.rb +99 -0
  45. data/spec/public/rack/shared_example_groups.rb +35 -0
  46. data/spec/public/reloading/directory/log/merb_test.log +40 -0
  47. data/spec/public/request/request_spec.rb +0 -5
  48. data/spec/public/router/fixture/log/merb_test.log +348 -0
  49. data/spec/public/test/route_matchers_spec.rb +4 -0
  50. data/spec/spec_helper.rb +7 -1
  51. metadata +42 -5
  52. data/spec/private/plugins/plugin_spec.rb +0 -166
@@ -0,0 +1,139 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
2
+ require File.join(File.dirname(__FILE__), "shared_example_groups")
3
+
4
+ require "sha1"
5
+
6
+ NOW = Time.now
7
+
8
+ class EtagController < Merb::Controller
9
+ def non_matching_etag
10
+ response = "Ruby world needs a Paste port. Or... CherryPy?"
11
+ headers['ETag'] = Digest::SHA1.hexdigest(response)
12
+
13
+ response
14
+ end
15
+
16
+ def matching_etag
17
+ response = "Everybody loves Rack"
18
+ headers['ETag'] = Digest::SHA1.hexdigest(response)
19
+
20
+ response
21
+ end
22
+
23
+ def no_etag
24
+ # sanity check
25
+ headers.delete('ETag')
26
+
27
+ "Everyone loves Rack"
28
+ end
29
+ end
30
+
31
+ class LastModifiedController < Merb::Controller
32
+ def non_matching_last_modified
33
+ response = "Who cares about efficiency? Just throw more hardware at the problem."
34
+ headers[Merb::Const::LAST_MODIFIED] = :non_matching
35
+
36
+ response
37
+ end
38
+
39
+ def matching_last_modified
40
+ response = "Who cares about efficiency? Just throw more hardware at the problem."
41
+ headers[Merb::Const::LAST_MODIFIED] = :matching
42
+
43
+ response
44
+ end
45
+
46
+ def no_last_modified
47
+ # sanity check
48
+ headers.delete('Last-Modified')
49
+
50
+ "Everyone loves Rack"
51
+ end
52
+ end
53
+
54
+
55
+ Merb::Router.prepare do |r|
56
+ r.match("/etag/match").to(:controller => "etag_controller", :action => "matching_etag")
57
+ r.match("/etag/nomatch").to(:controller => "etag_controller", :action => "non_matching_etag")
58
+ r.match("/etag/stomach").to(:controller => "etag_controller", :action => "no_etag")
59
+
60
+ r.match("/last_modified/match").to(:controller => "last_modified_controller", :action => "matching_last_modified")
61
+ r.match("/last_modified/nomatch").to(:controller => "last_modified_controller", :action => "non_matching_last_modified")
62
+ r.match("/last_modified/stomach").to(:controller => "last_modified_controller", :action => "no_last_modified")
63
+ end
64
+
65
+
66
+
67
+ describe Merb::Rack::ConditionalGet do
68
+
69
+ before(:each) do
70
+ @app = Merb::Rack::Application.new
71
+ @middleware = Merb::Rack::ConditionalGet.new(@app)
72
+ end
73
+
74
+ describe "when response has no ETag header" do
75
+ it 'does not modify status' do
76
+ env = Rack::MockRequest.env_for('/etag/stomach')
77
+ status, headers, body = @middleware.call(env)
78
+
79
+ status.should == 200
80
+ end
81
+ end
82
+
83
+ describe "when response has ETag header" do
84
+ describe "and it == to HTTP_IF_NONE_MATCH of the request" do
85
+ it 'sets status to "304"' do
86
+ env = Rack::MockRequest.env_for('/etag/match')
87
+ env['HTTP_IF_NONE_MATCH'] =
88
+ Digest::SHA1.hexdigest("Everybody loves Rack")
89
+
90
+ status, headers, body = @middleware.call(env)
91
+ status.should == 304
92
+ end
93
+ end
94
+
95
+ describe "and it IS NOT == to HTTP_IF_NONE_MATCH of the request" do
96
+ it 'does not modify status' do
97
+ env = Rack::MockRequest.env_for('/etag/nomatch')
98
+ env['HTTP_IF_NONE_MATCH'] =
99
+ Digest::SHA1.hexdigest("Everybody loves Rack")
100
+
101
+ status, headers, body = @middleware.call(env)
102
+ status.should == 200
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "when response has no Last-Modified header" do
108
+ it 'does not modify status' do
109
+ env = Rack::MockRequest.env_for('/last_modified/stomach')
110
+ status, headers, body = @middleware.call(env)
111
+
112
+ status.should == 200
113
+ end
114
+ end
115
+
116
+ describe "when response has Last-Modified header" do
117
+ describe "when response has Last-Modified header" do
118
+ describe "and it == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
119
+ it 'sets status to "304"' do
120
+ env = Rack::MockRequest.env_for('/last_modified/match')
121
+ env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :matching
122
+
123
+ status, headers, body = @middleware.call(env)
124
+ status.should == 304
125
+ end
126
+ end
127
+
128
+ describe "and it IS NOT == to HTTP_IF_NOT_MODIFIED_SINCE of the request" do
129
+ it 'does not modify status' do
130
+ env = Rack::MockRequest.env_for('/last_modified/nomatch')
131
+ env[Merb::Const::HTTP_IF_MODIFIED_SINCE] = :matching
132
+
133
+ status, headers, body = @middleware.call(env)
134
+ status.should == 200
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,99 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
2
+ require File.join(File.dirname(__FILE__), "shared_example_groups")
3
+
4
+ class RackyController < Merb::Controller
5
+ def index
6
+ body = "Everyone loves Rack"
7
+ headers['Content-Length'] = body.size.to_s
8
+
9
+ body
10
+ end
11
+ end
12
+
13
+ Merb::Router.prepare do |r|
14
+ r.match("/heavy/lifting").to(:controller => "racky_controller")
15
+ end
16
+
17
+
18
+ describe Merb::Rack::Application do
19
+ before(:each) do
20
+ @app = Merb::Rack::Application.new
21
+ @env = Rack::MockRequest.env_for('/heavy/lifting')
22
+
23
+ @result = @app.call(@env)
24
+ @body = "Everyone loves Rack"
25
+ end
26
+
27
+ it_should_behave_like "rack application"
28
+
29
+ it 'sets Date header' do
30
+ status, headers, body = @app.call(@env)
31
+
32
+ headers.should include(Merb::Const::DATE)
33
+ end
34
+
35
+ describe "#deferred?" do
36
+ it "returns true when request path matches deferred actions regexp" do
37
+ Merb::Config[:deferred_actions] = ['/heavy/lifting']
38
+
39
+ @app.deferred?(@env).should be(true)
40
+ end
41
+
42
+ it "returns false when request path DOES NOT match deferred actions regexp" do
43
+ @app.deferred?(Rack::MockRequest.env_for('/not/deferred')).should be(false)
44
+ end
45
+ end
46
+ end
47
+
48
+
49
+ describe Merb::Rack::Middleware do
50
+ before(:each) do
51
+ @app = Merb::Rack::Application.new
52
+ @middleware = Merb::Rack::Middleware.new(@app)
53
+ @env = Rack::MockRequest.env_for('/heavy/lifting')
54
+
55
+ @result = @middleware.call(@env)
56
+ @body = "Everyone loves Rack"
57
+ end
58
+
59
+ it_should_behave_like "rack application"
60
+
61
+ it_should_behave_like "transparent middleware"
62
+ end
63
+
64
+
65
+
66
+ describe Merb::Rack::Tracer do
67
+ before(:each) do
68
+ @app = Merb::Rack::Application.new
69
+ @middleware = Merb::Rack::Tracer.new(@app)
70
+ @env = Rack::MockRequest.env_for('/heavy/lifting')
71
+
72
+ @result = @middleware.call(@env)
73
+ @body = "Everyone loves Rack"
74
+ end
75
+
76
+ it_should_behave_like "rack application"
77
+
78
+ it_should_behave_like "transparent middleware"
79
+ end
80
+
81
+
82
+ describe Merb::Rack::ContentLength do
83
+ before(:each) do
84
+ @app = Merb::Rack::Application.new
85
+ @middleware = Merb::Rack::ContentLength.new(@app)
86
+ @env = Rack::MockRequest.env_for('/heavy/lifting')
87
+
88
+ @result = @middleware.call(@env)
89
+ @body = "Everyone loves Rack"
90
+ end
91
+
92
+ it_should_behave_like "rack application"
93
+
94
+ it_should_behave_like "transparent middleware"
95
+
96
+ it 'sets Content-Length header to response body size' do
97
+ @result[1]['Content-Length'].should == @body.size.to_s
98
+ end
99
+ end
@@ -0,0 +1,35 @@
1
+ describe "rack application", :shared => true do
2
+ it 'is callable' do
3
+ @app.should respond_to(:call)
4
+ end
5
+
6
+ it 'returns a 3-tuple' do
7
+ @result.size.should == 3
8
+ end
9
+
10
+ it 'returns status as first tuple element' do
11
+ @result.first.should == 200
12
+ end
13
+
14
+ it 'returns hash of headers as the second tuple element' do
15
+ @result[1].should be_an_instance_of(Hash)
16
+ end
17
+
18
+ it 'returns response body as third tuple element' do
19
+ @result.last.should == @body
20
+ end
21
+ end
22
+
23
+ describe "transparent middleware", :shared => true do
24
+ it "delegates request handling to wrapped Rack application" do
25
+ @result.last.should == @body
26
+ end
27
+
28
+ describe "#deferred?" do
29
+ it "is delegated to wrapped Rack application" do
30
+ @middleware.deferred?(@env).should be(true)
31
+ @middleware.deferred?(Rack::MockRequest.env_for('/not-deferred/')).should be(false)
32
+ end
33
+ end
34
+ end
35
+
@@ -288121,3 +288121,43 @@ Restarting Worker Thread
288121
288121
  ~ Not Using Sessions
288122
288122
  ~ Not Using Sessions
288123
288123
  ~ Not Using Sessions
288124
+ ~ Not Using Sessions
288125
+ ~ Not Using Sessions
288126
+ ~ Not Using Sessions
288127
+ ~ Not Using Sessions
288128
+ ~ Not Using Sessions
288129
+ ~ Not Using Sessions
288130
+ ~ Not Using Sessions
288131
+ ~ Not Using Sessions
288132
+ ~ Not Using Sessions
288133
+ ~ Not Using Sessions
288134
+ ~ Not Using Sessions
288135
+ ~ Not Using Sessions
288136
+ ~ Not Using Sessions
288137
+ ~ Not Using Sessions
288138
+ ~ Not Using Sessions
288139
+ ~ Not Using Sessions
288140
+ ~ Not Using Sessions
288141
+ ~ Not Using Sessions
288142
+ ~ Not Using Sessions
288143
+ ~ Not Using Sessions
288144
+ ~ Not Using Sessions
288145
+ ~ Not Using Sessions
288146
+ ~ Not Using Sessions
288147
+ ~ Not Using Sessions
288148
+ ~ Not Using Sessions
288149
+ ~ Not Using Sessions
288150
+ ~ Not Using Sessions
288151
+ ~ Not Using Sessions
288152
+ ~ Not Using Sessions
288153
+ ~ Not Using Sessions
288154
+ ~ Not Using Sessions
288155
+ ~ Not Using Sessions
288156
+ ~ Not Using Sessions
288157
+ ~ Not Using Sessions
288158
+ ~ Not Using Sessions
288159
+ ~ Not Using Sessions
288160
+ ~ Not Using Sessions
288161
+ ~ Not Using Sessions
288162
+ ~ Not Using Sessions
288163
+ ~ Not Using Sessions
@@ -63,13 +63,11 @@ describe Merb::Request, " query and body params" do
63
63
 
64
64
  it "should convert #{query.inspect} to #{parse.inspect} in the query string" do
65
65
  request = fake_request({:query_string => query})
66
- request.stub!(:route_params).and_return({})
67
66
  request.params.should == parse
68
67
  end
69
68
 
70
69
  it "should convert #{query.inspect} to #{parse.inspect} in the post body" do
71
70
  request = fake_request({}, :post_body => query)
72
- request.stub!(:route_params).and_return({})
73
71
  request.params.should == parse
74
72
  end
75
73
 
@@ -77,20 +75,17 @@ describe Merb::Request, " query and body params" do
77
75
 
78
76
  it "should support JSON params" do
79
77
  request = fake_request({:content_type => "application/json"}, :req => %{{"foo": "bar"}})
80
- request.stub!(:route_params).and_return({})
81
78
  request.params.should == {"foo" => "bar"}
82
79
  end
83
80
 
84
81
  it "should populated the inflated_object parameter if JSON params do not inflate to a hash" do
85
82
  request = fake_request({:content_type => "application/json"}, :req => %{["foo", "bar"]})
86
- request.stub!(:route_params).and_return({})
87
83
  request.params.should have_key(:inflated_object)
88
84
  request.params[:inflated_object].should eql(["foo", "bar"])
89
85
  end
90
86
 
91
87
  it "should support XML params" do
92
88
  request = fake_request({:content_type => "application/xml"}, :req => %{<foo bar="baz"><baz/></foo>})
93
- request.stub!(:route_params).and_return({})
94
89
  request.params.should == {"foo" => {"baz" => nil, "bar" => "baz"}}
95
90
  end
96
91
 
@@ -30048,3 +30048,351 @@ Restarting Worker Thread
30048
30048
  ~ Not Using Sessions
30049
30049
  ~ Not Using Sessions
30050
30050
  ~ Not Using Sessions
30051
+ ~ Not Using Sessions
30052
+ ~ Not Using Sessions
30053
+ ~ Not Using Sessions
30054
+ ~ Not Using Sessions
30055
+ ~ Not Using Sessions
30056
+ ~ Not Using Sessions
30057
+ ~ Not Using Sessions
30058
+ ~ Not Using Sessions
30059
+ ~ Not Using Sessions
30060
+ ~ Not Using Sessions
30061
+ ~ Not Using Sessions
30062
+ ~ Not Using Sessions
30063
+ ~ Not Using Sessions
30064
+ ~ Not Using Sessions
30065
+ ~ Not Using Sessions
30066
+ ~ Not Using Sessions
30067
+ ~ Not Using Sessions
30068
+ ~ Not Using Sessions
30069
+ ~ Not Using Sessions
30070
+ ~ Not Using Sessions
30071
+ ~ Not Using Sessions
30072
+ ~ Not Using Sessions
30073
+ ~ Not Using Sessions
30074
+ ~ Not Using Sessions
30075
+ ~ Not Using Sessions
30076
+ ~ Not Using Sessions
30077
+ ~ Not Using Sessions
30078
+ ~ Not Using Sessions
30079
+ ~ Not Using Sessions
30080
+ ~ Not Using Sessions
30081
+ ~ Not Using Sessions
30082
+ ~ Not Using Sessions
30083
+ ~ Not Using Sessions
30084
+ ~ Not Using Sessions
30085
+ ~ Not Using Sessions
30086
+ ~ Not Using Sessions
30087
+ ~ Not Using Sessions
30088
+ ~ Not Using Sessions
30089
+ ~ Not Using Sessions
30090
+ ~ Not Using Sessions
30091
+ ~ Not Using Sessions
30092
+ ~ Not Using Sessions
30093
+ ~ Not Using Sessions
30094
+ ~ Not Using Sessions
30095
+ ~ Not Using Sessions
30096
+ ~ Not Using Sessions
30097
+ ~ Not Using Sessions
30098
+ ~ Not Using Sessions
30099
+ ~ Not Using Sessions
30100
+ ~ Not Using Sessions
30101
+ ~ Not Using Sessions
30102
+ ~ Not Using Sessions
30103
+ ~ Not Using Sessions
30104
+ ~ Not Using Sessions
30105
+ ~ Not Using Sessions
30106
+ ~ Not Using Sessions
30107
+ ~ Not Using Sessions
30108
+ ~ Not Using Sessions
30109
+ ~ Not Using Sessions
30110
+ ~ Not Using Sessions
30111
+ ~ Not Using Sessions
30112
+ ~ Not Using Sessions
30113
+ ~ Not Using Sessions
30114
+ ~ Not Using Sessions
30115
+ ~ Not Using Sessions
30116
+ ~ Not Using Sessions
30117
+ ~ Not Using Sessions
30118
+ ~ Not Using Sessions
30119
+ ~ Not Using Sessions
30120
+ ~ Not Using Sessions
30121
+ ~ Not Using Sessions
30122
+ ~ Not Using Sessions
30123
+ ~ Not Using Sessions
30124
+ ~ Not Using Sessions
30125
+ ~ Not Using Sessions
30126
+ ~ Not Using Sessions
30127
+ ~ Not Using Sessions
30128
+ ~ Not Using Sessions
30129
+ ~ Not Using Sessions
30130
+ ~ Not Using Sessions
30131
+ ~ Not Using Sessions
30132
+ ~ Not Using Sessions
30133
+ ~ Not Using Sessions
30134
+ ~ Not Using Sessions
30135
+ ~ Not Using Sessions
30136
+ ~ Not Using Sessions
30137
+ ~ Not Using Sessions
30138
+ ~ Not Using Sessions
30139
+ ~ Not Using Sessions
30140
+ ~ Not Using Sessions
30141
+ ~ Not Using Sessions
30142
+ ~ Not Using Sessions
30143
+ ~ Not Using Sessions
30144
+ ~ Not Using Sessions
30145
+ ~ Not Using Sessions
30146
+ ~ Not Using Sessions
30147
+ ~ Not Using Sessions
30148
+ ~ Not Using Sessions
30149
+ ~ Not Using Sessions
30150
+ ~ Not Using Sessions
30151
+ ~ Not Using Sessions
30152
+ ~ Not Using Sessions
30153
+ ~ Not Using Sessions
30154
+ ~ Not Using Sessions
30155
+ ~ Not Using Sessions
30156
+ ~ Not Using Sessions
30157
+ ~ Not Using Sessions
30158
+ ~ Not Using Sessions
30159
+ ~ Not Using Sessions
30160
+ ~ Not Using Sessions
30161
+ ~ Not Using Sessions
30162
+ ~ Not Using Sessions
30163
+ ~ Not Using Sessions
30164
+ ~ Not Using Sessions
30165
+ ~ Not Using Sessions
30166
+ ~ Not Using Sessions
30167
+ ~ Not Using Sessions
30168
+ ~ Not Using Sessions
30169
+ ~ Not Using Sessions
30170
+ ~ Not Using Sessions
30171
+ ~ Not Using Sessions
30172
+ ~ Not Using Sessions
30173
+ ~ Not Using Sessions
30174
+ ~ Not Using Sessions
30175
+ ~ Not Using Sessions
30176
+ ~ Not Using Sessions
30177
+ ~ Not Using Sessions
30178
+ ~ Not Using Sessions
30179
+ ~ Not Using Sessions
30180
+ ~ Not Using Sessions
30181
+ ~ Not Using Sessions
30182
+ ~ Not Using Sessions
30183
+ ~ Not Using Sessions
30184
+ ~ Not Using Sessions
30185
+ ~ Not Using Sessions
30186
+ ~ Not Using Sessions
30187
+ ~ Not Using Sessions
30188
+ ~ Not Using Sessions
30189
+ ~ Not Using Sessions
30190
+ ~ Not Using Sessions
30191
+ ~ Not Using Sessions
30192
+ ~ Not Using Sessions
30193
+ ~ Not Using Sessions
30194
+ ~ Not Using Sessions
30195
+ ~ Not Using Sessions
30196
+ ~ Not Using Sessions
30197
+ ~ Not Using Sessions
30198
+ ~ Not Using Sessions
30199
+ ~ Not Using Sessions
30200
+ ~ Not Using Sessions
30201
+ ~ Not Using Sessions
30202
+ ~ Not Using Sessions
30203
+ ~ Not Using Sessions
30204
+ ~ Not Using Sessions
30205
+ ~ Not Using Sessions
30206
+ ~ Not Using Sessions
30207
+ ~ Not Using Sessions
30208
+ ~ Not Using Sessions
30209
+ ~ Not Using Sessions
30210
+ ~ Not Using Sessions
30211
+ ~ Not Using Sessions
30212
+ ~ Not Using Sessions
30213
+ ~ Not Using Sessions
30214
+ ~ Not Using Sessions
30215
+ ~ Not Using Sessions
30216
+ ~ Not Using Sessions
30217
+ ~ Not Using Sessions
30218
+ ~ Not Using Sessions
30219
+ ~ Not Using Sessions
30220
+ ~ Not Using Sessions
30221
+ ~ Not Using Sessions
30222
+ ~ Not Using Sessions
30223
+ ~ Not Using Sessions
30224
+ ~ Not Using Sessions
30225
+ ~ Not Using Sessions
30226
+ ~ Not Using Sessions
30227
+ ~ Not Using Sessions
30228
+ ~ Not Using Sessions
30229
+ ~ Not Using Sessions
30230
+ ~ Not Using Sessions
30231
+ ~ Not Using Sessions
30232
+ ~ Not Using Sessions
30233
+ ~ Not Using Sessions
30234
+ ~ Not Using Sessions
30235
+ ~ Not Using Sessions
30236
+ ~ Not Using Sessions
30237
+ ~ Not Using Sessions
30238
+ ~ Not Using Sessions
30239
+ ~ Not Using Sessions
30240
+ ~ Not Using Sessions
30241
+ ~ Not Using Sessions
30242
+ ~ Not Using Sessions
30243
+ ~ Not Using Sessions
30244
+ ~ Not Using Sessions
30245
+ ~ Not Using Sessions
30246
+ ~ Not Using Sessions
30247
+ ~ Not Using Sessions
30248
+ ~ Not Using Sessions
30249
+ ~ Not Using Sessions
30250
+ ~ Not Using Sessions
30251
+ ~ Not Using Sessions
30252
+ ~ Not Using Sessions
30253
+ ~ Not Using Sessions
30254
+ ~ Not Using Sessions
30255
+ ~ Not Using Sessions
30256
+ ~ Not Using Sessions
30257
+ ~ Not Using Sessions
30258
+ ~ Not Using Sessions
30259
+ ~ Not Using Sessions
30260
+ ~ Not Using Sessions
30261
+ ~ Not Using Sessions
30262
+ ~ Not Using Sessions
30263
+ ~ Not Using Sessions
30264
+ ~ Not Using Sessions
30265
+ ~ Not Using Sessions
30266
+ ~ Not Using Sessions
30267
+ ~ Not Using Sessions
30268
+ ~ Not Using Sessions
30269
+ ~ Not Using Sessions
30270
+ ~ Not Using Sessions
30271
+ ~ Not Using Sessions
30272
+ ~ Not Using Sessions
30273
+ ~ Not Using Sessions
30274
+ ~ Not Using Sessions
30275
+ ~ Not Using Sessions
30276
+ ~ Not Using Sessions
30277
+ ~ Not Using Sessions
30278
+ ~ Not Using Sessions
30279
+ ~ Not Using Sessions
30280
+ ~ Not Using Sessions
30281
+ ~ Not Using Sessions
30282
+ ~ Not Using Sessions
30283
+ ~ Not Using Sessions
30284
+ ~ Not Using Sessions
30285
+ ~ Not Using Sessions
30286
+ ~ Not Using Sessions
30287
+ ~ Not Using Sessions
30288
+ ~ Not Using Sessions
30289
+ ~ Not Using Sessions
30290
+ ~ Not Using Sessions
30291
+ ~ Not Using Sessions
30292
+ ~ Not Using Sessions
30293
+ ~ Not Using Sessions
30294
+ ~ Not Using Sessions
30295
+ ~ Not Using Sessions
30296
+ ~ Not Using Sessions
30297
+ ~ Not Using Sessions
30298
+ ~ Not Using Sessions
30299
+ ~ Not Using Sessions
30300
+ ~ Not Using Sessions
30301
+ ~ Not Using Sessions
30302
+ ~ Not Using Sessions
30303
+ ~ Not Using Sessions
30304
+ ~ Not Using Sessions
30305
+ ~ Not Using Sessions
30306
+ ~ Not Using Sessions
30307
+ ~ Not Using Sessions
30308
+ ~ Not Using Sessions
30309
+ ~ Not Using Sessions
30310
+ ~ Not Using Sessions
30311
+ ~ Not Using Sessions
30312
+ ~ Not Using Sessions
30313
+ ~ Not Using Sessions
30314
+ ~ Not Using Sessions
30315
+ ~ Not Using Sessions
30316
+ ~ Not Using Sessions
30317
+ ~ Not Using Sessions
30318
+ ~ Not Using Sessions
30319
+ ~ Not Using Sessions
30320
+ ~ Not Using Sessions
30321
+ ~ Not Using Sessions
30322
+ ~ Not Using Sessions
30323
+ ~ Not Using Sessions
30324
+ ~ Not Using Sessions
30325
+ ~ Not Using Sessions
30326
+ ~ Not Using Sessions
30327
+ ~ Not Using Sessions
30328
+ ~ Not Using Sessions
30329
+ ~ Not Using Sessions
30330
+ ~ Not Using Sessions
30331
+ ~ Not Using Sessions
30332
+ ~ Not Using Sessions
30333
+ ~ Not Using Sessions
30334
+ ~ Not Using Sessions
30335
+ ~ Not Using Sessions
30336
+ ~ Not Using Sessions
30337
+ ~ Not Using Sessions
30338
+ ~ Not Using Sessions
30339
+ ~ Not Using Sessions
30340
+ ~ Not Using Sessions
30341
+ ~ Not Using Sessions
30342
+ ~ Not Using Sessions
30343
+ ~ Not Using Sessions
30344
+ ~ Not Using Sessions
30345
+ ~ Not Using Sessions
30346
+ ~ Not Using Sessions
30347
+ ~ Not Using Sessions
30348
+ ~ Not Using Sessions
30349
+ ~ Not Using Sessions
30350
+ ~ Not Using Sessions
30351
+ ~ Not Using Sessions
30352
+ ~ Not Using Sessions
30353
+ ~ Not Using Sessions
30354
+ ~ Not Using Sessions
30355
+ ~ Not Using Sessions
30356
+ ~ Not Using Sessions
30357
+ ~ Not Using Sessions
30358
+ ~ Not Using Sessions
30359
+ ~ Not Using Sessions
30360
+ ~ Not Using Sessions
30361
+ ~ Not Using Sessions
30362
+ ~ Not Using Sessions
30363
+ ~ Not Using Sessions
30364
+ ~ Not Using Sessions
30365
+ ~ Not Using Sessions
30366
+ ~ Not Using Sessions
30367
+ ~ Not Using Sessions
30368
+ ~ Not Using Sessions
30369
+ ~ Not Using Sessions
30370
+ ~ Not Using Sessions
30371
+ ~ Not Using Sessions
30372
+ ~ Not Using Sessions
30373
+ ~ Not Using Sessions
30374
+ ~ Not Using Sessions
30375
+ ~ Not Using Sessions
30376
+ ~ Not Using Sessions
30377
+ ~ Not Using Sessions
30378
+ ~ Not Using Sessions
30379
+ ~ Not Using Sessions
30380
+ ~ Not Using Sessions
30381
+ ~ Not Using Sessions
30382
+ ~ Not Using Sessions
30383
+ ~ Not Using Sessions
30384
+ ~ Not Using Sessions
30385
+ ~ Not Using Sessions
30386
+ ~ Not Using Sessions
30387
+ ~ Not Using Sessions
30388
+ ~ Not Using Sessions
30389
+ ~ Not Using Sessions
30390
+ ~ Not Using Sessions
30391
+ ~ Not Using Sessions
30392
+ ~ Not Using Sessions
30393
+ ~ Not Using Sessions
30394
+ ~ Not Using Sessions
30395
+ ~ Not Using Sessions
30396
+ ~ Not Using Sessions
30397
+ ~ Not Using Sessions
30398
+ ~ Not Using Sessions
@@ -89,6 +89,10 @@ describe Merb::Test::Rspec::RouteMatchers do
89
89
  route_matcher = RouteToMatcher.new(TestController, :get)
90
90
  route_matcher.with(:id => "123")
91
91
  end
92
+
93
+ it "should work with an empty expectation" do
94
+ ParameterMatcher.new({}).matches?(:param => "abc").should be_false
95
+ end
92
96
  end
93
97
 
94
98
  describe "#failure_message" do