roda 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +34 -0
  3. data/Rakefile +22 -46
  4. data/doc/release_notes/2.3.0.txt +109 -0
  5. data/lib/roda/plugins/assets.rb +2 -1
  6. data/lib/roda/plugins/caching.rb +1 -1
  7. data/lib/roda/plugins/chunked.rb +1 -1
  8. data/lib/roda/plugins/error_email.rb +1 -1
  9. data/lib/roda/plugins/head.rb +6 -0
  10. data/lib/roda/plugins/heartbeat.rb +40 -0
  11. data/lib/roda/plugins/json.rb +23 -3
  12. data/lib/roda/plugins/json_parser.rb +72 -0
  13. data/lib/roda/plugins/mailer.rb +22 -5
  14. data/lib/roda/plugins/named_templates.rb +2 -2
  15. data/lib/roda/plugins/path_rewriter.rb +82 -0
  16. data/lib/roda/plugins/precompile_templates.rb +87 -0
  17. data/lib/roda/plugins/render.rb +111 -43
  18. data/lib/roda/plugins/render_each.rb +1 -1
  19. data/lib/roda/plugins/shared_vars.rb +1 -1
  20. data/lib/roda/plugins/view_options.rb +28 -3
  21. data/lib/roda/version.rb +1 -1
  22. data/spec/composition_spec.rb +3 -3
  23. data/spec/env_spec.rb +1 -1
  24. data/spec/freeze_spec.rb +6 -6
  25. data/spec/integration_spec.rb +16 -15
  26. data/spec/matchers_spec.rb +110 -110
  27. data/spec/opts_spec.rb +8 -8
  28. data/spec/plugin/_erubis_escaping_spec.rb +34 -3
  29. data/spec/plugin/all_verbs_spec.rb +8 -8
  30. data/spec/plugin/assets_spec.rb +164 -150
  31. data/spec/plugin/backtracking_array_spec.rb +18 -18
  32. data/spec/plugin/caching_spec.rb +70 -70
  33. data/spec/plugin/chunked_spec.rb +38 -38
  34. data/spec/plugin/class_level_routing_spec.rb +78 -78
  35. data/spec/plugin/content_for_spec.rb +2 -2
  36. data/spec/plugin/cookies_spec.rb +4 -4
  37. data/spec/plugin/csrf_spec.rb +8 -8
  38. data/spec/plugin/default_headers_spec.rb +6 -6
  39. data/spec/plugin/delay_build_spec.rb +7 -6
  40. data/spec/plugin/delegate_spec.rb +2 -2
  41. data/spec/plugin/delete_empty_headers_spec.rb +2 -2
  42. data/spec/plugin/drop_body_spec.rb +6 -6
  43. data/spec/plugin/empty_root_spec.rb +3 -3
  44. data/spec/plugin/environments_spec.rb +7 -7
  45. data/spec/plugin/error_email_spec.rb +23 -23
  46. data/spec/plugin/error_handler_spec.rb +14 -14
  47. data/spec/plugin/flash_spec.rb +30 -29
  48. data/spec/plugin/h_spec.rb +1 -1
  49. data/spec/plugin/halt_spec.rb +16 -16
  50. data/spec/plugin/hash_matcher_spec.rb +5 -5
  51. data/spec/plugin/head_spec.rb +10 -10
  52. data/spec/plugin/header_matchers_spec.rb +13 -13
  53. data/spec/plugin/heartbeat_spec.rb +74 -0
  54. data/spec/plugin/hooks_spec.rb +20 -20
  55. data/spec/plugin/indifferent_params_spec.rb +1 -1
  56. data/spec/plugin/json_parser_spec.rb +72 -0
  57. data/spec/plugin/json_spec.rb +22 -9
  58. data/spec/plugin/mailer_spec.rb +72 -58
  59. data/spec/plugin/match_affix_spec.rb +2 -2
  60. data/spec/plugin/middleware_spec.rb +7 -7
  61. data/spec/plugin/module_include_spec.rb +4 -4
  62. data/spec/plugin/multi_route_spec.rb +66 -66
  63. data/spec/plugin/multi_run_spec.rb +21 -21
  64. data/spec/plugin/named_templates_spec.rb +6 -6
  65. data/spec/plugin/not_allowed_spec.rb +17 -17
  66. data/spec/plugin/not_found_spec.rb +14 -14
  67. data/spec/plugin/padrino_render_spec.rb +2 -2
  68. data/spec/plugin/param_matchers_spec.rb +6 -6
  69. data/spec/plugin/partials_spec.rb +3 -3
  70. data/spec/plugin/pass_spec.rb +7 -7
  71. data/spec/plugin/path_matchers_spec.rb +6 -6
  72. data/spec/plugin/path_rewriter_spec.rb +37 -0
  73. data/spec/plugin/path_spec.rb +41 -40
  74. data/spec/plugin/per_thread_caching_spec.rb +6 -6
  75. data/spec/plugin/precompile_templates_spec.rb +74 -0
  76. data/spec/plugin/render_each_spec.rb +4 -4
  77. data/spec/plugin/render_spec.rb +179 -76
  78. data/spec/plugin/shared_vars_spec.rb +4 -4
  79. data/spec/plugin/sinatra_helpers_spec.rb +121 -121
  80. data/spec/plugin/slash_path_empty_spec.rb +10 -10
  81. data/spec/plugin/static_spec.rb +4 -4
  82. data/spec/plugin/streaming_spec.rb +11 -11
  83. data/spec/plugin/symbol_matchers_spec.rb +24 -24
  84. data/spec/plugin/symbol_views_spec.rb +3 -3
  85. data/spec/plugin/view_options_spec.rb +10 -10
  86. data/spec/plugin_spec.rb +2 -2
  87. data/spec/redirect_spec.rb +10 -10
  88. data/spec/request_spec.rb +8 -8
  89. data/spec/response_spec.rb +23 -23
  90. data/spec/session_spec.rb +4 -4
  91. data/spec/spec_helper.rb +5 -19
  92. data/spec/version_spec.rb +4 -4
  93. data/spec/views/iv.erb +1 -0
  94. metadata +16 -5
