roda 3.28.0 → 3.33.0

Sign up to get free protection for your applications and to get access to all the features.
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,42 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe "backtracking_array plugin" do
4
- it "backtracks to next entry in array if later matcher fails" do
5
- app(:backtracking_array) do |r|
6
- r.is %w'a a/b' do |id|
7
- id
8
- end
9
-
10
- r.is %w'c c/d', %w'd e' do |a, b|
11
- "#{a}-#{b}"
12
- end
13
-
14
- r.is [%w'f f/g', %w'g g/h'] do |id|
15
- id
16
- end
17
- end
18
-
19
- tests = lambda do
20
- status.must_equal 404
21
-
22
- body("/a").must_equal 'a'
23
- body("/a/b").must_equal 'a/b'
24
- status("/a/b/").must_equal 404
25
-
26
- body("/c/d").must_equal 'c-d'
27
- body("/c/e").must_equal 'c-e'
28
- body("/c/d/d").must_equal 'c/d-d'
29
- body("/c/d/e").must_equal 'c/d-e'
30
- status("/c/d/").must_equal 404
31
-
32
- body("/f").must_equal 'f'
33
- body("/f/g").must_equal 'f/g'
34
- body("/g").must_equal 'g'
35
- body("/g/h").must_equal 'g/h'
36
- status("/f/g/").must_equal 404
37
- status("/g/h/").must_equal 404
38
- end
39
-
40
- tests.call
41
- end
42
- end
@@ -1,106 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- begin
4
- require 'tilt/erb'
5
- rescue LoadError
6
- warn "tilt not installed, skipping branch_locals plugin test"
7
- else
8
-
9
- describe "branch_locals plugin" do
10
- it "should set view and layout locals to use" do
11
- app(:branch_locals) do
12
- set_view_locals :title=>'About Roda'
13
- set_layout_locals :title=>'Home'
14
- view(:inline=>'<h1><%= title %></h1>', :layout=>{:inline=>"<title>Alternative Layout: <%= title %></title>\n<%= yield %>"})
15
- end
16
-
17
- body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
18
- end
19
-
20
- it "should have set_view_locals work without set_layout_locals" do
21
- app(:branch_locals) do
22
- set_view_locals :title=>'About Roda'
23
- view(:inline=>'<h1><%= title %></h1>', :layout=>{:inline=>"<title>Alternative Layout: <%= title %></title>\n<%= yield %>", :locals=>{:title=>'Home'}})
24
- end
25
-
26
- body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
27
- end
28
-
29
- it "should have set_layout_locals work without set_view_locals" do
30
- app(:branch_locals) do
31
- set_layout_locals :title=>'Home'
32
- view(:inline=>'<h1><%= title %></h1>', :locals=>{:title=>'About Roda'}, :layout=>{:inline=>"<title>Alternative Layout: <%= title %></title>\n<%= yield %>"})
33
- end
34
-
35
- body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
36
- end
37
-
38
- it "should merge multiple calls to set view and layout locals" do
39
- app(:branch_locals) do
40
- set_layout_locals :title=>'About Roda'
41
- set_view_locals :title=>'Home'
42
-
43
- set_layout_locals :a=>'A'
44
- set_view_locals :b=>'B'
45
-
46
- view(:inline=>'<%= title %>:<%= b %>', :layout=>{:inline=>"<%= title %>:<%= a %>::<%= yield %>"})
47
- end
48
-
49
- body.strip.must_equal "About Roda:A::Home:B"
50
- end
51
-
52
- it "should merge multiple calls in the correct order" do
53
- app(:branch_locals) do
54
- set_layout_locals :title=>'Roda'
55
- set_view_locals :title=>'H'
56
-
57
- set_layout_locals :a=>'A', :title=>'About Roda'
58
- set_view_locals :b=>'B', :title=>'Home'
59
-
60
- view(:inline=>'<%= title %>:<%= b %>', :layout=>{:inline=>"<%= title %>:<%= a %>::<%= yield %>"})
61
- end
62
-
63
- body.strip.must_equal "About Roda:A::Home:B"
64
- end
65
-
66
- it "should have set_view_locals have more precedence than plugin options, but less than view/render method options" do
67
- app(:bare) do
68
- plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'multiple-layout'}
69
- plugin :render_locals, :render=>{:title=>'Home', :b=>'B'}, :layout=>{:title=>'About Roda', :a=>'A'}
70
- plugin :branch_locals
71
-
72
- route do |r|
73
- r.is 'c' do
74
- view(:multiple)
75
- end
76
-
77
- set_view_locals :b=>'BB'
78
- set_layout_locals :a=>'AA'
79
-
80
- r.on 'b' do
81
- set_view_locals :title=>'About'
82
- set_layout_locals :title=>'Roda'
83
-
84
- r.is 'a' do
85
- view(:multiple)
86
- end
87
-
88
- view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
89
- end
90
-
91
- r.is 'a' do
92
- view(:multiple)
93
- end
94
-
95
- view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
96
- end
97
- end
98
-
99
- body('/c').strip.must_equal "About Roda:A::Home:B"
100
- body('/b/a').strip.must_equal "Roda:AA::About:BB"
101
- body('/b').strip.must_equal "Roda:AAA::About:BBB"
102
- body('/a').strip.must_equal "About Roda:AA::Home:BB"
103
- body.strip.must_equal "About Roda:AAA::Home:BBB"
104
- end
105
- end
106
- end
@@ -1,337 +0,0 @@
1
- require_relative "../spec_helper"
2
-
3
- describe 'response.cache_control' do
4
- it 'sets the Cache-Control header' do
5
- app(:caching) do |r|
6
- response.cache_control :public=>true, :no_cache=>true, :max_age => 60
7
- end
8
- header('Cache-Control').split(', ').sort.must_equal ['max-age=60', 'no-cache', 'public']
9
- end
10
-
11
- it 'does not add a Cache-Control header if it would be empty' do
12
- app(:caching) do |r|
13
- response.cache_control({})
14
- end
15
- header('Cache-Control').must_be_nil
16
- end
17
- end
18
-
19
- describe 'response.expires' do
20
- it 'sets the Cache-Control and Expires header' do
21
- app(:caching) do |r|
22
- response.expires 60, :public=>true, :no_cache=>true
23
- end
24
- header('Cache-Control').split(', ').sort.must_equal ['max-age=60', 'no-cache', 'public']
25
- ((Time.httpdate(header('Expires')) - Time.now).round - 60).abs.must_be :<=, 1
26
- end
27
-
28
- it 'can be called with only one argument' do
29
- app(:caching) do |r|
30
- response.expires 60
31
- end
32
- header('Cache-Control').split(', ').sort.must_equal ['max-age=60']
33
- ((Time.httpdate(header('Expires')) - Time.now).round - 60).abs.must_be :<=, 1
34
- end
35
- end
36
-
37
- describe 'response.finish' do
38
- it 'removes Content-Type and Content-Length for 304 responses' do
39
- app(:caching) do |r|
40
- response.status = 304
41
- nil
42
- end
43
- header('Content-Type').must_be_nil
44
- header('Content-Length').must_be_nil
45
- end
46
-
47
- it 'does not change non-304 responses' do
48
- app(:caching) do |r|
49
- response.status = 200
50
- nil
51
- end
52
- header('Content-Type').must_equal 'text/html'
53
- header('Content-Length').must_equal '0'
54
- end
55
- end
56
-
57
- describe 'request.last_modified' do
58
- it 'ignores nil' do
59
- app(:caching) do |r|
60
- r.last_modified nil
61
- end
62
- header('Last-Modified').must_be_nil
63
- end
64
-
65
- it 'does not change a status other than 200' do
66
- app(:caching) do |r|
67
- response.status = 201
68
- r.last_modified Time.now
69
- end
70
- status.must_equal 201
71
- status('HTTP_IF_MODIFIED_SINCE' => 'Sun, 26 Sep 2030 23:43:52 GMT').must_equal 201
72
- status('HTTP_IF_MODIFIED_SINCE' => 'Sun, 26 Sep 2000 23:43:52 GMT').must_equal 201
73
- end
74
- end
75
-
76
- describe 'request.last_modified' do
77
- def res(a={})
78
- s, h, b = req(a)
79
- h['Last-Modified'].must_equal @last_modified.httpdate
80
- [s, b.join]
81
- end
82
-
83
- before(:all) do
84
- lm = @last_modified = Time.now
85
- app(:caching) do |r|
86
- r.last_modified lm
87
- 'ok'
88
- end
89
- end
90
-
91
- it 'just sets Last-Modified if no If-Modified-Since header' do
92
- res.must_equal [200, 'ok']
93
- end
94
-
95
- it 'just sets Last-Modified if bogus If-Modified-Since header' do
96
- res('HTTP_IF_MODIFIED_SINCE' => 'a really weird date').must_equal [200, 'ok']
97
- end
98
-
99
- it 'just sets Last-Modified if modified since If-Modified-Since header' do
100
- res('HTTP_IF_MODIFIED_SINCE' => (@last_modified - 1).httpdate).must_equal [200, 'ok']
101
- end
102
-
103
- it 'sets Last-Modified and returns 304 if modified on If-Modified-Since header' do
104
- res('HTTP_IF_MODIFIED_SINCE' => @last_modified.httpdate).must_equal [304, '']
105
- end
106
-
107
- it 'sets Last-Modified and returns 304 if modified before If-Modified-Since header' do
108
- res('HTTP_IF_MODIFIED_SINCE' => (@last_modified + 1).httpdate).must_equal [304, '']
109
- end
110
-
111
- it 'sets Last-Modified if If-None-Match header present' do
112
- res('HTTP_IF_NONE_MATCH' => '*', 'HTTP_IF_MODIFIED_SINCE' => (@last_modified + 1).httpdate).must_equal [200, 'ok']
113
- end
114
-
115
- it 'sets Last-Modified if modified before If-Unmodified-Since header' do
116
- res('HTTP_IF_UNMODIFIED_SINCE' => (@last_modified + 1).httpdate).must_equal [200, 'ok']
117
- end
118
-
119
- it 'sets Last-Modified if modified on If-Unmodified-Since header' do
120
- res('HTTP_IF_UNMODIFIED_SINCE' => @last_modified.httpdate).must_equal [200, 'ok']
121
- end
122
-
123
- it 'sets Last-Modified and returns 412 if modified after If-Unmodified-Since header' do
124
- res('HTTP_IF_UNMODIFIED_SINCE' => (@last_modified - 1).httpdate).must_equal [412, '']
125
- end
126
- end
127
-
128
- describe 'request.etag' do
129
- before(:all) do
130
- app(:caching) do |r|
131
- r.is "" do
132
- response.status = r.env['status'] if r.env['status']
133
- etag_opts = {}
134
- etag_opts[:new_resource] = r.env['new_resource'] if r.env.has_key?('new_resource')
135
- etag_opts[:weak] = r.env['weak'] if r.env.has_key?('weak')
136
- r.etag 'foo', etag_opts
137
- 'ok'
138
- end
139
- end
140
- end
141
-
142
- it 'uses a weak etag with the :weak option' do
143
- header('ETag', 'weak'=>true).must_equal 'W/"foo"'
144
- end
145
-
146
- describe 'for GET requests' do
147
- def res(a={})
148
- s, h, b = req(a)
149
- h['ETag'].must_equal '"foo"'
150
- [s, b.join]
151
- end
152
-
153
- it "sets etag if no If-None-Match" do
154
- res.must_equal [200, 'ok']
155
- end
156
-
157
- it "sets etag and returns 304 if If-None-Match is *" do
158
- res('HTTP_IF_NONE_MATCH' => '*').must_equal [304, '']
159
- end
160
-
161
- it "sets etag and if If-None-Match is * and it is a new resource" do
162
- res('HTTP_IF_NONE_MATCH' => '*', 'new_resource'=>true).must_equal [200, 'ok']
163
- end
164
-
165
- it "sets etag and returns 304 if If-None-Match is etag" do
166
- res('HTTP_IF_NONE_MATCH' => '"foo"').must_equal [304, '']
167
- end
168
-
169
- it "sets etag and returns 304 if If-None-Match includes etag" do
170
- res('HTTP_IF_NONE_MATCH' => '"bar", "foo"').must_equal [304, '']
171
- end
172
-
173
- it "sets etag if If-None-Match does not include etag" do
174
- res('HTTP_IF_NONE_MATCH' => '"bar", "baz"').must_equal [200, 'ok']
175
- end
176
-
177
- it "sets etag and does not change status code if status code set and not 2xx or 304 if If-None-Match is etag" do
178
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>499).must_equal [499, 'ok']
179
- end
180
-
181
- it "sets etag and returns 304 if status code set to 2xx if If-None-Match is etag" do
182
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>201).must_equal [304, '']
183
- end
184
-
185
- it "sets etag and returns 304 if status code is already 304 if If-None-Match is etag" do
186
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>304).must_equal [304, '']
187
- end
188
-
189
- it "sets etag if If-Match is *" do
190
- res('HTTP_IF_MATCH' => '*').must_equal [200, 'ok']
191
- end
192
-
193
- it "sets etag if If-Match is etag" do
194
- res('HTTP_IF_MATCH' => '"foo"').must_equal [200, 'ok']
195
- end
196
-
197
- it "sets etag if If-Match includes etag" do
198
- res('HTTP_IF_MATCH' => '"bar", "foo"').must_equal [200, 'ok']
199
- end
200
-
201
- it "sets etag and returns 412 if If-Match is * for new resources" do
202
- res('HTTP_IF_MATCH' => '*', 'new_resource'=>true).must_equal [412, '']
203
- end
204
-
205
- it "sets etag if If-Match does not include etag" do
206
- res('HTTP_IF_MATCH' => '"bar", "baz"', 'new_resource'=>true).must_equal [412, '']
207
- end
208
- end
209
-
210
- describe 'for PUT requests' do
211
- def res(a={})
212
- s, h, b = req(a.merge('REQUEST_METHOD'=>'PUT'))
213
- h['ETag'].must_equal '"foo"'
214
- [s, b.join]
215
- end
216
-
217
- it "sets etag if no If-None-Match" do
218
- res.must_equal [200, 'ok']
219
- end
220
-
221
- it "sets etag and returns 412 if If-None-Match is *" do
222
- res('HTTP_IF_NONE_MATCH' => '*').must_equal [412, '']
223
- end
224
-
225
- it "sets etag and if If-None-Match is * and it is a new resource" do
226
- res('HTTP_IF_NONE_MATCH' => '*', 'new_resource'=>true).must_equal [200, 'ok']
227
- end
228
-
229
- it "sets etag and returns 412 if If-None-Match is etag" do
230
- res('HTTP_IF_NONE_MATCH' => '"foo"').must_equal [412, '']
231
- end
232
-
233
- it "sets etag and returns 412 if If-None-Match includes etag" do
234
- res('HTTP_IF_NONE_MATCH' => '"bar", "foo"').must_equal [412, '']
235
- end
236
-
237
- it "sets etag if If-None-Match does not include etag" do
238
- res('HTTP_IF_NONE_MATCH' => '"bar", "baz"').must_equal [200, 'ok']
239
- end
240
-
241
- it "sets etag and does not change status code if status code set and not 2xx or 304 if If-None-Match is etag" do
242
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>499).must_equal [499, 'ok']
243
- end
244
-
245
- it "sets etag and returns 304 if status code set to 2xx if If-None-Match is etag" do
246
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>201).must_equal [412, '']
247
- end
248
-
249
- it "sets etag and returns 304 if status code is already 304 if If-None-Match is etag" do
250
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>304).must_equal [412, '']
251
- end
252
-
253
- it "sets etag if If-Match is *" do
254
- res('HTTP_IF_MATCH' => '*').must_equal [200, 'ok']
255
- end
256
-
257
- it "sets etag if If-Match is etag" do
258
- res('HTTP_IF_MATCH' => '"foo"').must_equal [200, 'ok']
259
- end
260
-
261
- it "sets etag if If-Match includes etag" do
262
- res('HTTP_IF_MATCH' => '"bar", "foo"').must_equal [200, 'ok']
263
- end
264
-
265
- it "sets etag and returns 412 if If-Match is * for new resources" do
266
- res('HTTP_IF_MATCH' => '*', 'new_resource'=>true).must_equal [412, '']
267
- end
268
-
269
- it "sets etag if If-Match does not include etag" do
270
- res('HTTP_IF_MATCH' => '"bar", "baz"', 'new_resource'=>true).must_equal [412, '']
271
- end
272
- end
273
-
274
- describe 'for POST requests' do
275
- def res(a={})
276
- s, h, b = req(a.merge('REQUEST_METHOD'=>'POST'))
277
- h['ETag'].must_equal '"foo"'
278
- [s, b.join]
279
- end
280
-
281
- it "sets etag if no If-None-Match" do
282
- res.must_equal [200, 'ok']
283
- end
284
-
285
- it "sets etag and returns 412 if If-None-Match is * and it is not a new resource" do
286
- res('HTTP_IF_NONE_MATCH' => '*', 'new_resource'=>false).must_equal [412, '']
287
- end
288
-
289
- it "sets etag and if If-None-Match is *" do
290
- res('HTTP_IF_NONE_MATCH' => '*').must_equal [200, 'ok']
291
- end
292
-
293
- it "sets etag and returns 412 if If-None-Match is etag" do
294
- res('HTTP_IF_NONE_MATCH' => '"foo"').must_equal [412, '']
295
- end
296
-
297
- it "sets etag and returns 412 if If-None-Match includes etag" do
298
- res('HTTP_IF_NONE_MATCH' => '"bar", "foo"').must_equal [412, '']
299
- end
300
-
301
- it "sets etag if If-None-Match does not include etag" do
302
- res('HTTP_IF_NONE_MATCH' => '"bar", "baz"').must_equal [200, 'ok']
303
- end
304
-
305
- it "sets etag and does not change status code if status code set and not 2xx or 304 if If-None-Match is etag" do
306
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>499).must_equal [499, 'ok']
307
- end
308
-
309
- it "sets etag and returns 304 if status code set to 2xx if If-None-Match is etag" do
310
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>201).must_equal [412, '']
311
- end
312
-
313
- it "sets etag and returns 304 if status code is already 304 if If-None-Match is etag" do
314
- res('HTTP_IF_NONE_MATCH' => '"foo"', 'status'=>304).must_equal [412, '']
315
- end
316
-
317
- it "sets etag if If-Match is * and this is not a new resource" do
318
- res('HTTP_IF_MATCH' => '*', 'new_resource'=>false).must_equal [200, 'ok']
319
- end
320
-
321
- it "sets etag if If-Match is etag" do
322
- res('HTTP_IF_MATCH' => '"foo"').must_equal [200, 'ok']
323
- end
324
-
325
- it "sets etag if If-Match includes etag" do
326
- res('HTTP_IF_MATCH' => '"bar", "foo"').must_equal [200, 'ok']
327
- end
328
-
329
- it "sets etag and returns 412 if If-Match is * for new resources" do
330
- res('HTTP_IF_MATCH' => '*').must_equal [412, '']
331
- end
332
-
333
- it "sets etag if If-Match does not include etag" do
334
- res('HTTP_IF_MATCH' => '"bar", "baz"', 'new_resource'=>true).must_equal [412, '']
335
- end
336
- end
337
- end