roda 3.28.0 → 3.33.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 (208) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +40 -0
  3. data/README.rdoc +15 -1
  4. data/doc/conventions.rdoc +17 -8
  5. data/doc/release_notes/3.29.0.txt +15 -0
  6. data/doc/release_notes/3.30.0.txt +14 -0
  7. data/doc/release_notes/3.31.0.txt +11 -0
  8. data/doc/release_notes/3.32.0.txt +42 -0
  9. data/doc/release_notes/3.33.0.txt +8 -0
  10. data/lib/roda.rb +3 -0
  11. data/lib/roda/plugins/_symbol_regexp_matchers.rb +2 -0
  12. data/lib/roda/plugins/assets.rb +26 -5
  13. data/lib/roda/plugins/caching.rb +2 -0
  14. data/lib/roda/plugins/common_logger.rb +1 -1
  15. data/lib/roda/plugins/content_security_policy.rb +2 -0
  16. data/lib/roda/plugins/default_headers.rb +2 -0
  17. data/lib/roda/plugins/exception_page.rb +9 -5
  18. data/lib/roda/plugins/hash_matcher.rb +1 -1
  19. data/lib/roda/plugins/header_matchers.rb +5 -1
  20. data/lib/roda/plugins/indifferent_params.rb +4 -0
  21. data/lib/roda/plugins/partials.rb +33 -6
  22. data/lib/roda/plugins/path.rb +42 -15
  23. data/lib/roda/plugins/placeholder_string_matchers.rb +2 -0
  24. data/lib/roda/plugins/public.rb +25 -17
  25. data/lib/roda/plugins/relative_path.rb +73 -0
  26. data/lib/roda/plugins/render.rb +17 -5
  27. data/lib/roda/plugins/render_each.rb +11 -3
  28. data/lib/roda/plugins/run_append_slash.rb +1 -1
  29. data/lib/roda/plugins/symbol_matchers.rb +2 -2
  30. data/lib/roda/version.rb +1 -1
  31. metadata +13 -214
  32. data/Rakefile +0 -108
  33. data/doc/release_notes/1.0.0.txt +0 -329
  34. data/doc/release_notes/1.1.0.txt +0 -226
  35. data/doc/release_notes/1.2.0.txt +0 -406
  36. data/doc/release_notes/1.3.0.txt +0 -109
  37. data/doc/release_notes/2.0.0.txt +0 -75
  38. data/doc/release_notes/2.1.0.txt +0 -124
  39. data/doc/release_notes/2.10.0.txt +0 -27
  40. data/doc/release_notes/2.11.0.txt +0 -70
  41. data/doc/release_notes/2.12.0.txt +0 -40
  42. data/doc/release_notes/2.13.0.txt +0 -10
  43. data/doc/release_notes/2.14.0.txt +0 -44
  44. data/doc/release_notes/2.15.0.txt +0 -53
  45. data/doc/release_notes/2.16.0.txt +0 -48
  46. data/doc/release_notes/2.17.0.txt +0 -62
  47. data/doc/release_notes/2.18.0.txt +0 -69
  48. data/doc/release_notes/2.19.0.txt +0 -30
  49. data/doc/release_notes/2.2.0.txt +0 -97
  50. data/doc/release_notes/2.20.0.txt +0 -5
  51. data/doc/release_notes/2.21.0.txt +0 -17
  52. data/doc/release_notes/2.22.0.txt +0 -41
  53. data/doc/release_notes/2.23.0.txt +0 -29
  54. data/doc/release_notes/2.24.0.txt +0 -65
  55. data/doc/release_notes/2.25.0.txt +0 -14
  56. data/doc/release_notes/2.26.0.txt +0 -13
  57. data/doc/release_notes/2.27.0.txt +0 -56
  58. data/doc/release_notes/2.28.0.txt +0 -17
  59. data/doc/release_notes/2.29.0.txt +0 -156
  60. data/doc/release_notes/2.3.0.txt +0 -109
  61. data/doc/release_notes/2.4.0.txt +0 -55
  62. data/doc/release_notes/2.5.0.txt +0 -23
  63. data/doc/release_notes/2.5.1.txt +0 -4
  64. data/doc/release_notes/2.6.0.txt +0 -21
  65. data/doc/release_notes/2.7.0.txt +0 -75
  66. data/doc/release_notes/2.8.0.txt +0 -44
  67. data/doc/release_notes/2.9.0.txt +0 -6
  68. data/spec/all.rb +0 -1
  69. data/spec/assets/css/app.scss +0 -1
  70. data/spec/assets/css/no_access.css +0 -1
  71. data/spec/assets/css/raw.css +0 -1
  72. data/spec/assets/js/head/app.js +0 -1
  73. data/spec/composition_spec.rb +0 -31
  74. data/spec/define_roda_method_spec.rb +0 -274
  75. data/spec/env_spec.rb +0 -11
  76. data/spec/freeze_spec.rb +0 -37
  77. data/spec/integration_spec.rb +0 -209
  78. data/spec/matchers_spec.rb +0 -832
  79. data/spec/opts_spec.rb +0 -42
  80. data/spec/plugin/_after_hook_spec.rb +0 -19
  81. data/spec/plugin/all_verbs_spec.rb +0 -29
  82. data/spec/plugin/assets_preloading_spec.rb +0 -98
  83. data/spec/plugin/assets_spec.rb +0 -745
  84. data/spec/plugin/backtracking_array_spec.rb +0 -42
  85. data/spec/plugin/branch_locals_spec.rb +0 -106
  86. data/spec/plugin/caching_spec.rb +0 -337
  87. data/spec/plugin/chunked_spec.rb +0 -201
  88. data/spec/plugin/class_level_routing_spec.rb +0 -164
  89. data/spec/plugin/class_matchers_spec.rb +0 -40
  90. data/spec/plugin/common_logger_spec.rb +0 -85
  91. data/spec/plugin/content_for_spec.rb +0 -162
  92. data/spec/plugin/content_security_policy_spec.rb +0 -175
  93. data/spec/plugin/cookies_spec.rb +0 -51
  94. data/spec/plugin/csrf_spec.rb +0 -111
  95. data/spec/plugin/default_headers_spec.rb +0 -82
  96. data/spec/plugin/default_status_spec.rb +0 -95
  97. data/spec/plugin/delay_build_spec.rb +0 -23
  98. data/spec/plugin/delegate_spec.rb +0 -23
  99. data/spec/plugin/delete_empty_headers_spec.rb +0 -27
  100. data/spec/plugin/direct_call_spec.rb +0 -28
  101. data/spec/plugin/disallow_file_uploads_spec.rb +0 -25
  102. data/spec/plugin/drop_body_spec.rb +0 -24
  103. data/spec/plugin/early_hints_spec.rb +0 -19
  104. data/spec/plugin/empty_root_spec.rb +0 -14
  105. data/spec/plugin/environments_spec.rb +0 -42
  106. data/spec/plugin/error_email_spec.rb +0 -97
  107. data/spec/plugin/error_handler_spec.rb +0 -216
  108. data/spec/plugin/error_mail_spec.rb +0 -93
  109. data/spec/plugin/exception_page_spec.rb +0 -168
  110. data/spec/plugin/flash_spec.rb +0 -121
  111. data/spec/plugin/h_spec.rb +0 -11
  112. data/spec/plugin/halt_spec.rb +0 -119
  113. data/spec/plugin/hash_matcher_spec.rb +0 -27
  114. data/spec/plugin/hash_routes_spec.rb +0 -535
  115. data/spec/plugin/head_spec.rb +0 -52
  116. data/spec/plugin/header_matchers_spec.rb +0 -98
  117. data/spec/plugin/heartbeat_spec.rb +0 -74
  118. data/spec/plugin/hooks_spec.rb +0 -152
  119. data/spec/plugin/indifferent_params_spec.rb +0 -14
  120. data/spec/plugin/json_parser_spec.rb +0 -141
  121. data/spec/plugin/json_spec.rb +0 -83
  122. data/spec/plugin/mail_processor_spec.rb +0 -451
  123. data/spec/plugin/mailer_spec.rb +0 -282
  124. data/spec/plugin/match_affix_spec.rb +0 -43
  125. data/spec/plugin/match_hook_spec.rb +0 -79
  126. data/spec/plugin/middleware_spec.rb +0 -237
  127. data/spec/plugin/middleware_stack_spec.rb +0 -81
  128. data/spec/plugin/module_include_spec.rb +0 -48
  129. data/spec/plugin/multi_route_spec.rb +0 -268
  130. data/spec/plugin/multi_run_spec.rb +0 -87
  131. data/spec/plugin/multi_view_spec.rb +0 -50
  132. data/spec/plugin/multibyte_string_matcher_spec.rb +0 -44
  133. data/spec/plugin/named_templates_spec.rb +0 -96
  134. data/spec/plugin/not_allowed_spec.rb +0 -69
  135. data/spec/plugin/not_found_spec.rb +0 -128
  136. data/spec/plugin/optimized_string_matchers_spec.rb +0 -43
  137. data/spec/plugin/padrino_render_spec.rb +0 -34
  138. data/spec/plugin/param_matchers_spec.rb +0 -69
  139. data/spec/plugin/params_capturing_spec.rb +0 -33
  140. data/spec/plugin/partials_spec.rb +0 -43
  141. data/spec/plugin/pass_spec.rb +0 -29
  142. data/spec/plugin/path_matchers_spec.rb +0 -42
  143. data/spec/plugin/path_rewriter_spec.rb +0 -45
  144. data/spec/plugin/path_spec.rb +0 -222
  145. data/spec/plugin/placeholder_string_matchers_spec.rb +0 -126
  146. data/spec/plugin/precompile_templates_spec.rb +0 -61
  147. data/spec/plugin/public_spec.rb +0 -85
  148. data/spec/plugin/render_each_spec.rb +0 -82
  149. data/spec/plugin/render_locals_spec.rb +0 -114
  150. data/spec/plugin/render_spec.rb +0 -912
  151. data/spec/plugin/request_aref_spec.rb +0 -51
  152. data/spec/plugin/request_headers_spec.rb +0 -39
  153. data/spec/plugin/response_request_spec.rb +0 -43
  154. data/spec/plugin/route_block_args_spec.rb +0 -86
  155. data/spec/plugin/route_csrf_spec.rb +0 -305
  156. data/spec/plugin/run_append_slash_spec.rb +0 -77
  157. data/spec/plugin/run_handler_spec.rb +0 -53
  158. data/spec/plugin/sessions_spec.rb +0 -452
  159. data/spec/plugin/shared_vars_spec.rb +0 -45
  160. data/spec/plugin/sinatra_helpers_spec.rb +0 -537
  161. data/spec/plugin/slash_path_empty_spec.rb +0 -22
  162. data/spec/plugin/static_routing_spec.rb +0 -192
  163. data/spec/plugin/static_spec.rb +0 -30
  164. data/spec/plugin/status_303_spec.rb +0 -28
  165. data/spec/plugin/status_handler_spec.rb +0 -158
  166. data/spec/plugin/streaming_spec.rb +0 -246
  167. data/spec/plugin/strip_path_prefix_spec.rb +0 -24
  168. data/spec/plugin/symbol_matchers_spec.rb +0 -51
  169. data/spec/plugin/symbol_status_spec.rb +0 -25
  170. data/spec/plugin/symbol_views_spec.rb +0 -32
  171. data/spec/plugin/timestamp_public_spec.rb +0 -85
  172. data/spec/plugin/type_routing_spec.rb +0 -348
  173. data/spec/plugin/typecast_params_spec.rb +0 -1370
  174. data/spec/plugin/unescape_path_spec.rb +0 -22
  175. data/spec/plugin/view_options_spec.rb +0 -170
  176. data/spec/plugin_spec.rb +0 -71
  177. data/spec/redirect_spec.rb +0 -41
  178. data/spec/request_spec.rb +0 -97
  179. data/spec/response_spec.rb +0 -199
  180. data/spec/route_spec.rb +0 -39
  181. data/spec/session_middleware_spec.rb +0 -129
  182. data/spec/session_spec.rb +0 -37
  183. data/spec/spec_helper.rb +0 -137
  184. data/spec/version_spec.rb +0 -14
  185. data/spec/views/_test.erb +0 -1
  186. data/spec/views/a.erb +0 -1
  187. data/spec/views/a.rdoc +0 -2
  188. data/spec/views/about.erb +0 -1
  189. data/spec/views/about.str +0 -1
  190. data/spec/views/about/_test.css.gz +0 -0
  191. data/spec/views/about/_test.erb +0 -1
  192. data/spec/views/about/_test.erb.gz +0 -0
  193. data/spec/views/about/comp_test.erb +0 -1
  194. data/spec/views/b.erb +0 -1
  195. data/spec/views/c.erb +0 -1
  196. data/spec/views/comp_layout.erb +0 -1
  197. data/spec/views/comp_test.erb +0 -1
  198. data/spec/views/content-yield.erb +0 -1
  199. data/spec/views/each.str +0 -1
  200. data/spec/views/home.erb +0 -2
  201. data/spec/views/home.str +0 -2
  202. data/spec/views/iv.erb +0 -1
  203. data/spec/views/layout-alternative.erb +0 -2
  204. data/spec/views/layout-yield.erb +0 -3
  205. data/spec/views/layout.erb +0 -2
  206. data/spec/views/layout.str +0 -2
  207. data/spec/views/multiple-layout.erb +0 -1
  208. data/spec/views/multiple.erb +0 -1