@@ -29,19 +29,19 @@ describe "hooks plugin" do
29
29
 
30
30
  it "adds before and after hooks for running code before and after requests" do
31
31
  s, h, b = req
32
- s.should == 201
33
- h['foo'].should == 'baz'
34
- b.join.should == 'bar'
35
- @a.should == [[200, 'baz', ['bar']]]
32
+ s.must_equal 201
33
+ h['foo'].must_equal 'baz'
34
+ b.join.must_equal 'bar'
35
+ @a.must_equal [[200, 'baz', ['bar']]]
36
36
  end
37
37
 
38
38
  it "multiple plugin calls do not override existing hooks" do
39
39
  app.plugin :hooks
40
40
  s, h, b = req
41
- s.should == 201
42
- h['foo'].should == 'baz'
43
- b.join.should == 'bar'
44
- @a.should == [[200, 'baz', ['bar']]]
41
+ s.must_equal 201
42
+ h['foo'].must_equal 'baz'
43
+ b.join.must_equal 'bar'
44
+ @a.must_equal [[200, 'baz', ['bar']]]
45
45
  end
46
46
 
47
47
  it "after hooks are still called if an exception is raised" do
@@ -55,9 +55,9 @@ describe "hooks plugin" do
55
55
  a << $!
56
56
  end
57
57
 
58
- proc{req}.should raise_error(Roda::RodaError)
59
- a.pop.should be_a_kind_of(Roda::RodaError)
60
- a.pop.should == nil
58
+ proc{req}.must_raise(Roda::RodaError)
59
+ a.pop.must_be_kind_of(Roda::RodaError)
60
+ a.pop.must_equal nil
61
61
  end
62
62
 
63
63
  it "handles multiple before and after blocks correctly" do
@@ -72,11 +72,11 @@ describe "hooks plugin" do
72
72
  end
73
73
 
74
74
  s, h, b = req
75
- s.should == 402
76
- h['foo'].should == 'baz'
77
- h['bar'].should == 'foo'
78
- b.join.should == 'bar'
79
- a.should == [[200, 'baz', ['bar']], 'foo']
75
+ s.must_equal 402
76
+ h['foo'].must_equal 'baz'
77
+ h['bar'].must_equal 'foo'
78
+ b.join.must_equal 'bar'
79
+ a.must_equal [[200, 'baz', ['bar']], 'foo']
80
80
  end
81
81
 
82
82
  it "copies before and after blocks when subclassing" do
@@ -87,9 +87,9 @@ describe "hooks plugin" do
87
87
  end
88
88
  end
89
89
  s, h, b = req
