roda 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +34 -0
- data/Rakefile +22 -46
- data/doc/release_notes/2.3.0.txt +109 -0
- data/lib/roda/plugins/assets.rb +2 -1
- data/lib/roda/plugins/caching.rb +1 -1
- data/lib/roda/plugins/chunked.rb +1 -1
- data/lib/roda/plugins/error_email.rb +1 -1
- data/lib/roda/plugins/head.rb +6 -0
- data/lib/roda/plugins/heartbeat.rb +40 -0
- data/lib/roda/plugins/json.rb +23 -3
- data/lib/roda/plugins/json_parser.rb +72 -0
- data/lib/roda/plugins/mailer.rb +22 -5
- data/lib/roda/plugins/named_templates.rb +2 -2
- data/lib/roda/plugins/path_rewriter.rb +82 -0
- data/lib/roda/plugins/precompile_templates.rb +87 -0
- data/lib/roda/plugins/render.rb +111 -43
- data/lib/roda/plugins/render_each.rb +1 -1
- data/lib/roda/plugins/shared_vars.rb +1 -1
- data/lib/roda/plugins/view_options.rb +28 -3
- data/lib/roda/version.rb +1 -1
- data/spec/composition_spec.rb +3 -3
- data/spec/env_spec.rb +1 -1
- data/spec/freeze_spec.rb +6 -6
- data/spec/integration_spec.rb +16 -15
- data/spec/matchers_spec.rb +110 -110
- data/spec/opts_spec.rb +8 -8
- data/spec/plugin/_erubis_escaping_spec.rb +34 -3
- data/spec/plugin/all_verbs_spec.rb +8 -8
- data/spec/plugin/assets_spec.rb +164 -150
- data/spec/plugin/backtracking_array_spec.rb +18 -18
- data/spec/plugin/caching_spec.rb +70 -70
- data/spec/plugin/chunked_spec.rb +38 -38
- data/spec/plugin/class_level_routing_spec.rb +78 -78
- data/spec/plugin/content_for_spec.rb +2 -2
- data/spec/plugin/cookies_spec.rb +4 -4
- data/spec/plugin/csrf_spec.rb +8 -8
- data/spec/plugin/default_headers_spec.rb +6 -6
- data/spec/plugin/delay_build_spec.rb +7 -6
- data/spec/plugin/delegate_spec.rb +2 -2
- data/spec/plugin/delete_empty_headers_spec.rb +2 -2
- data/spec/plugin/drop_body_spec.rb +6 -6
- data/spec/plugin/empty_root_spec.rb +3 -3
- data/spec/plugin/environments_spec.rb +7 -7
- data/spec/plugin/error_email_spec.rb +23 -23
- data/spec/plugin/error_handler_spec.rb +14 -14
- data/spec/plugin/flash_spec.rb +30 -29
- data/spec/plugin/h_spec.rb +1 -1
- data/spec/plugin/halt_spec.rb +16 -16
- data/spec/plugin/hash_matcher_spec.rb +5 -5
- data/spec/plugin/head_spec.rb +10 -10
- data/spec/plugin/header_matchers_spec.rb +13 -13
- data/spec/plugin/heartbeat_spec.rb +74 -0
- data/spec/plugin/hooks_spec.rb +20 -20
- data/spec/plugin/indifferent_params_spec.rb +1 -1
- data/spec/plugin/json_parser_spec.rb +72 -0
- data/spec/plugin/json_spec.rb +22 -9
- data/spec/plugin/mailer_spec.rb +72 -58
- data/spec/plugin/match_affix_spec.rb +2 -2
- data/spec/plugin/middleware_spec.rb +7 -7
- data/spec/plugin/module_include_spec.rb +4 -4
- data/spec/plugin/multi_route_spec.rb +66 -66
- data/spec/plugin/multi_run_spec.rb +21 -21
- data/spec/plugin/named_templates_spec.rb +6 -6
- data/spec/plugin/not_allowed_spec.rb +17 -17
- data/spec/plugin/not_found_spec.rb +14 -14
- data/spec/plugin/padrino_render_spec.rb +2 -2
- data/spec/plugin/param_matchers_spec.rb +6 -6
- data/spec/plugin/partials_spec.rb +3 -3
- data/spec/plugin/pass_spec.rb +7 -7
- data/spec/plugin/path_matchers_spec.rb +6 -6
- data/spec/plugin/path_rewriter_spec.rb +37 -0
- data/spec/plugin/path_spec.rb +41 -40
- data/spec/plugin/per_thread_caching_spec.rb +6 -6
- data/spec/plugin/precompile_templates_spec.rb +74 -0
- data/spec/plugin/render_each_spec.rb +4 -4
- data/spec/plugin/render_spec.rb +179 -76
- data/spec/plugin/shared_vars_spec.rb +4 -4
- data/spec/plugin/sinatra_helpers_spec.rb +121 -121
- data/spec/plugin/slash_path_empty_spec.rb +10 -10
- data/spec/plugin/static_spec.rb +4 -4
- data/spec/plugin/streaming_spec.rb +11 -11
- data/spec/plugin/symbol_matchers_spec.rb +24 -24
- data/spec/plugin/symbol_views_spec.rb +3 -3
- data/spec/plugin/view_options_spec.rb +10 -10
- data/spec/plugin_spec.rb +2 -2
- data/spec/redirect_spec.rb +10 -10
- data/spec/request_spec.rb +8 -8
- data/spec/response_spec.rb +23 -23
- data/spec/session_spec.rb +4 -4
- data/spec/spec_helper.rb +5 -19
- data/spec/version_spec.rb +4 -4
- data/spec/views/iv.erb +1 -0
- metadata +16 -5
@@ -39,41 +39,41 @@ describe "class_level_routing plugin" do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it "adds class methods for setting up routes" do
|
42
|
-
body.
|
43
|
-
body('/foo').
|
44
|
-
body('/foo/bar').
|
45
|
-
body('/dgo').
|
46
|
-
body('/dgo', 'REQUEST_METHOD'=>'POST').
|
47
|
-
body('/bar').
|
48
|
-
body('/bar', 'REQUEST_METHOD'=>'POST').
|
49
|
-
body('/bar', 'REQUEST_METHOD'=>'DELETE').
|
50
|
-
body('/bar', 'REQUEST_METHOD'=>'HEAD').
|
51
|
-
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').
|
52
|
-
body('/bar', 'REQUEST_METHOD'=>'PATCH').
|
53
|
-
body('/bar', 'REQUEST_METHOD'=>'PUT').
|
54
|
-
body('/bar', 'REQUEST_METHOD'=>'TRACE').
|
42
|
+
body.must_equal 'root'
|
43
|
+
body('/foo').must_equal 'foo'
|
44
|
+
body('/foo/bar').must_equal 'foobar'
|
45
|
+
body('/dgo').must_equal 'bazgetgo'
|
46
|
+
body('/dgo', 'REQUEST_METHOD'=>'POST').must_equal 'bazpostgo'
|
47
|
+
body('/bar').must_equal "x-get-bar"
|
48
|
+
body('/bar', 'REQUEST_METHOD'=>'POST').must_equal "x-post-bar"
|
49
|
+
body('/bar', 'REQUEST_METHOD'=>'DELETE').must_equal "x-delete-bar"
|
50
|
+
body('/bar', 'REQUEST_METHOD'=>'HEAD').must_equal "x-head-bar"
|
51
|
+
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').must_equal "x-options-bar"
|
52
|
+
body('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal "x-patch-bar"
|
53
|
+
body('/bar', 'REQUEST_METHOD'=>'PUT').must_equal "x-put-bar"
|
54
|
+
body('/bar', 'REQUEST_METHOD'=>'TRACE').must_equal "x-trace-bar"
|
55
55
|
if ::Rack::Request.method_defined?("link?")
|
56
|
-
body('/bar', 'REQUEST_METHOD'=>'LINK').
|
57
|
-
body('/bar', 'REQUEST_METHOD'=>'UNLINK').
|
56
|
+
body('/bar', 'REQUEST_METHOD'=>'LINK').must_equal "x-link-bar"
|
57
|
+
body('/bar', 'REQUEST_METHOD'=>'UNLINK').must_equal "x-unlink-bar"
|
58
58
|
end
|
59
59
|
|
60
|
-
status.
|
61
|
-
status("/asdfa/asdf").
|
60
|
+
status.must_equal 200
|
61
|
+
status("/asdfa/asdf").must_equal 404
|
62
62
|
|
63
63
|
@app = Class.new(app)
|
64
|
-
body.
|
65
|
-
body('/foo').
|
66
|
-
body('/foo/bar').
|
67
|
-
body('/dgo').
|
68
|
-
body('/dgo', 'REQUEST_METHOD'=>'POST').
|
69
|
-
body('/bar').
|
70
|
-
body('/bar', 'REQUEST_METHOD'=>'POST').
|
71
|
-
body('/bar', 'REQUEST_METHOD'=>'DELETE').
|
72
|
-
body('/bar', 'REQUEST_METHOD'=>'HEAD').
|
73
|
-
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').
|
74
|
-
body('/bar', 'REQUEST_METHOD'=>'PATCH').
|
75
|
-
body('/bar', 'REQUEST_METHOD'=>'PUT').
|
76
|
-
body('/bar', 'REQUEST_METHOD'=>'TRACE').
|
64
|
+
body.must_equal 'root'
|
65
|
+
body('/foo').must_equal 'foo'
|
66
|
+
body('/foo/bar').must_equal 'foobar'
|
67
|
+
body('/dgo').must_equal 'bazgetgo'
|
68
|
+
body('/dgo', 'REQUEST_METHOD'=>'POST').must_equal 'bazpostgo'
|
69
|
+
body('/bar').must_equal "x-get-bar"
|
70
|
+
body('/bar', 'REQUEST_METHOD'=>'POST').must_equal "x-post-bar"
|
71
|
+
body('/bar', 'REQUEST_METHOD'=>'DELETE').must_equal "x-delete-bar"
|
72
|
+
body('/bar', 'REQUEST_METHOD'=>'HEAD').must_equal "x-head-bar"
|
73
|
+
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').must_equal "x-options-bar"
|
74
|
+
body('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal "x-patch-bar"
|
75
|
+
body('/bar', 'REQUEST_METHOD'=>'PUT').must_equal "x-put-bar"
|
76
|
+
body('/bar', 'REQUEST_METHOD'=>'TRACE').must_equal "x-trace-bar"
|
77
77
|
end
|
78
78
|
|
79
79
|
it "only calls class level routes if routing tree doesn't handle request" do
|
@@ -97,19 +97,19 @@ describe "class_level_routing plugin" do
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
body.
|
101
|
-
body('/foo').
|
102
|
-
body('/foo/bar').
|
103
|
-
body('/dgo').
|
104
|
-
body('/dgo', 'REQUEST_METHOD'=>'POST').
|
105
|
-
body('/bar').
|
106
|
-
body('/bar', 'REQUEST_METHOD'=>'POST').
|
107
|
-
body('/bar', 'REQUEST_METHOD'=>'DELETE').
|
108
|
-
body('/bar', 'REQUEST_METHOD'=>'HEAD').
|
109
|
-
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').
|
110
|
-
body('/bar', 'REQUEST_METHOD'=>'PATCH').
|
111
|
-
body('/bar', 'REQUEST_METHOD'=>'PUT').
|
112
|
-
body('/bar', 'REQUEST_METHOD'=>'TRACE').
|
100
|
+
body.must_equal 'iroot'
|
101
|
+
body('/foo').must_equal 'ifoo'
|
102
|
+
body('/foo/bar').must_equal 'foobar'
|
103
|
+
body('/dgo').must_equal 'bazgetgo'
|
104
|
+
body('/dgo', 'REQUEST_METHOD'=>'POST').must_equal 'bazpostgo'
|
105
|
+
body('/bar').must_equal ""
|
106
|
+
body('/bar', 'REQUEST_METHOD'=>'POST').must_equal "ibar"
|
107
|
+
body('/bar', 'REQUEST_METHOD'=>'DELETE').must_equal "x-delete-bar"
|
108
|
+
body('/bar', 'REQUEST_METHOD'=>'HEAD').must_equal "x-head-bar"
|
109
|
+
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').must_equal "x-options-bar"
|
110
|
+
body('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal "x-patch-bar"
|
111
|
+
body('/bar', 'REQUEST_METHOD'=>'PUT').must_equal "x-put-bar"
|
112
|
+
body('/bar', 'REQUEST_METHOD'=>'TRACE').must_equal "x-trace-bar"
|
113
113
|
end
|
114
114
|
|
115
115
|
it "works with the not_found plugin if loaded before" do
|
@@ -117,48 +117,48 @@ describe "class_level_routing plugin" do
|
|
117
117
|
"nf"
|
118
118
|
end
|
119
119
|
|
120
|
-
body.
|
121
|
-
body('/foo').
|
122
|
-
body('/foo/bar').
|
123
|
-
body('/dgo').
|
124
|
-
body('/dgo', 'REQUEST_METHOD'=>'POST').
|
125
|
-
body('/bar').
|
126
|
-
body('/bar', 'REQUEST_METHOD'=>'POST').
|
127
|
-
body('/bar', 'REQUEST_METHOD'=>'DELETE').
|
128
|
-
body('/bar', 'REQUEST_METHOD'=>'HEAD').
|
129
|
-
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').
|
130
|
-
body('/bar', 'REQUEST_METHOD'=>'PATCH').
|
131
|
-
body('/bar', 'REQUEST_METHOD'=>'PUT').
|
132
|
-
body('/bar', 'REQUEST_METHOD'=>'TRACE').
|
133
|
-
|
134
|
-
status.
|
135
|
-
status("/asdfa/asdf").
|
136
|
-
body("/asdfa/asdf").
|
120
|
+
body.must_equal 'root'
|
121
|
+
body('/foo').must_equal 'foo'
|
122
|
+
body('/foo/bar').must_equal 'foobar'
|
123
|
+
body('/dgo').must_equal 'bazgetgo'
|
124
|
+
body('/dgo', 'REQUEST_METHOD'=>'POST').must_equal 'bazpostgo'
|
125
|
+
body('/bar').must_equal "x-get-bar"
|
126
|
+
body('/bar', 'REQUEST_METHOD'=>'POST').must_equal "x-post-bar"
|
127
|
+
body('/bar', 'REQUEST_METHOD'=>'DELETE').must_equal "x-delete-bar"
|
128
|
+
body('/bar', 'REQUEST_METHOD'=>'HEAD').must_equal "x-head-bar"
|
129
|
+
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').must_equal "x-options-bar"
|
130
|
+
body('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal "x-patch-bar"
|
131
|
+
body('/bar', 'REQUEST_METHOD'=>'PUT').must_equal "x-put-bar"
|
132
|
+
body('/bar', 'REQUEST_METHOD'=>'TRACE').must_equal "x-trace-bar"
|
133
|
+
|
134
|
+
status.must_equal 200
|
135
|
+
status("/asdfa/asdf").must_equal 404
|
136
|
+
body("/asdfa/asdf").must_equal "nf"
|
137
137
|
end
|
138
138
|
|
139
139
|
it "works when freezing the app" do
|
140
140
|
app.freeze
|
141
|
-
body.
|
142
|
-
body('/foo').
|
143
|
-
body('/foo/bar').
|
144
|
-
body('/dgo').
|
145
|
-
body('/dgo', 'REQUEST_METHOD'=>'POST').
|
146
|
-
body('/bar').
|
147
|
-
body('/bar', 'REQUEST_METHOD'=>'POST').
|
148
|
-
body('/bar', 'REQUEST_METHOD'=>'DELETE').
|
149
|
-
body('/bar', 'REQUEST_METHOD'=>'HEAD').
|
150
|
-
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').
|
151
|
-
body('/bar', 'REQUEST_METHOD'=>'PATCH').
|
152
|
-
body('/bar', 'REQUEST_METHOD'=>'PUT').
|
153
|
-
body('/bar', 'REQUEST_METHOD'=>'TRACE').
|
141
|
+
body.must_equal 'root'
|
142
|
+
body('/foo').must_equal 'foo'
|
143
|
+
body('/foo/bar').must_equal 'foobar'
|
144
|
+
body('/dgo').must_equal 'bazgetgo'
|
145
|
+
body('/dgo', 'REQUEST_METHOD'=>'POST').must_equal 'bazpostgo'
|
146
|
+
body('/bar').must_equal "x-get-bar"
|
147
|
+
body('/bar', 'REQUEST_METHOD'=>'POST').must_equal "x-post-bar"
|
148
|
+
body('/bar', 'REQUEST_METHOD'=>'DELETE').must_equal "x-delete-bar"
|
149
|
+
body('/bar', 'REQUEST_METHOD'=>'HEAD').must_equal "x-head-bar"
|
150
|
+
body('/bar', 'REQUEST_METHOD'=>'OPTIONS').must_equal "x-options-bar"
|
151
|
+
body('/bar', 'REQUEST_METHOD'=>'PATCH').must_equal "x-patch-bar"
|
152
|
+
body('/bar', 'REQUEST_METHOD'=>'PUT').must_equal "x-put-bar"
|
153
|
+
body('/bar', 'REQUEST_METHOD'=>'TRACE').must_equal "x-trace-bar"
|
154
154
|
if ::Rack::Request.method_defined?("link?")
|
155
|
-
body('/bar', 'REQUEST_METHOD'=>'LINK').
|
156
|
-
body('/bar', 'REQUEST_METHOD'=>'UNLINK').
|
155
|
+
body('/bar', 'REQUEST_METHOD'=>'LINK').must_equal "x-link-bar"
|
156
|
+
body('/bar', 'REQUEST_METHOD'=>'UNLINK').must_equal "x-unlink-bar"
|
157
157
|
end
|
158
158
|
|
159
|
-
status.
|
160
|
-
status("/asdfa/asdf").
|
159
|
+
status.must_equal 200
|
160
|
+
status("/asdfa/asdf").must_equal 404
|
161
161
|
|
162
|
-
proc{app.on{}}.
|
162
|
+
proc{app.on{}}.must_raise FrozenError
|
163
163
|
end
|
164
164
|
end
|
@@ -23,11 +23,11 @@ describe "content_for plugin" do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should be able to set content in template and get that content in the layout" do
|
26
|
-
body.strip.
|
26
|
+
body.strip.must_equal "bar foo"
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should work if content is not set by the template" do
|
30
|
-
body('/a').strip.
|
30
|
+
body('/a').strip.must_equal "bar"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/spec/plugin/cookies_spec.rb
CHANGED
@@ -8,8 +8,8 @@ describe "cookies plugin" do
|
|
8
8
|
"Hello"
|
9
9
|
end
|
10
10
|
|
11
|
-
header('Set-Cookie').
|
12
|
-
body.
|
11
|
+
header('Set-Cookie').must_equal "foo=bar\nbar=baz"
|
12
|
+
body.must_equal 'Hello'
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should delete cookies on response" do
|
@@ -19,7 +19,7 @@ describe "cookies plugin" do
|
|
19
19
|
"Hello"
|
20
20
|
end
|
21
21
|
|
22
|
-
header('Set-Cookie').
|
23
|
-
body.
|
22
|
+
header('Set-Cookie').must_match(/foo=; (max-age=0; )?expires=Thu, 01[ -]Jan[ -]1970 00:00:00 (-0000|GMT)/)
|
23
|
+
body.must_equal 'Hello'
|
24
24
|
end
|
25
25
|
end
|
data/spec/plugin/csrf_spec.rb
CHANGED
@@ -30,20 +30,20 @@ describe "csrf plugin" do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
io = StringIO.new
|
33
|
-
status('REQUEST_METHOD'=>'POST', 'rack.input'=>io).
|
34
|
-
body('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).
|
33
|
+
status('REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 403
|
34
|
+
body('/foo', 'REQUEST_METHOD'=>'POST', 'rack.input'=>io).must_equal 'bar'
|
35
35
|
|
36
36
|
env = proc{|h| h['Set-Cookie'] ? {'HTTP_COOKIE'=>h['Set-Cookie'].sub("; path=/; HttpOnly", '')} : {}}
|
37
37
|
s, h, b = req
|
38
|
-
s.
|
38
|
+
s.must_equal 200
|
39
39
|
field = h['FIELD']
|
40
40
|
token = Regexp.escape(h['TOKEN'])
|
41
|
-
h['TAG'].
|
42
|
-
h['METATAG'].
|
43
|
-
b.
|
41
|
+
h['TAG'].must_match(/\A<input type="hidden" name="#{field}" value="#{token}" \/>\z/)
|
42
|
+
h['METATAG'].must_match(/\A<meta name="#{field}" content="#{token}" \/>\z/)
|
43
|
+
b.must_equal ['g']
|
44
44
|
s, _, b = req('/', env[h].merge('REQUEST_METHOD'=>'POST', 'rack.input'=>io, "HTTP_#{h['HEADER']}"=>h['TOKEN']))
|
45
|
-
s.
|
46
|
-
b.
|
45
|
+
s.must_equal 200
|
46
|
+
b.must_equal ['p']
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -11,8 +11,8 @@ describe "default_headers plugin" do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
req[1].
|
15
|
-
req[1].
|
14
|
+
req[1].must_equal h
|
15
|
+
req[1].wont_be_same_as h
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should not override existing default headers" do
|
@@ -27,7 +27,7 @@ describe "default_headers plugin" do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
req[1].
|
30
|
+
req[1].must_equal h
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should allow modifying the default headers by reloading the plugin" do
|
@@ -40,7 +40,7 @@ describe "default_headers plugin" do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
req[1].
|
43
|
+
req[1].must_equal('Content-Type'=>'text/json', 'Foo'=>'baz')
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should have a default Content-Type header" do
|
@@ -54,7 +54,7 @@ describe "default_headers plugin" do
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
req[1].
|
57
|
+
req[1].must_equal('Content-Type'=>'text/html', 'Foo'=>'bar')
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should work correctly in subclasses" do
|
@@ -70,6 +70,6 @@ describe "default_headers plugin" do
|
|
70
70
|
|
71
71
|
@app = Class.new(@app)
|
72
72
|
|
73
|
-
req[1].
|
73
|
+
req[1].must_equal h
|
74
74
|
end
|
75
75
|
end
|
@@ -3,21 +3,22 @@ require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
|
3
3
|
describe "delay_build plugin" do
|
4
4
|
it "does not build rack app until app is called" do
|
5
5
|
app(:delay_build){"a"}
|
6
|
-
app.instance_variable_get(:@app).
|
7
|
-
body.
|
8
|
-
|
6
|
+
app.instance_variable_get(:@app).must_equal nil
|
7
|
+
body.must_equal "a"
|
8
|
+
# Work around minitest bug
|
9
|
+
refute_equal app.instance_variable_get(:@app), nil
|
9
10
|
end
|
10
11
|
|
11
12
|
it "only rebuilds the app if build! is called" do
|
12
13
|
app(:delay_build){"a"}
|
13
|
-
body.
|
14
|
+
body.must_equal "a"
|
14
15
|
c = Class.new do
|
15
16
|
def initialize(_) end
|
16
17
|
def call(_) [200, {}, ["b"]] end
|
17
18
|
end
|
18
19
|
app.use c
|
19
|
-
body.
|
20
|
+
body.must_equal "a"
|
20
21
|
app.build!
|
21
|
-
body.
|
22
|
+
body.must_equal "b"
|
22
23
|
end
|
23
24
|
end
|
@@ -10,7 +10,7 @@ describe "delete_empty_headers plugin" do
|
|
10
10
|
'a'
|
11
11
|
end
|
12
12
|
|
13
|
-
req[1].
|
13
|
+
req[1].must_equal('Bar'=>'1')
|
14
14
|
end
|
15
15
|
|
16
16
|
it "is called when finishing with a body" do
|
@@ -22,6 +22,6 @@ describe "delete_empty_headers plugin" do
|
|
22
22
|
r.halt response.finish_with_body(['a'])
|
23
23
|
end
|
24
24
|
|
25
|
-
req[1].
|
25
|
+
req[1].must_equal('Bar'=>'1')
|
26
26
|
end
|
27
27
|
end
|
@@ -8,13 +8,13 @@ describe "drop_body plugin" do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
[101, 102, 204, 205, 304].each do |i|
|
11
|
-
body(i.to_s).
|
12
|
-
header('Content-Type', i.to_s).
|
13
|
-
header('Content-Length', i.to_s).
|
11
|
+
body(i.to_s).must_equal ''
|
12
|
+
header('Content-Type', i.to_s).must_equal nil
|
13
|
+
header('Content-Length', i.to_s).must_equal nil
|
14
14
|
end
|
15
15
|
|
16
|
-
body('200').
|
17
|
-
header('Content-Type', '200').
|
18
|
-
header('Content-Length', '200').
|
16
|
+
body('200').must_equal 'a'
|
17
|
+
header('Content-Type', '200').must_equal 'text/html'
|
18
|
+
header('Content-Length', '200').must_equal '1'
|
19
19
|
end
|
20
20
|
end
|
@@ -7,18 +7,18 @@ describe "environments plugin" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "adds environment accessor for getting/setting the environment" do
|
10
|
-
app.environment.
|
10
|
+
app.environment.must_equal :development
|
11
11
|
app.environment = :test
|
12
|
-
app.environment.
|
12
|
+
app.environment.must_equal :test
|
13
13
|
|
14
14
|
app.plugin :environments, :production
|
15
|
-
app.environment.
|
15
|
+
app.environment.must_equal :production
|
16
16
|
end
|
17
17
|
|
18
18
|
it "adds predicates for testing the environment" do
|
19
|
-
app.development?.
|
20
|
-
app.test?.
|
21
|
-
app.production?.
|
19
|
+
app.development?.must_equal true
|
20
|
+
app.test?.must_equal false
|
21
|
+
app.production?.must_equal false
|
22
22
|
end
|
23
23
|
|
24
24
|
it "adds configure method which yields if no arguments are given or an environment matches" do
|
@@ -26,6 +26,6 @@ describe "environments plugin" do
|
|
26
26
|
app.configure{a << 1}
|
27
27
|
app.configure(:development){|ap| a << ap}
|
28
28
|
app.configure(:test, :production){a << 2}
|
29
|
-
a.
|
29
|
+
a.must_equal [1, app]
|
30
30
|
end
|
31
31
|
end
|
@@ -19,18 +19,18 @@ describe "error_email plugin" do
|
|
19
19
|
|
20
20
|
it "adds error_email method for emailing exceptions" do
|
21
21
|
app
|
22
|
-
body('rack.input'=>StringIO.new, 'QUERY_STRING'=>'b=c', 'rack.session'=>{'d'=>'e'}).
|
23
|
-
email[:to].
|
24
|
-
email[:from].
|
25
|
-
email[:host].
|
26
|
-
email[:message].
|
27
|
-
email[:message].
|
22
|
+
body('rack.input'=>StringIO.new, 'QUERY_STRING'=>'b=c', 'rack.session'=>{'d'=>'e'}).must_equal 'e'
|
23
|
+
email[:to].must_equal 't'
|
24
|
+
email[:from].must_equal 'f'
|
25
|
+
email[:host].must_equal 'localhost'
|
26
|
+
email[:message].must_match(/^Subject: ArgumentError/)
|
27
|
+
email[:message].must_match(/^Backtrace:$.+^ENV:$.+^"rack\.input" => .+^Params:$\s+^"b" => "c"$\s+^Session:$\s+^"d" => "e"$/m)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "uses :host option" do
|
31
31
|
app(:host=>'foo.bar.com')
|
32
|
-
body('rack.input'=>StringIO.new).
|
33
|
-
email[:host].
|
32
|
+
body('rack.input'=>StringIO.new).must_equal 'e'
|
33
|
+
email[:host].must_equal 'foo.bar.com'
|
34
34
|
end
|
35
35
|
|
36
36
|
it "handles error messages with new lines" do
|
@@ -38,26 +38,26 @@ describe "error_email plugin" do
|
|
38
38
|
raise "foo\nbar\nbaz" rescue error_email($!)
|
39
39
|
'e'
|
40
40
|
end
|
41
|
-
body('rack.input'=>StringIO.new).
|
42
|
-
email[:message].
|
41
|
+
body('rack.input'=>StringIO.new).must_equal 'e'
|
42
|
+
email[:message].must_match %r{From: f\r\nSubject: RuntimeError: foo\r\n bar\r\n baz\r\nTo: t\r\n\r\n}
|
43
43
|
end
|
44
44
|
|
45
45
|
it "adds :prefix option to subject line" do
|
46
46
|
app(:prefix=>'TEST ')
|
47
|
-
body('rack.input'=>StringIO.new).
|
48
|
-
email[:message].
|
47
|
+
body('rack.input'=>StringIO.new).must_equal 'e'
|
48
|
+
email[:message].must_match(/^Subject: TEST ArgumentError/)
|
49
49
|
end
|
50
50
|
|
51
51
|
it "uses :headers option for additional headers" do
|
52
52
|
app(:headers=>{'Foo'=>'Bar', 'Baz'=>'Quux'})
|
53
|
-
body('rack.input'=>StringIO.new).
|
54
|
-
email[:message].
|
55
|
-
email[:message].
|
53
|
+
body('rack.input'=>StringIO.new).must_equal 'e'
|
54
|
+
email[:message].must_match(/^Foo: Bar/)
|
55
|
+
email[:message].must_match(/^Baz: Quux/)
|
56
56
|
end
|
57
57
|
|
58
58
|
it "requires the :to and :from options" do
|
59
|
-
proc{app :from=>nil}.
|
60
|
-
proc{app :to=>nil}.
|
59
|
+
proc{app :from=>nil}.must_raise(Roda::RodaError)
|
60
|
+
proc{app :to=>nil}.must_raise(Roda::RodaError)
|
61
61
|
end
|
62
62
|
|
63
63
|
it "works correctly in subclasses" do
|
@@ -66,11 +66,11 @@ describe "error_email plugin" do
|
|
66
66
|
raise ArgumentError rescue error_email($!)
|
67
67
|
'e'
|
68
68
|
end
|
69
|
-
body('rack.input'=>StringIO.new).
|
70
|
-
email[:to].
|
71
|
-
email[:from].
|
72
|
-
email[:host].
|
73
|
-
email[:message].
|
74
|
-
email[:message].
|
69
|
+
body('rack.input'=>StringIO.new).must_equal 'e'
|
70
|
+
email[:to].must_equal 't'
|
71
|
+
email[:from].must_equal 'f'
|
72
|
+
email[:host].must_equal 'localhost'
|
73
|
+
email[:message].must_match(/^Subject: ArgumentError/)
|
74
|
+
email[:message].must_match(/Backtrace.*ENV/m)
|
75
75
|
end
|
76
76
|
end
|