@@ -1,55 +0,0 @@
1
- = New Plugins
2
-
3
- * A websocket plugin has been added, for websocket support using
4
- faye-websocket. Here's an example of a simple echo service using
5
- websockets:
6
-
7
- plugin :websockets
8
-
9
- route do |r|
10
- r.get "echo" do
11
- r.websocket do |ws|
12
- # Routing block taken for a websocket request to /echo
13
-
14
- # ws is a Faye::WebSocket instance, so you can use the
15
- # Faye::WebSocket API
16
- ws.on(:message) do |event|
17
- ws.send(event.data)
18
- end
19
- end
20
-
21
- # View rendered if a regular GET request to /echo
22
- view "echo"
23
- end
24
- end
25
-
26
- * A status_handler plugin has been added, which allows Roda to
27
- specially handle arbitrary status codes. Usage is similar to the
28
- not_found plugin (which now uses status_handler internally):
29
-
30
- plugin :status_handler
31
-
32
- status_handler 403 do
33
- "You are forbidden from seeing that!"
34
- end
35
- status_handler 404 do
36
- "Where did it go?"
37
- end
38
-
39
- = Other New Features
40
-
41
- * The assets plugin now supports a :gzip option, which will save
42
- gzipped versions when compiling assets. When serving compiled
43
- assets, if the request accepts gzip encoding, it will serve
44
- the gzipped version. This also plays nicely with nginx's
45
- gzip_static support.
46
-
47
- * The assets plugin now supports Google Closure Compiler, Uglifier,
48
- and MinJS for minifying javascript. You can now specify which
49
- css and js compressors to use via the :css_compressor and
50
- :js_compressor options.
51
-
52
- = Backwards Compatibility
53
-
54
- * Roda.plugin now always returns nil. Previously the return value
55
- could be non-nil if the plugin used a configure method.
@@ -1,23 +0,0 @@
1
- = New Features
2
-
3
- * The assets plugin now supports a :compiled_asset_host option, which
4
- specifies a hostname used to serve compiled assets.
5
-
6
- * The render plugin now supports a :cache_class option, which
7
- specificies a class to use for the thread-safe template cache.
8
- This can be used to setup LRU caching or caching that checks
9
- modify times on the underlying template files.
10
-
11
- * r.multi_run in the multi_run plugin now accepts a block, and calls
12
- the block before dispatching to the related rack application. This
13
- can be used to modify the environment before dispatching. Example:
14
-
15
- r.multi_run do |prefix|
16
- env['authenticated'] = true
17
- end
18
-
19
- = Backwards Compatibility
20
-
21
- * The :by_name option to the path plugin now defaults to true in
22
- development mode. This should only negatively affect applications
23
- that register anonymous classes with the path plugin.
@@ -1,4 +0,0 @@
1
- = Improvements
2
-
3
- * The multi_route plugin now works correctly if the middleware plugin
4
- is loaded after it.
@@ -1,21 +0,0 @@
1
- = New Features
2
-
3
- * :params and :params! matchers have been added to the param_matchers
4
- plugin, allowing you to match multiple params at the same time:
5
-
6
- r.on :params=>%w'foo bar' do |foo, bar| end
7
- # instead of
8
- r.on({:param=>'foo'}, :param=>'bar') do |foo, bar| end
9
-
10
- = Other Improvements
11
-
12
- * When loading the csrf plugin multiple times, instead of loading the
13
- middleware multiple times with different settings, merge options
14
- in later plugin calls into a single middleware option hash, and
15
- only load the middleware once.
16
-
17
- This allows plugins to depend on the csrf plugin, while also
18
- allowing the application to use the csrf plugin with options.
19
-
20
- * request.halt now works correctly when used inside a before hook when
21
- using the hooks plugin.
@@ -1,75 +0,0 @@
1
- = New Features
2
-
3
- * A default_status plugin has been added for changing the default
4
- status for responses. Previously, the default status was hard
5
- coded to 200, this plugin allows you to change it. The plugin
6
- takes a block which is instance_evaled in the context of the
7
- response:
8
-
9
- plugin :default_status do
10
- headers['Content-Type'] == 'foo' ? 201 : 200
11
- end
12
-
13
- Note that the default status for empty responses (used when no
14
- route handles the response) is still 404, this just changes the
15
- default for non-empty responses.
16
-
17
- * A response_request plugin has been added for giving the response
18
- instance access to the related request. This can be useful in
19
- conjunction with the default_status plugin, if you want the
20
- default status of the response to depend on the request, such as
21
- using a different status for different request methods:
22
-
23
- plugin :response_request
24
- plugin :default_status do
25
- request.post? ? 201 : 200
26
- end
27
-
28
- * A run_handler plugin has been added, for modifying rack response
29
- arrays before returning them when using r.run. Additionally, it
30
- allows for continuing with routing if the response returned by
31
- r.run is a 404 response, using the :not_found=>:pass option:
32
-
33
- plugin :run_handler
34
- route do |r|
35
- # Keep running code if RackAppFoo returns a 404 response
36
- r.run RackAppFoo, :not_found=>:pass
37
-
38
- # Change response status codes before returning.
39
- r.run(RackAppBar) do |response|
40
- response[0] = 200 if response[0] == 201
41
- end
42
- end
43
-
44
- * Roda.rewite_path in the path_rewriter extension now accepts a block
45
- to allow for dynamic replacements. The block is yielded a MatchData
46
- instance:
47
-
48
- rewrite_path(/\A\/a/(\w+)/){|match| match[1].capitalize}
49
- # PATH_INFO '/a/moo' => remaining_path '/a/Moo'
50
-
51
- rewrite_path(/\A\/a/(\w+)/, :path_info => true) do |match|
52
- match[1].capitalize
53
- end
54
- # PATH_INFO '/a/moo' => PATH_INFO '/a/Moo'
55
-
56
- * The :host matcher in the header_matchers plugin will now yield the
57
- regexp captures to the block if given a regexp when the
58
- :host_matcher_captures application option is set. This behavior
59
- will become the default behavior in Roda 3. This will allow for
60
- code like:
61
-
62
- opts[:host_matcher_captures] = true
63
- route do |r|
64
- r.on :host=>/\A(\w+).example.com\z/ do |subdomain|
65
- # ...
66
- end
67
- end
68
-
69
- = Other Improvements
70
-
71
- * RodaCache now uses a mutex to synchronize access on MRI.
72
- Previously, it relied on the global interpreter lock, but testing
73
- has shown that is not reliable in all cases. RodaCache has always
74
- used a mutex for synchronization on other ruby implementations,
75
- this just extends that code to MRI as well.
@@ -1,44 +0,0 @@
1
- = New Features
2
-
3
- * A multi_view plugin has been added, for easily setting up routing
4
- for rendering multiple views:
5
-
6
- plugin :multi_view
7
-
8
- route do |r|
9
- r.multi_view(['foo', 'bar', 'baz'])
10
- end
11
-
12
- # or:
13
-
14
- route do |r|
15
- r.multi_view(/(foo|bar|baz)/)
16
- end
17
-
18
- # or:
19
-
20
- regexp = multi_view_compile(['foo', 'bar', 'baz'])
21
- route do |r|
22
- r.multi_view(regexp)
23
- end
24
-
25
- # all are equivalent to:
26
-
27
- route do |r|
28
- r.get 'foo' do
29
- view('foo')
30
- end
31
-
32
- r.get 'bar' do
33
- view('bar')
34
- end
35
-
36
- r.get 'baz' do
37
- view('baz')
38
- end
39
- end
40
-
41
- = Other Improvements
42
-
43
- * The content_for plugin now supports haml templates. Previous only
44
- erb templates were supported.
@@ -1,6 +0,0 @@
1
- = New Features
2
-
3
- * The content_for plugin now supports passing the content as a
4
- string argument instead of a block:
5
-
6
- <% content_for :foo, "Some content" %>
@@ -1 +0,0 @@
1
- (Dir['./spec/*_spec.rb'] + Dir['./spec/plugin/*_spec.rb']).each{|f| require f}
@@ -1 +0,0 @@
1
- body { color: red; }
@@ -1 +0,0 @@
1
- no access
@@ -1 +0,0 @@
1
- body { color: blue; }
@@ -1 +0,0 @@
1
- console.log('test')
@@ -1,31 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "r.run" do
4
- it "should allow composition of apps" do
5
- a = app do |r|
6
- r.on "services", :id do |id|
7
- "View #{id}"
8
- end
9
- end
10
-
11
- app(:new) do |r|
12
- r.on "provider" do
13
- r.run a
14
- end
15
- end
16
-
17
- body("/provider/services/101").must_equal 'View 101'
18
- end
19
-
20
- it "modifies SCRIPT_NAME/PATH_INFO when calling run" do
21
- a = app{|r| "#{r.script_name}|#{r.path_info}"}
22
- app{|r| r.on("a"){r.run a}}
23
- body("/a/b").must_equal "/a|/b"
24
- end
25
-
26
- it "restores SCRIPT_NAME/PATH_INFO before returning from run" do
27
- a = app{|r| "#{r.script_name}|#{r.path_info}"}
28
- app{|r| s = catch(:halt){r.on("a"){r.run a}}; "#{s[2].join}%#{r.script_name}|#{r.path_info}"}
29
- body("/a/b").must_equal "/a|/b%|/a/b"
30
- end
31
- end
@@ -1,274 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Roda.define_roda_method" do
4
- before do
5
- @scope = app.new({'PATH_INFO'=>'/'})
6
- end
7
-
8
- it "should define methods using block" do
9
- m0 = app.define_roda_method("x", 0){1}
10
- m0.must_be_kind_of Symbol
11
- m0.must_match(/\A_roda_x_\d+\z/)
12
- @scope.send(m0).must_equal 1
13
-
14
- m1 = app.define_roda_method("x", 1){|x| [x, 2]}
15
- m1.must_be_kind_of Symbol
16
- m1.must_match(/\A_roda_x_\d+\z/)
17
- @scope.send(m1, 3).must_equal [3, 2]
18
- end
19
-
20
- it "should define private methods" do
21
- proc{@scope.public_send(app.define_roda_method("x", 0){1})}.must_raise NoMethodError
22
- end
23
-
24
- it "should accept symbols as method name and return the same symbol" do
25
- m0 = app.define_roda_method(:_roda_foo, 0){1}
26
- m0.must_equal :_roda_foo
27
- @scope.send(m0).must_equal 1
28
- end
29
-
30
- it "should handle optional arguments and splats for expected_arity 0" do
31
- m2 = app.define_roda_method("x", 0){|*x| [x, 3]}
32
- @scope.send(m2).must_equal [[], 3]
33
-
34
- m3 = app.define_roda_method("x", 0){|x=5| [x, 4]}
35
- @scope.send(m3).must_equal [5, 4]
36
-
37
- m4 = app.define_roda_method("x", 0){|x=6, *y| [x, y, 5]}
38
- @scope.send(m4).must_equal [6, [], 5]
39
- end
40
-
41
- it "should should optional arguments and splats for expected_arity 1" do
42
- m2 = app.define_roda_method("x", 1){|y, *x| [y, x, 3]}
43
- @scope.send(m2, :a).must_equal [:a, [], 3]
44
-
45
- m3 = app.define_roda_method("x", 1){|y, x=5| [y, x, 4]}
46
- @scope.send(m3, :b).must_equal [:b, 5, 4]
47
-
48
- m4 = app.define_roda_method("x", 1){|y, x=6, *z| [y, x, z, 5]}
49
- @scope.send(m4, :c).must_equal [:c, 6, [], 5]
50
- end
51
-
52
- it "should handle differences in arity" do
53
- m0 = app.define_roda_method("x", 0){|x| [x, 1]}
54
- @scope.send(m0).must_equal [nil, 1]
55
-
56
- m1 = app.define_roda_method("x", 1){2}
57
- @scope.send(m1, 3).must_equal 2
58
-
59
- m1 = app.define_roda_method("x", 1){|x, y| [x, y]}
60
- @scope.send(m1, 4).must_equal [4, nil]
61
- end
62
-
63
- it "should raise for unexpected expected_arity" do
64
- proc{app.define_roda_method("x", 2){|x|}}.must_raise Roda::RodaError
65
- end
66
-
67
- it "should fail if :check_arity false app option is used and a block with invalid arity is passed" do
68
- app.opts[:check_arity] = false
69
- m0 = app.define_roda_method("x", 0){|x| [x, 1]}
70
- proc{@scope.send(m0)}.must_raise ArgumentError
71
-
72
- m1 = app.define_roda_method("x", 1){2}
73
- proc{@scope.send(m1, 1)}.must_raise ArgumentError
74
- end
75
-
76
- deprecated "should warn if :check_arity :warn app option is used and a block with invalid arity is passed" do
77
- app.opts[:check_arity] = :warn
78
- m0 = app.define_roda_method("x", 0){|x| [x, 1]}
79
- @scope.send(m0).must_equal [nil, 1]
80
-
81
- m1 = app.define_roda_method("x", 1){2}
82
- @scope.send(m1, 3).must_equal 2
83
- end
84
-
85
- [false, true].each do |warn_dynamic_arity|
86
- meth = warn_dynamic_arity ? :deprecated : :it
87
- send meth, "should handle expected_arity :any and do dynamic arity check/fix" do
88
- if warn_dynamic_arity
89
- app.opts[:check_dynamic_arity] = :warn
90
- end
91
-
92
- m0 = app.define_roda_method("x", :any){1}
93
- @scope.send(m0).must_equal 1
94
- @scope.send(m0, 2).must_equal 1
95
-
96
- m1 = app.define_roda_method("x", :any){|x| [x, 1]}
97
- @scope.send(m1).must_equal [nil, 1]
98
- @scope.send(m1, 2).must_equal [2, 1]
99
- @scope.send(m1, 2, 3).must_equal [2, 1]
100
-
101
- m2 = app.define_roda_method("x", :any){|x=5| [x, 2]}
102
- @scope.send(m2).must_equal [5, 2]
103
- @scope.send(m2, 2).must_equal [2, 2]
104
- @scope.send(m2, 2, 3).must_equal [2, 2]
105
-
106
- m3 = app.define_roda_method("x", :any){|y, x=5| [x, y, 3]}
107
- @scope.send(m3).must_equal [5, nil, 3]
108
- @scope.send(m3, 2).must_equal [5, 2, 3]
109
- @scope.send(m3, 2, 3).must_equal [3, 2, 3]
110
- @scope.send(m3, 2, 3, 4).must_equal [3, 2, 3]
111
-
112
- m4 = app.define_roda_method("x", :any){|*z| [z, 1]}
113
- @scope.send(m4).must_equal [[], 1]
114
- @scope.send(m4, 2).must_equal [[2], 1]
115
-
116
- m5 = app.define_roda_method("x", :any){|x, *z| [x, z, 1]}
117
- @scope.send(m5).must_equal [nil, [], 1]
118
- @scope.send(m5, 2).must_equal [2, [], 1]
119
- @scope.send(m5, 2, 3).must_equal [2, [3], 1]
120
-
121
- m6 = app.define_roda_method("x", :any){|x=5, *z| [x, z, 2]}
122
- @scope.send(m6).must_equal [5, [], 2]
123
- @scope.send(m6, 2).must_equal [2, [], 2]
124
- @scope.send(m6, 2, 3).must_equal [2, [3], 2]
125
-
126
- m7 = app.define_roda_method("x", :any){|y, x=5, *z| [x, y, z, 3]}
127
- @scope.send(m7).must_equal [5, nil, [], 3]
128
- @scope.send(m7, 2).must_equal [5, 2, [], 3]
129
- @scope.send(m7, 2, 3).must_equal [3, 2, [], 3]
130
- @scope.send(m7, 2, 3, 4).must_equal [3, 2, [4], 3]
131
- end
132
- end
133
-
134
- it "should not fix dynamic arity issues if :check_dynamic_arity false app option is used" do
135
- app.opts[:check_dynamic_arity] = false
136
-
137
- m0 = app.define_roda_method("x", :any){1}
138
- @scope.send(m0).must_equal 1
139
- proc{@scope.send(m0, 2)}.must_raise ArgumentError
140
-
141
- m1 = app.define_roda_method("x", :any){|x| [x, 1]}
142
- proc{@scope.send(m1)}.must_raise ArgumentError
143
- @scope.send(m1, 2).must_equal [2, 1]
144
- proc{@scope.send(m1, 2, 3)}.must_raise ArgumentError
145
-
146
- m2 = app.define_roda_method("x", :any){|x=5| [x, 2]}
147
- @scope.send(m2).must_equal [5, 2]
148
- @scope.send(m2, 2).must_equal [2, 2]
149
- proc{@scope.send(m2, 2, 3)}.must_raise ArgumentError
150
-
151
- m3 = app.define_roda_method("x", :any){|y, x=5| [x, y, 3]}
152
- proc{@scope.send(m3)}.must_raise ArgumentError
153
- @scope.send(m3, 2).must_equal [5, 2, 3]
154
- @scope.send(m3, 2, 3).must_equal [3, 2, 3]
155
- proc{@scope.send(m3, 2, 3, 4)}.must_raise ArgumentError
156
-
157
- m4 = app.define_roda_method("x", :any){|*z| [z, 1]}
158
- @scope.send(m4).must_equal [[], 1]
159
- @scope.send(m4, 2).must_equal [[2], 1]
160
-
161
- m5 = app.define_roda_method("x", :any){|x, *z| [x, z, 1]}
162
- proc{@scope.send(m5)}.must_raise ArgumentError
163
- @scope.send(m5, 2).must_equal [2, [], 1]
164
- @scope.send(m5, 2, 3).must_equal [2, [3], 1]
165
-
166
- m6 = app.define_roda_method("x", :any){|x=5, *z| [x, z, 2]}
167
- @scope.send(m6).must_equal [5, [], 2]
168
- @scope.send(m6, 2).must_equal [2, [], 2]
169
- @scope.send(m6, 2, 3).must_equal [2, [3], 2]
170
-
171
- m7 = app.define_roda_method("x", :any){|y, x=5, *z| [x, y, z, 3]}
172
- proc{@scope.send(m7)}.must_raise ArgumentError
173
- @scope.send(m7, 2).must_equal [5, 2, [], 3]
174
- @scope.send(m7, 2, 3).must_equal [3, 2, [], 3]
175
- @scope.send(m7, 2, 3, 4).must_equal [3, 2, [4], 3]
176
- end
177
-
178
- if RUBY_VERSION > '2.1'
179
- it "should raise for required keyword arguments for expected_arity 0 or 1" do
180
- proc{eval("app.define_roda_method('x', 0){|b:| [b, 1]}", binding)}.must_raise Roda::RodaError
181
- proc{eval("app.define_roda_method('x', 0){|c=1, b:| [c, b, 1]}", binding)}.must_raise Roda::RodaError
182
- proc{eval("app.define_roda_method('x', 1){|x, b:| [b, 1]}", binding)}.must_raise Roda::RodaError
183
- proc{eval("app.define_roda_method('x', 1){|x, c=1, b:| [c, b, 1]}", binding)}.must_raise Roda::RodaError
184
- end
185
-
186
- it "should ignore keyword arguments for expected_arity 0" do
187
- @scope.send(eval("app.define_roda_method('x', 0){|b:2| [b, 1]}", binding)).must_equal [2, 1]
188
- @scope.send(eval("app.define_roda_method('x', 0){|**b| [b, 1]}", binding)).must_equal [{}, 1]
189
- @scope.send(eval("app.define_roda_method('x', 0){|c=1, b:2| [c, b, 1]}", binding)).must_equal [1, 2, 1]
190
- @scope.send(eval("app.define_roda_method('x', 0){|c=1, **b| [c, b, 1]}", binding)).must_equal [1, {}, 1]
191
- @scope.send(eval("app.define_roda_method('x', 0){|x, b:2| [x, b, 1]}", binding)).must_equal [nil, 2, 1]
192
- @scope.send(eval("app.define_roda_method('x', 0){|x, **b| [x, b, 1]}", binding)).must_equal [nil, {}, 1]
193
- @scope.send(eval("app.define_roda_method('x', 0){|x, c=1, b:2| [x, c, b, 1]}", binding)).must_equal [nil, 1, 2, 1]
194
- @scope.send(eval("app.define_roda_method('x', 0){|x, c=1, **b| [x, c, b, 1]}", binding)).must_equal [nil, 1, {}, 1]
195
- end
196
-
197
- it "should ignore keyword arguments for expected_arity 1" do
198
- @scope.send(eval("app.define_roda_method('x', 1){|b:2| [b, 1]}", binding), 3).must_equal [2, 1]
199
- @scope.send(eval("app.define_roda_method('x', 1){|**b| [b, 1]}", binding), 3).must_equal [{}, 1]
200
- @scope.send(eval("app.define_roda_method('x', 1){|c=1, b:2| [c, b, 1]}", binding), 3).must_equal [3, 2, 1]
201
- @scope.send(eval("app.define_roda_method('x', 1){|c=1, **b| [c, b, 1]}", binding), 3).must_equal [3, {}, 1]
202
- @scope.send(eval("app.define_roda_method('x', 1){|x, b:2| [x, b, 1]}", binding), 3).must_equal [3, 2, 1]
203
- @scope.send(eval("app.define_roda_method('x', 1){|x, **b| [x, b, 1]}", binding), 3).must_equal [3, {}, 1]
204
- @scope.send(eval("app.define_roda_method('x', 1){|x, c=1, b:2| [x, c, b, 1]}", binding), 3).must_equal [3, 1, 2, 1]
205
- @scope.send(eval("app.define_roda_method('x', 1){|x, c=1, **b| [x, c, b, 1]}", binding), 3).must_equal [3, 1, {}, 1]
206
- end
207
-
208
- it "should handle expected_arity :any with keyword arguments" do
209
- if RUBY_VERSION >= '2.7' && RUBY_VERSION < '3'
210
- suppress = proc do |&b|
211
- begin
212
- stderr = $stderr
213
- $stderr = StringIO.new
214
- b.call
215
- ensure
216
- $stderr = stderr
217
- end
218
- end
219
- else
220
- suppress = proc{|&b| b.call}
221
- end
222
-
223
- m = eval('app.define_roda_method("x", :any){|b:2| b}', binding)
224
- @scope.send(m).must_equal 2
225
- @scope.send(m, 4).must_equal 2
226
- @scope.send(m, b: 3).must_equal 3
227
- @scope.send(m, 4, b: 3).must_equal 3
228
-
229
- m = eval('app.define_roda_method("x", :any){|b:| b}', binding)
230
- proc{@scope.send(m)}.must_raise ArgumentError
231
- proc{@scope.send(m, 4)}.must_raise ArgumentError
232
- @scope.send(m, b: 3).must_equal 3
233
- @scope.send(m, 4, b: 3).must_equal 3
234
-
235
- m = eval('app.define_roda_method("x", :any){|**b| b}', binding)
236
- @scope.send(m).must_equal({})
237
- @scope.send(m, 4).must_equal({})
238
- @scope.send(m, b: 3).must_equal(b: 3)
239
- @scope.send(m, 4, b: 3).must_equal(b: 3)
240
-
241
- m = eval('app.define_roda_method("x", :any){|x, b:9| [x, b, 1]}', binding)
242
- suppress.call{@scope.send(m)[1..-1]}.must_equal [9, 1]
243
- @scope.send(m, 2).must_equal [2, 9, 1]
244
- @scope.send(m, 2, 3).must_equal [2, 9, 1]
245
- eval("@scope.send(m, {b: 4}#{', **{}' if RUBY_VERSION > '2'})").must_equal [{b: 4}, 9, 1]
246
- @scope.send(m, 2, b: 4).must_equal [2, 4, 1]
247
- @scope.send(m, 2, 3, b: 4).must_equal [2, 4, 1]
248
-
249
- m = eval('app.define_roda_method("x", :any){|x, b:| [x, b, 1]}', binding)
250
- proc{suppress.call{@scope.send(m)}}.must_raise ArgumentError
251
- proc{@scope.send(m, 2)}.must_raise ArgumentError
252
- proc{@scope.send(m, 2, 3)}.must_raise ArgumentError
253
- proc{eval("@scope.send(m, {b: 4}#{', **{}' if RUBY_VERSION > '2'})")}.must_raise ArgumentError
254
- @scope.send(m, 2, b: 4).must_equal [2, 4, 1]
255
- @scope.send(m, 2, 3, b: 4).must_equal [2, 4, 1]
256
-
257
- m = eval('app.define_roda_method("x", :any){|x, **b| [x, b, 1]}', binding)
258
- suppress.call{@scope.send(m)[1..-1]}.must_equal [{}, 1]
259
- @scope.send(m, 2).must_equal [2, {}, 1]
260
- @scope.send(m, 2, 3).must_equal [2, {}, 1]
261
- eval("@scope.send(m, {b: 4}#{', **{}' if RUBY_VERSION > '2'})").must_equal [{b: 4}, {}, 1]
262
- @scope.send(m, 2, b: 4).must_equal [2, {b: 4}, 1]
263
- @scope.send(m, 2, 3, b: 4).must_equal [2, {b: 4}, 1]
264
-
265
- m = eval('m = app.define_roda_method("x", :any){|x=5, b:9| [x, b, 2]}', binding)
266
- @scope.send(m).must_equal [5, 9, 2]
267
- @scope.send(m, 2).must_equal [2, 9, 2]
268
- @scope.send(m, 2, 3).must_equal [2, 9, 2]
269
- @scope.send(m, b: 4).must_equal [5, 4, 2]
270
- @scope.send(m, 2, b: 4).must_equal [2, 4, 2]
271
- @scope.send(m, 2, 3, b: 4).must_equal [2, 4, 2]
272
- end
273
- end
274
- end