merb-core 0.9.4 → 0.9.5

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