90
- s.should == 201
91
- h['foo'].should == 'bar'
92
- b.join.should == 'foo'
93
- @a.should == [[200, 'bar', ['foo']]]
90
+ s.must_equal 201
91
+ h['foo'].must_equal 'bar'
92
+ b.join.must_equal 'foo'
93
+ @a.must_equal [[200, 'bar', ['foo']]]
94
94
  end
95
95
  end
@@ -8,6 +8,6 @@ describe "indifferent_params plugin" do
8
8
  end
9
9
  end
10
10
 
11
- body('QUERY_STRING'=>'a=2&b[][c]=3', 'rack.input'=>StringIO.new).should == '2/3'
11
+ body('QUERY_STRING'=>'a=2&b[][c]=3', 'rack.input'=>StringIO.new).must_equal '2/3'
12
12
  end
13
13
  end
@@ -0,0 +1,72 @@
1
+ require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
2
+
3
+ describe "json_parser plugin" do
4
+ before do
5
+ app(:json_parser) do |r|
6
+ r.params['a']['b'].to_s
7
+ end
8
+ end
9
+
10
+ it "parses incoming json if content type specifies json" do
11
+ body('rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
12
+ end
13
+
14
+ it "doesn't affect parsing of non-json content type" do
15
+ body('rack.input'=>StringIO.new('a[b]=1'), 'REQUEST_METHOD'=>'POST').must_equal '1'
16
+ end
17
+
18
+ it "returns 400 for invalid json" do
19
+ req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [400, {}, []]
20
+ end
21
+ end
22
+
23
+ describe "json_parser plugin" do
24
+ it "handles empty request bodies" do
25
+ app(:json_parser) do |r|
26
+ r.params.length.to_s
27
+ end
28
+ body('rack.input'=>StringIO.new(''), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '0'
29
+ end
30
+
31
+ it "supports :error_handler option" do
32
+ app(:bare) do
33
+ plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
34
+ route do |r|
35
+ r.params['a']['b'].to_s
36
+ end
37
+ end
38
+ req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [401, {}, ['bad']]
39
+ end
40
+
41
+ it "works with bare POST" do
42
+ app(:bare) do
43
+ plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
44
+ route do |r|
45
+ (r.POST['a']['b'] + r.POST['a']['c']).to_s
46
+ end
47
+ end
48
+ body('rack.input'=>StringIO.new('{"a":{"b":1,"c":2}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '3'
49
+ end
50
+
51
+ it "supports :parser option" do
52
+ app(:bare) do
53
+ plugin(:json_parser, :parser=>method(:eval))
54
+ route do |r|
55
+ r.params['a']['b'].to_s
56
+ end
57
+ end
58
+ body('rack.input'=>StringIO.new("{'a'=>{'b'=>1}}"), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
59
+ end
60
+
61
+ it "supports :include_request option" do
62
+ app(:bare) do
63
+ plugin(:json_parser,
64
+ :include_request => true,
65
+ :parser => lambda{|s,r| {'a'=>s, 'b'=>r.path_info}})
66
+ route do |r|
67
+ "#{r.params['a']}:#{r.params['b']}"
68
+ end
69
+ end
70
+ body('rack.input'=>StringIO.new('{}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '{}:/'
71
+ end
72
+ end
@@ -28,22 +28,35 @@ describe "json plugin" do
28
28
  end
29
29
 
30
30
  it "should use a json content type for a json response" do
31
- header('Content-Type', "/array").should == 'application/json'
32
- header('Content-Type', "/hash").should == 'application/json'
33
- header('Content-Type', "/c").should == 'application/json'
34
- header('Content-Type').should == 'text/html'
31
+ header('Content-Type', "/array").must_equal 'application/json'
32
+ header('Content-Type', "/hash").must_equal 'application/json'
33
+ header('Content-Type', "/c").must_equal 'application/json'
34
+ header('Content-Type').must_equal 'text/html'
35
35
  end
36
36
 
37
37
  it "should convert objects to json" do
38
- body('/array').gsub(/\s/, '').should == '[1,2,3]'
39
- body('/hash').gsub(/\s/, '').should == '{"a":"b"}'
40
- body('/c').should == '[1]'
41
- body.should == ''
38
+ body('/array').gsub(/\s/, '').must_equal '[1,2,3]'
39
+ body('/hash').gsub(/\s/, '').must_equal '{"a":"b"}'
40
+ body('/c').must_equal '[1]'
41
+ body.must_equal ''
42
42
  end
43
43
 
44
44
  it "should work when subclassing" do
45
45
  @app = Class.new(app)
46
46
  app.route{[1]}
47
- body.should == '[1]'
47
+ body.must_equal '[1]'
48
+ end
49
+
50
+ it "should accept custom serializers" do
51
+ app.plugin :json, :serializer => proc{|o| o.inspect}
52
+ body("/hash").must_equal '{"a"=>"b"}'
53
+ end
54
+
55
+ it "should give serializer the request if :include_request is set" do
56
+ app.plugin :json,
57
+ :include_request => true,
58
+ :serializer => lambda{|o,r| "#{o['a']}:#{r.path_info}"}
59
+
60
+ body("/hash").must_equal 'b:/hash'
48
61
  end
49
62
  end
@@ -36,28 +36,28 @@ describe "mailer plugin" do
36
36
  end
37
37
 
38
38
  m = app.mail('/foo')
39
- deliveries.should == []
40
- m.from.should == ['f@example.com']
41
- m.to.should == ['t@example.com']
42
- m.cc.should == ['c@example.com']
43
- m.bcc.should == ['b@example.com']
44
- m.subject.should == 's'
45
- m.body.should == 'b'
46
- m.header['X-Foo'].to_s.should == 'Bar'
39
+ deliveries.must_equal []
40
+ m.from.must_equal ['f@example.com']
41
+ m.to.must_equal ['t@example.com']
42
+ m.cc.must_equal ['c@example.com']
43
+ m.bcc.must_equal ['b@example.com']
44
+ m.subject.must_equal 's'
45
+ m.body.must_be :==, 'b'
46
+ m.header['X-Foo'].to_s.must_equal 'Bar'
47
47
 
48
48
  m.deliver!
49
- deliveries.should == [m]
49
+ deliveries.must_equal [m]
50
50
 
51
51
  deliveries.clear
52
52
  m = app.sendmail('/foo')
53
- deliveries.should == [m]
54
- m.from.should == ['f@example.com']
55
- m.to.should == ['t@example.com']
56
- m.cc.should == ['c@example.com']
57
- m.bcc.should == ['b@example.com']
58
- m.subject.should == 's'
59
- m.body.should == 'b'
60
- m.header['X-Foo'].to_s.should == 'Bar'
53
+ deliveries.must_equal [m]
54
+ m.from.must_equal ['f@example.com']
55
+ m.to.must_equal ['t@example.com']
56
+ m.cc.must_equal ['c@example.com']
57
+ m.bcc.must_equal ['b@example.com']
58
+ m.subject.must_equal 's'
59
+ m.body.must_be :==, 'b'
60
+ m.header['X-Foo'].to_s.must_equal 'Bar'
61
61
  end
62
62
 
63
63
  it "supports arguments to mail/sendmail methods, yielding them to the route blocks" do
@@ -71,8 +71,22 @@ describe "mailer plugin" do
71
71
  end
72
72
  end
73
73
 
74
- app.mail('/foo', 1, 2).body.should == 'foo[1, 2]'
75
- app.sendmail('/bar', 1, 2).body.should == '["bar", 1, 2]'
74
+ app.mail('/foo', 1, 2).body.must_be :==, 'foo[1, 2]'
75
+ app.sendmail('/bar', 1, 2).body.must_be :==, '["bar", 1, 2]'
76
+ end
77
+
78
+ it "supports no_mail! method for skipping mailing" do
79
+ app(:mailer) do |r|
80
+ instance_exec(&setup_email)
81
+ r.mail "foo" do |*args|
82
+ no_mail!
83
+ raise
84
+ end
85
+ end
86
+
87
+ app.mail('/foo', 1, 2).must_equal nil
88
+ app.sendmail('/foo', 1, 2).must_equal nil
89
+ deliveries.must_equal []
76
90
  end
77
91
 
78
92
  it "supports attachments" do
@@ -84,11 +98,11 @@ describe "mailer plugin" do
84
98
  end
85
99
 
86
100
  m = app.mail('foo')
87
- m.attachments.length.should == 1
88
- m.attachments.first.content_type.should =~ /mailer_spec\.rb/
89
- m.content_type.should =~ /\Amultipart\/mixed/
90
- m.parts.length.should == 1
91
- m.parts.first.body.should == File.read(__FILE__)
101
+ m.attachments.length.must_equal 1
102
+ m.attachments.first.content_type.must_match(/mailer_spec\.rb/)
103
+ m.content_type.must_match(/\Amultipart\/mixed/)
104
+ m.parts.length.must_equal 1
105
+ m.parts.first.body.must_be :==, File.read(__FILE__)
92
106
  end
93
107
 
94
108
  it "supports attachments with blocks" do
@@ -102,11 +116,11 @@ describe "mailer plugin" do
102
116
  end
103
117
 
104
118
  m = app.mail('foo')
105
- m.attachments.length.should == 1
106
- m.attachments.first.content_type.should == 'text/foo'
107
- m.content_type.should =~ /\Amultipart\/mixed/
108
- m.parts.length.should == 1
109
- m.parts.first.body.should == File.read(__FILE__)
119
+ m.attachments.length.must_equal 1
120
+ m.attachments.first.content_type.must_equal 'text/foo'
121
+ m.content_type.must_match(/\Amultipart\/mixed/)
122
+ m.parts.length.must_equal 1
123
+ m.parts.first.body.must_be :==, File.read(__FILE__)
110
124
  end
111
125
 
112
126
  it "supports plain-text attachments with an email body" do
@@ -119,14 +133,14 @@ describe "mailer plugin" do
119
133
  end
120
134
 
121
135
  m = app.mail('foo')
122
- m.parts.length.should == 2
123
- m.parts.first.content_type.should =~ /text\/plain/
124
- m.parts.first.body.should == 'c'
125
- m.parts.last.content_type.should =~ /text\/plain/
126
- m.parts.last.body.should == 'b'
127
- m.attachments.length.should == 1
128
- m.attachments.first.content_type.should =~ /a\.txt/
129
- m.content_type.should =~ /\Amultipart\/mixed/
136
+ m.parts.length.must_equal 2
137
+ m.parts.first.content_type.must_match(/text\/plain/)
138
+ m.parts.first.body.must_be :==, 'c'
139
+ m.parts.last.content_type.must_match(/text\/plain/)
140
+ m.parts.last.body.must_be :==, 'b'
141
+ m.attachments.length.must_equal 1
142
+ m.attachments.first.content_type.must_match(/a\.txt/)
143
+ m.content_type.must_match(/\Amultipart\/mixed/)
130
144
  end
131
145
 
132
146
  it "supports regular web requests in same application" do
@@ -140,8 +154,8 @@ describe "mailer plugin" do
140
154
  end
141
155
  end
142
156
 
143
- body("/foo/baz", 'rack.input'=>StringIO.new).should == 'foobaz'
144
- app.mail('/bar').body.should == 'b'
157
+ body("/foo/baz", 'rack.input'=>StringIO.new).must_equal 'foobaz'
158
+ app.mail('/bar').body.must_be :==, 'b'
145
159
  end
146
160
 
147
161
  it "supports multipart email using text_part/html_pat" do
@@ -154,9 +168,9 @@ describe "mailer plugin" do
154
168
  end
155
169
 
156
170
  m = app.mail('/foo')
157
- m.text_part.body.should == 't'
158
- m.html_part.body.should == 'h'
159
- m.content_type.should =~ /\Amultipart\/alternative/
171
+ m.text_part.body.must_be :==, 't'
172
+ m.html_part.body.must_be :==, 'h'
173
+ m.content_type.must_match(/\Amultipart\/alternative/)
160
174
  end
161
175
 
162
176
  it "supports setting arbitrary email headers for multipart emails" do
@@ -169,21 +183,21 @@ describe "mailer plugin" do
169
183
  end
170
184
 
171
185
  m = app.mail('/foo')
172
- m.text_part.body.should == 't'
173
- m.text_part.header['X-Text'].to_s.should == 'T'
174
- m.html_part.body.should == 'h'
175
- m.html_part.header['X-HTML'].to_s.should == 'H'
176
- m.content_type.should =~ /\Amultipart\/alternative/
186
+ m.text_part.body.must_be :==, 't'
187
+ m.text_part.header['X-Text'].to_s.must_equal 'T'
188
+ m.html_part.body.must_be :==, 'h'
189
+ m.html_part.header['X-HTML'].to_s.must_equal 'H'
190
+ m.content_type.must_match(/\Amultipart\/alternative/)
177
191
  end
178
192
 
179
193
  it "raises error if mail object is not returned" do
180
194
  app(:mailer){}
181
- proc{app.mail('/')}.should raise_error(Roda::RodaPlugins::Mailer::Error)
195
+ proc{app.mail('/')}.must_raise(Roda::RodaPlugins::Mailer::Error)
182
196
  end
183
197
 
184
198
  it "does not raise an error when using an explicitly empty body" do
185
199
  app(:mailer){""}
186
- proc{app.mail('/')}.should_not raise_error
200
+ app.mail('/')
187
201
  end
188
202
 
189
203
  it "supports setting the default content-type for emails when loading the plugin" do
@@ -191,7 +205,7 @@ describe "mailer plugin" do
191
205
  plugin :mailer, :content_type=>'text/html'
192
206
  route{""}
193
207
  end
194
- app.mail('/').content_type.should =~ /\Atext\/html/
208
+ app.mail('/').content_type.must_match(/\Atext\/html/)
195
209
  end
196
210
 
197
211
  it "supports loading the plugin multiple times" do
@@ -200,7 +214,7 @@ describe "mailer plugin" do
200
214
  plugin :mailer
201
215
  route{""}
202
216
  end
203
- app.mail('/').content_type.should =~ /\Atext\/html/
217
+ app.mail('/').content_type.must_match(/\Atext\/html/)
204
218
  end
205
219
 
206
220
  it "supports manually overridding the default content-type for emails" do
@@ -211,7 +225,7 @@ describe "mailer plugin" do
211
225
  ""
212
226
  end
213
227
  end
214
- app.mail('/').content_type.should =~ /\Atext\/foo/
228
+ app.mail('/').content_type.must_match(/\Atext\/foo/)
215
229
  end
216
230
 
217
231
  it "supports setting the default content type when attachments are used" do
@@ -223,12 +237,12 @@ describe "mailer plugin" do
223
237
  end
224
238
  end
225
239
  m = app.mail('/')
226
- m.content_type.should =~ /\Amultipart\/mixed/
227
- m.parts.length.should == 2
228
- m.parts.first.content_type.should =~ /\Atext\/html/
229
- m.parts.first.body.should == "a"
230
- m.parts.last.content_type.should =~ /\Atext\/css/
231
- m.parts.last.body.should == File.read('spec/assets/css/raw.css')
240
+ m.content_type.must_match(/\Amultipart\/mixed/)
241
+ m.parts.length.must_equal 2
242
+ m.parts.first.content_type.must_match(/\Atext\/html/)
243
+ m.parts.first.body.must_be :==, "a"
244
+ m.parts.last.content_type.must_match(/\Atext\/css/)
245
+ m.parts.last.body.must_be :==, File.read('spec/assets/css/raw.css')
232
246
  end
233
247
  end
234
248
  end
@@ -16,7 +16,7 @@ describe "match_affix plugin" do
16
16
  end
17
17
  end
18
18
 
19
- body("/albums/a/1").should == 'albums-/'
20
- body("/albums/b/1").should == 'b-/-1-""'
19
+ body("/albums/a/1").must_equal 'albums-/'
20
+ body("/albums/b/1").must_equal 'b-/-1-""'
21
21
  end
22
22
  end
@@ -42,18 +42,18 @@ describe "middleware plugin" do
42
42
  end
43
43
  end
44
44
 
45
- body('/a').should == 'a3'
46
- body('/b').should == 'b3'
47
- body('/a', 'REQUEST_METHOD'=>'POST').should == 'a2'
48
- body('/b', 'REQUEST_METHOD'=>'POST').should == 'b2'
49
- body('/a', 'REQUEST_METHOD'=>'PATCH').should == 'a2'
50
- body('/b', 'REQUEST_METHOD'=>'PATCH').should == 'b1'
45
+ body('/a').must_equal 'a3'
46
+ body('/b').must_equal 'b3'
47
+ body('/a', 'REQUEST_METHOD'=>'POST').must_equal 'a2'
48
+ body('/b', 'REQUEST_METHOD'=>'POST').must_equal 'b2'
49
+ body('/a', 'REQUEST_METHOD'=>'PATCH').must_equal 'a2'
50
+ body('/b', 'REQUEST_METHOD'=>'PATCH').must_equal 'b1'
51
51
  end
52
52
 
53
53
  it "makes it still possible to use the Roda app normally" do
54
54
  app(:middleware) do
55
55
  "a"
56
56
  end
57
- body.should == 'a'
57
+ body.must_equal 'a'
58
58
  end
59
59
  end