roda 3.28.0 → 3.29.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +10 -0
  3. data/README.rdoc +10 -0
  4. data/doc/release_notes/3.29.0.txt +15 -0
  5. data/lib/roda.rb +1 -0
  6. data/lib/roda/plugins/caching.rb +2 -0
  7. data/lib/roda/plugins/common_logger.rb +1 -1
  8. data/lib/roda/plugins/exception_page.rb +7 -1
  9. data/lib/roda/plugins/indifferent_params.rb +2 -0
  10. data/lib/roda/version.rb +1 -1
  11. metadata +4 -214
  12. data/Rakefile +0 -108
  13. data/doc/release_notes/1.0.0.txt +0 -329
  14. data/doc/release_notes/1.1.0.txt +0 -226
  15. data/doc/release_notes/1.2.0.txt +0 -406
  16. data/doc/release_notes/1.3.0.txt +0 -109
  17. data/doc/release_notes/2.0.0.txt +0 -75
  18. data/doc/release_notes/2.1.0.txt +0 -124
  19. data/doc/release_notes/2.10.0.txt +0 -27
  20. data/doc/release_notes/2.11.0.txt +0 -70
  21. data/doc/release_notes/2.12.0.txt +0 -40
  22. data/doc/release_notes/2.13.0.txt +0 -10
  23. data/doc/release_notes/2.14.0.txt +0 -44
  24. data/doc/release_notes/2.15.0.txt +0 -53
  25. data/doc/release_notes/2.16.0.txt +0 -48
  26. data/doc/release_notes/2.17.0.txt +0 -62
  27. data/doc/release_notes/2.18.0.txt +0 -69
  28. data/doc/release_notes/2.19.0.txt +0 -30
  29. data/doc/release_notes/2.2.0.txt +0 -97
  30. data/doc/release_notes/2.20.0.txt +0 -5
  31. data/doc/release_notes/2.21.0.txt +0 -17
  32. data/doc/release_notes/2.22.0.txt +0 -41
  33. data/doc/release_notes/2.23.0.txt +0 -29
  34. data/doc/release_notes/2.24.0.txt +0 -65
  35. data/doc/release_notes/2.25.0.txt +0 -14
  36. data/doc/release_notes/2.26.0.txt +0 -13
  37. data/doc/release_notes/2.27.0.txt +0 -56
  38. data/doc/release_notes/2.28.0.txt +0 -17
  39. data/doc/release_notes/2.29.0.txt +0 -156
  40. data/doc/release_notes/2.3.0.txt +0 -109
  41. data/doc/release_notes/2.4.0.txt +0 -55
  42. data/doc/release_notes/2.5.0.txt +0 -23
  43. data/doc/release_notes/2.5.1.txt +0 -4
  44. data/doc/release_notes/2.6.0.txt +0 -21
  45. data/doc/release_notes/2.7.0.txt +0 -75
  46. data/doc/release_notes/2.8.0.txt +0 -44
  47. data/doc/release_notes/2.9.0.txt +0 -6
  48. data/spec/all.rb +0 -1
  49. data/spec/assets/css/app.scss +0 -1
  50. data/spec/assets/css/no_access.css +0 -1
  51. data/spec/assets/css/raw.css +0 -1
  52. data/spec/assets/js/head/app.js +0 -1
  53. data/spec/composition_spec.rb +0 -31
  54. data/spec/define_roda_method_spec.rb +0 -274
  55. data/spec/env_spec.rb +0 -11
  56. data/spec/freeze_spec.rb +0 -37
  57. data/spec/integration_spec.rb +0 -209
  58. data/spec/matchers_spec.rb +0 -832
  59. data/spec/opts_spec.rb +0 -42
  60. data/spec/plugin/_after_hook_spec.rb +0 -19
  61. data/spec/plugin/all_verbs_spec.rb +0 -29
  62. data/spec/plugin/assets_preloading_spec.rb +0 -98
  63. data/spec/plugin/assets_spec.rb +0 -745
  64. data/spec/plugin/backtracking_array_spec.rb +0 -42
  65. data/spec/plugin/branch_locals_spec.rb +0 -106
  66. data/spec/plugin/caching_spec.rb +0 -337
  67. data/spec/plugin/chunked_spec.rb +0 -201
  68. data/spec/plugin/class_level_routing_spec.rb +0 -164
  69. data/spec/plugin/class_matchers_spec.rb +0 -40
  70. data/spec/plugin/common_logger_spec.rb +0 -85
  71. data/spec/plugin/content_for_spec.rb +0 -162
  72. data/spec/plugin/content_security_policy_spec.rb +0 -175
  73. data/spec/plugin/cookies_spec.rb +0 -51
  74. data/spec/plugin/csrf_spec.rb +0 -111
  75. data/spec/plugin/default_headers_spec.rb +0 -82
  76. data/spec/plugin/default_status_spec.rb +0 -95
  77. data/spec/plugin/delay_build_spec.rb +0 -23
  78. data/spec/plugin/delegate_spec.rb +0 -23
  79. data/spec/plugin/delete_empty_headers_spec.rb +0 -27
  80. data/spec/plugin/direct_call_spec.rb +0 -28
  81. data/spec/plugin/disallow_file_uploads_spec.rb +0 -25
  82. data/spec/plugin/drop_body_spec.rb +0 -24
  83. data/spec/plugin/early_hints_spec.rb +0 -19
  84. data/spec/plugin/empty_root_spec.rb +0 -14
  85. data/spec/plugin/environments_spec.rb +0 -42
  86. data/spec/plugin/error_email_spec.rb +0 -97
  87. data/spec/plugin/error_handler_spec.rb +0 -216
  88. data/spec/plugin/error_mail_spec.rb +0 -93
  89. data/spec/plugin/exception_page_spec.rb +0 -168
  90. data/spec/plugin/flash_spec.rb +0 -121
  91. data/spec/plugin/h_spec.rb +0 -11
  92. data/spec/plugin/halt_spec.rb +0 -119
  93. data/spec/plugin/hash_matcher_spec.rb +0 -27
  94. data/spec/plugin/hash_routes_spec.rb +0 -535
  95. data/spec/plugin/head_spec.rb +0 -52
  96. data/spec/plugin/header_matchers_spec.rb +0 -98
  97. data/spec/plugin/heartbeat_spec.rb +0 -74
  98. data/spec/plugin/hooks_spec.rb +0 -152
  99. data/spec/plugin/indifferent_params_spec.rb +0 -14
  100. data/spec/plugin/json_parser_spec.rb +0 -141
  101. data/spec/plugin/json_spec.rb +0 -83
  102. data/spec/plugin/mail_processor_spec.rb +0 -451
  103. data/spec/plugin/mailer_spec.rb +0 -282
  104. data/spec/plugin/match_affix_spec.rb +0 -43
  105. data/spec/plugin/match_hook_spec.rb +0 -79
  106. data/spec/plugin/middleware_spec.rb +0 -237
  107. data/spec/plugin/middleware_stack_spec.rb +0 -81
  108. data/spec/plugin/module_include_spec.rb +0 -48
  109. data/spec/plugin/multi_route_spec.rb +0 -268
  110. data/spec/plugin/multi_run_spec.rb +0 -87
  111. data/spec/plugin/multi_view_spec.rb +0 -50
  112. data/spec/plugin/multibyte_string_matcher_spec.rb +0 -44
  113. data/spec/plugin/named_templates_spec.rb +0 -96
  114. data/spec/plugin/not_allowed_spec.rb +0 -69
  115. data/spec/plugin/not_found_spec.rb +0 -128
  116. data/spec/plugin/optimized_string_matchers_spec.rb +0 -43
  117. data/spec/plugin/padrino_render_spec.rb +0 -34
  118. data/spec/plugin/param_matchers_spec.rb +0 -69
  119. data/spec/plugin/params_capturing_spec.rb +0 -33
  120. data/spec/plugin/partials_spec.rb +0 -43
  121. data/spec/plugin/pass_spec.rb +0 -29
  122. data/spec/plugin/path_matchers_spec.rb +0 -42
  123. data/spec/plugin/path_rewriter_spec.rb +0 -45
  124. data/spec/plugin/path_spec.rb +0 -222
  125. data/spec/plugin/placeholder_string_matchers_spec.rb +0 -126
  126. data/spec/plugin/precompile_templates_spec.rb +0 -61
  127. data/spec/plugin/public_spec.rb +0 -85
  128. data/spec/plugin/render_each_spec.rb +0 -82
  129. data/spec/plugin/render_locals_spec.rb +0 -114
  130. data/spec/plugin/render_spec.rb +0 -912
  131. data/spec/plugin/request_aref_spec.rb +0 -51
  132. data/spec/plugin/request_headers_spec.rb +0 -39
  133. data/spec/plugin/response_request_spec.rb +0 -43
  134. data/spec/plugin/route_block_args_spec.rb +0 -86
  135. data/spec/plugin/route_csrf_spec.rb +0 -305
  136. data/spec/plugin/run_append_slash_spec.rb +0 -77
  137. data/spec/plugin/run_handler_spec.rb +0 -53
  138. data/spec/plugin/sessions_spec.rb +0 -452
  139. data/spec/plugin/shared_vars_spec.rb +0 -45
  140. data/spec/plugin/sinatra_helpers_spec.rb +0 -537
  141. data/spec/plugin/slash_path_empty_spec.rb +0 -22
  142. data/spec/plugin/static_routing_spec.rb +0 -192
  143. data/spec/plugin/static_spec.rb +0 -30
  144. data/spec/plugin/status_303_spec.rb +0 -28
  145. data/spec/plugin/status_handler_spec.rb +0 -158
  146. data/spec/plugin/streaming_spec.rb +0 -246
  147. data/spec/plugin/strip_path_prefix_spec.rb +0 -24
  148. data/spec/plugin/symbol_matchers_spec.rb +0 -51
  149. data/spec/plugin/symbol_status_spec.rb +0 -25
  150. data/spec/plugin/symbol_views_spec.rb +0 -32
  151. data/spec/plugin/timestamp_public_spec.rb +0 -85
  152. data/spec/plugin/type_routing_spec.rb +0 -348
  153. data/spec/plugin/typecast_params_spec.rb +0 -1370
  154. data/spec/plugin/unescape_path_spec.rb +0 -22
  155. data/spec/plugin/view_options_spec.rb +0 -170
  156. data/spec/plugin_spec.rb +0 -71
  157. data/spec/redirect_spec.rb +0 -41
  158. data/spec/request_spec.rb +0 -97
  159. data/spec/response_spec.rb +0 -199
  160. data/spec/route_spec.rb +0 -39
  161. data/spec/session_middleware_spec.rb +0 -129
  162. data/spec/session_spec.rb +0 -37
  163. data/spec/spec_helper.rb +0 -137
  164. data/spec/version_spec.rb +0 -14
  165. data/spec/views/_test.erb +0 -1
  166. data/spec/views/a.erb +0 -1
  167. data/spec/views/a.rdoc +0 -2
  168. data/spec/views/about.erb +0 -1
  169. data/spec/views/about.str +0 -1
  170. data/spec/views/about/_test.css.gz +0 -0
  171. data/spec/views/about/_test.erb +0 -1
  172. data/spec/views/about/_test.erb.gz +0 -0
  173. data/spec/views/about/comp_test.erb +0 -1
  174. data/spec/views/b.erb +0 -1
  175. data/spec/views/c.erb +0 -1
  176. data/spec/views/comp_layout.erb +0 -1
  177. data/spec/views/comp_test.erb +0 -1
  178. data/spec/views/content-yield.erb +0 -1
  179. data/spec/views/each.str +0 -1
  180. data/spec/views/home.erb +0 -2
  181. data/spec/views/home.str +0 -2
  182. data/spec/views/iv.erb +0 -1
  183. data/spec/views/layout-alternative.erb +0 -2
  184. data/spec/views/layout-yield.erb +0 -3
  185. data/spec/views/layout.erb +0 -2
  186. data/spec/views/layout.str +0 -2
  187. data/spec/views/multiple-layout.erb +0 -1
  188. data/spec/views/multiple.erb +0 -1
@@ -1,52 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "head plugin" do
4
- it "considers HEAD requests as GET requests which return no body" do
5
- app(:head) do |r|
6
- r.root do
7
- 'root'
8
- end
9
-
10
- r.get 'a' do
11
- 'a'
12
- end
13
-
14
- r.is 'b', :method=>[:get, :post] do
15
- 'b'
16
- end
17
- end
18
-
19
- s, h, b = req
20
- s.must_equal 200
21
- h['Content-Length'].must_equal '4'
22
- b.must_equal ['root']
23
-
24
- s, h, b = req('REQUEST_METHOD' => 'HEAD')
25
- s.must_equal 200
26
- h['Content-Length'].must_equal '4'
27
- b.must_equal []
28
-
29
- body('/a').must_equal 'a'
30
- status('/a', 'REQUEST_METHOD' => 'HEAD').must_equal 200
31
-
32
- body('/b').must_equal 'b'
33
- status('/b', 'REQUEST_METHOD' => 'HEAD').must_equal 200
34
- end
35
-
36
- it "releases resources via body.close" do
37
- body = StringIO.new('hi')
38
- app(:head) do |r|
39
- r.root do
40
- r.halt [ 200, {}, body ]
41
- end
42
- end
43
- s, _, b = req('REQUEST_METHOD' => 'HEAD')
44
- s.must_equal 200
45
- res = String.new
46
- body.closed?.must_equal false
47
- b.each { |buf| res << buf }
48
- b.close
49
- body.closed?.must_equal true
50
- res.must_equal ''
51
- end
52
- end
@@ -1,98 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "accept matcher" do
4
- it "should accept mimetypes and set response Content-Type" do
5
- app(:header_matchers) do |r|
6
- r.on :accept=>"application/xml" do
7
- response["Content-Type"]
8
- end
9
- end
10
-
11
- body("HTTP_ACCEPT" => "application/xml").must_equal "application/xml"
12
- status.must_equal 404
13
- end
14
- end
15
-
16
- describe "header matcher" do
17
- it "should match if header present" do
18
- app(:header_matchers) do |r|
19
- r.on :header=>"accept" do
20
- "bar"
21
- end
22
- end
23
-
24
- body("HTTP_ACCEPT" => "application/xml").must_equal "bar"
25
- status("HTTP_HTTP_ACCEPT" => "application/xml").must_equal 404
26
- status.must_equal 404
27
- end
28
-
29
- it "should yield the header value" do
30
- app(:header_matchers) do |r|
31
- r.on :header=>"accept" do |v|
32
- "bar-#{v}"
33
- end
34
- end
35
-
36
- app.opts[:header_matcher_prefix] = true
37
- body("HTTP_ACCEPT" => "application/xml").must_equal "bar-application/xml"
38
- status.must_equal 404
39
- end
40
- end
41
-
42
- describe "host matcher" do
43
- it "should match a host" do
44
- app(:header_matchers) do |r|
45
- r.on :host=>"example.com" do
46
- "worked"
47
- end
48
- end
49
-
50
- body("HTTP_HOST" => "example.com").must_equal 'worked'
51
- status("HTTP_HOST" => "foo.com").must_equal 404
52
- end
53
-
54
- it "should match a host with a regexp" do
55
- app(:header_matchers) do |r|
56
- r.on :host=>/example/ do
57
- "worked"
58
- end
59
- end
60
-
61
- body("HTTP_HOST" => "example.com").must_equal 'worked'
62
- status("HTTP_HOST" => "foo.com").must_equal 404
63
- end
64
-
65
- it "doesn't yield host if given a string" do
66
- app(:header_matchers) do |r|
67
- r.on :host=>"example.com" do |*args|
68
- args.size.to_s
69
- end
70
- end
71
-
72
- body("HTTP_HOST" => "example.com").must_equal '0'
73
- end
74
-
75
- it "yields host if passed a regexp and opts[:host_matcher_captures] is set" do
76
- app(:header_matchers) do |r|
77
- r.on :host=>/\A(.*)\.example\.com\z/ do |*m|
78
- m.empty? ? '0' : m[0]
79
- end
80
- end
81
-
82
- body("HTTP_HOST" => "foo.example.com").must_equal 'foo'
83
- end
84
- end
85
-
86
- describe "user_agent matcher" do
87
- it "should accept pattern and match against user-agent" do
88
- app(:header_matchers) do |r|
89
- r.on :user_agent=>/(chrome)(\d+)/ do |agent, num|
90
- "a-#{agent}-#{num}"
91
- end
92
- end
93
-
94
- body("HTTP_USER_AGENT" => "chrome31").must_equal "a-chrome-31"
95
- status.must_equal 404
96
- end
97
- end
98
-
@@ -1,74 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "heartbeat plugin" do
4
- it "should return heartbeat response for heartbeat paths only" do
5
- app(:bare) do
6
- plugin :heartbeat
7
- route do |r|
8
- r.on 'a' do
9
- "a"
10
- end
11
- end
12
- end
13
-
14
- body('/a').must_equal 'a'
15
- status.must_equal 404
16
- status('/heartbeat').must_equal 200
17
- body('/heartbeat').must_equal 'OK'
18
- end
19
-
20
- it "should support custom heartbeat paths" do
21
- app(:bare) do
22
- plugin :heartbeat, :path=>'/heartbeat2'
23
- route do |r|
24
- r.on 'a' do
25
- "a"
26
- end
27
- end
28
- end
29
-
30
- body('/a').must_equal 'a'
31
- status.must_equal 404
32
- status('/heartbeat').must_equal 404
33
- status('/heartbeat2').must_equal 200
34
- body('/heartbeat2').must_equal 'OK'
35
- end
36
-
37
- it "should work when using sessions" do
38
- app(:bare) do
39
- send(*DEFAULT_SESSION_ARGS)
40
- plugin :heartbeat
41
-
42
- route do |r|
43
- session.clear
44
- r.on "a" do
45
- "a"
46
- end
47
- end
48
- end
49
-
50
- body('/a').must_equal 'a'
51
- status.must_equal 404
52
- status('/heartbeat').must_equal 200
53
- body('/heartbeat').must_equal 'OK'
54
- end
55
-
56
- it "should work when redirecting" do
57
- app(:bare) do
58
- plugin :heartbeat
59
-
60
- route do |r|
61
- r.on "a" do
62
- "a"
63
- end
64
- r.redirect '/a'
65
- end
66
- end
67
-
68
- body('/a').must_equal 'a'
69
- status.must_equal 302
70
- status('/heartbeat').must_equal 200
71
- body('/heartbeat').must_equal 'OK'
72
- end
73
- end
74
-
@@ -1,152 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "hooks plugin" do
4
- before do
5
- a = @a = []
6
- app(:bare) do
7
- plugin :hooks
8
-
9
- before do
10
- response['foo'] = 'bar'
11
- end
12
-
13
- after do |r|
14
- if r
15
- a << [r[0], r[1]['foo'], r[2]]
16
- r[0] += 1
17
- else
18
- a << r
19
- end
20
- end
21
-
22
- route do |r|
23
- f = response['foo']
24
- response['foo'] = 'baz'
25
- f
26
- end
27
- end
28
- end
29
-
30
- it "adds before and after hooks for running code before and after requests" do
31
- s, h, b = req
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
- end
37
-
38
- it "multiple plugin calls do not override existing hooks" do
39
- app.plugin :hooks
40
- s, h, b = req
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
- end
46
-
47
- it "works when freezing the app" do
48
- app.freeze
49
- s, h, b = req
50
- s.must_equal 201
51
- h['foo'].must_equal 'baz'
52
- b.join.must_equal 'bar'
53
- @a.must_equal [[200, 'baz', ['bar']]]
54
- end
55
-
56
- it "after hooks are still called if an exception is raised" do
57
- a = @a
58
- @app.before do
59
- raise Roda::RodaError, "foo"
60
- end
61
-
62
- @app.after do |r|
63
- a << r
64
- a << $!
65
- end
66
-
67
- proc{req}.must_raise(Roda::RodaError)
68
- a.pop.must_be_kind_of(Roda::RodaError)
69
- a.pop.must_be_nil
70
- end
71
-
72
- it "handles multiple before and after blocks correctly" do
73
- a = @a
74
- @app.before do
75
- response['bar'] = "foo#{response['foo']}"
76
- end
77
-
78
- @app.after do |r|
79
- a << r[1]['bar']
80
- r[0] *= 2
81
- end
82
-
83
- s, h, b = req
84
- s.must_equal 402
85
- h['foo'].must_equal 'baz'
86
- h['bar'].must_equal 'foo'
87
- b.join.must_equal 'bar'
88
- a.must_equal [[200, 'baz', ['bar']], 'foo']
89
- end
90
-
91
- it "copies before and after blocks when subclassing" do
92
- @app = Class.new(@app)
93
- @app.route do |r|
94
- r.on do
95
- "foo"
96
- end
97
- end
98
- s, h, b = req
99
- s.must_equal 201
100
- h['foo'].must_equal 'bar'
101
- b.join.must_equal 'foo'
102
- @a.must_equal [[200, 'bar', ['foo']]]
103
- end
104
-
105
- it "handles halt in before blocks" do
106
- app.before do
107
- response.status = 200
108
- request.halt
109
- end
110
- status.must_equal 201
111
- end
112
-
113
- it "works with error plugin when loaded first" do
114
- app.plugin(:error_handler){|e| "error"}
115
- app.before do
116
- raise "before" if @_request.path == '/b'
117
- end
118
- app.after do
119
- raise "after" if @_request.path == '/a'
120
- end
121
- body('/a').must_equal "error"
122
- body('/b').must_equal "error"
123
- end
124
-
125
- it "works with error plugin when loaded after" do
126
- app(:bare) do
127
- plugin(:error_handler){|e| "error"}
128
- plugin :hooks
129
- before do
130
- raise "before" if @_request.path == '/b'
131
- end
132
- after do
133
- raise "after" if @_request.path == '/a'
134
- end
135
- route{}
136
- end
137
- body('/a').must_equal "error"
138
- body('/b').must_equal "error"
139
- end
140
-
141
- deprecated "should work if #call is overridden" do
142
- app.class_eval do
143
- def call; super end
144
- end
145
- app.route(&app.route_block)
146
- s, h, b = req
147
- s.must_equal 201
148
- h['foo'].must_equal 'baz'
149
- b.join.must_equal 'bar'
150
- @a.must_equal [[200, 'baz', ['bar']]]
151
- end
152
- end
@@ -1,14 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "indifferent_params plugin" do
4
- it "allows indifferent access to request params via params method" do
5
- app(:indifferent_params) do |r|
6
- r.on do
7
- "#{params[:a]}/#{params[:b][0][:c]}"
8
- end
9
- end
10
-
11
- body('QUERY_STRING'=>'a=2&b[][c]=3', 'rack.input'=>StringIO.new).must_equal '2/3'
12
- body('REQUEST_METHOD'=>'POST', 'rack.input'=>StringIO.new('a=2&b[][c]=3')).must_equal '2/3'
13
- end
14
- end
@@ -1,141 +0,0 @@
1
- require_relative "../spec_helper"
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 "parses incoming json if content type specifies json and body is already read" do
19
- @app.route do |r|
20
- r.body.read
21
- r.params['a']['b'].to_s
22
- end
23
- body('rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
24
- end
25
-
26
- it "returns 400 for invalid json" do
27
- req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [400, {}, []]
28
- end
29
-
30
- it "returns 400 for invalid json when using params_capturing plugin" do
31
- @app.plugin :params_capturing
32
- req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [400, {}, []]
33
- end
34
-
35
- it "raises by default if r.params is called and a non-hash is submitted" do
36
- proc do
37
- req('rack.input'=>StringIO.new('[1]'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST')
38
- end.must_raise
39
- end
40
- end
41
-
42
- describe "json_parser plugin" do
43
- it "handles empty request bodies" do
44
- app(:json_parser) do |r|
45
- r.params.length.to_s
46
- end
47
- body('rack.input'=>StringIO.new(''), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '0'
48
- end
49
-
50
- it "handles arrays and other non-hash values using r.POST" do
51
- app(:json_parser) do |r|
52
- r.POST.inspect
53
- end
54
- body('rack.input'=>StringIO.new('[ 1 ]'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '[1]'
55
- end
56
-
57
- it "supports :wrap=>:always option" do
58
- app(:bare) do
59
- plugin(:json_parser, :wrap=>:always)
60
- route do |r|
61
- r.post 'a' do r.params['_json']['a']['b'].to_s end
62
- r.params['_json'][1].to_s
63
- end
64
- end
65
- body('/a', 'rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
66
- body('rack.input'=>StringIO.new('[true, 2]'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '2'
67
- end
68
-
69
- it "supports :wrap=>:unless_hash option" do
70
- app(:bare) do
71
- plugin(:json_parser, :wrap=>:unless_hash)
72
- route do |r|
73
- r.post 'a' do r.params['a']['b'].to_s end
74
- r.params['_json'][1].to_s
75
- end
76
- end
77
- body('/a', 'rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
78
- body('rack.input'=>StringIO.new('[true, 2]'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '2'
79
- end
80
-
81
- it "raises for unsupported :wrap option" do
82
- proc do
83
- app(:bare) do
84
- plugin(:json_parser, :wrap=>:foo)
85
- end
86
- end.must_raise Roda::RodaError
87
- end
88
-
89
- it "supports :error_handler option" do
90
- app(:bare) do
91
- plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
92
- route do |r|
93
- r.params['a']['b'].to_s
94
- end
95
- end
96
- req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [401, {}, ['bad']]
97
- end
98
-
99
- it "works with bare POST" do
100
- app(:bare) do
101
- plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
102
- route do |r|
103
- (r.POST['a']['b'] + r.POST['a']['c']).to_s
104
- end
105
- end
106
- body('rack.input'=>StringIO.new('{"a":{"b":1,"c":2}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '3'
107
- end
108
-
109
- it "supports :parser option" do
110
- app(:bare) do
111
- plugin(:json_parser, :parser=>method(:eval))
112
- route do |r|
113
- r.params['a']['b'].to_s
114
- end
115
- end
116
- body('rack.input'=>StringIO.new("{'a'=>{'b'=>1}}"), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
117
- end
118
-
119
- it "supports :include_request option" do
120
- app(:bare) do
121
- plugin(:json_parser,
122
- :include_request => true,
123
- :parser => lambda{|s,r| {'a'=>s, 'b'=>r.path_info}})
124
- route do |r|
125
- "#{r.params['a']}:#{r.params['b']}"
126
- end
127
- end
128
- body('rack.input'=>StringIO.new('{}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '{}:/'
129
- end
130
-
131
- it "supports resetting :include_request option to false" do
132
- app(:bare) do
133
- plugin :json_parser, :include_request => true
134
- plugin :json_parser, :include_request => false
135
- route do |r|
136
- r.params['a']['b'].to_s
137
- end
138
- end
139
- body('rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
140
- end
141
- end