roda 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +34 -0
  3. data/Rakefile +22 -46
  4. data/doc/release_notes/2.3.0.txt +109 -0
  5. data/lib/roda/plugins/assets.rb +2 -1
  6. data/lib/roda/plugins/caching.rb +1 -1
  7. data/lib/roda/plugins/chunked.rb +1 -1
  8. data/lib/roda/plugins/error_email.rb +1 -1
  9. data/lib/roda/plugins/head.rb +6 -0
  10. data/lib/roda/plugins/heartbeat.rb +40 -0
  11. data/lib/roda/plugins/json.rb +23 -3
  12. data/lib/roda/plugins/json_parser.rb +72 -0
  13. data/lib/roda/plugins/mailer.rb +22 -5
  14. data/lib/roda/plugins/named_templates.rb +2 -2
  15. data/lib/roda/plugins/path_rewriter.rb +82 -0
  16. data/lib/roda/plugins/precompile_templates.rb +87 -0
  17. data/lib/roda/plugins/render.rb +111 -43
  18. data/lib/roda/plugins/render_each.rb +1 -1
  19. data/lib/roda/plugins/shared_vars.rb +1 -1
  20. data/lib/roda/plugins/view_options.rb +28 -3
  21. data/lib/roda/version.rb +1 -1
  22. data/spec/composition_spec.rb +3 -3
  23. data/spec/env_spec.rb +1 -1
  24. data/spec/freeze_spec.rb +6 -6
  25. data/spec/integration_spec.rb +16 -15
  26. data/spec/matchers_spec.rb +110 -110
  27. data/spec/opts_spec.rb +8 -8
  28. data/spec/plugin/_erubis_escaping_spec.rb +34 -3
  29. data/spec/plugin/all_verbs_spec.rb +8 -8
  30. data/spec/plugin/assets_spec.rb +164 -150
  31. data/spec/plugin/backtracking_array_spec.rb +18 -18
  32. data/spec/plugin/caching_spec.rb +70 -70
  33. data/spec/plugin/chunked_spec.rb +38 -38
  34. data/spec/plugin/class_level_routing_spec.rb +78 -78
  35. data/spec/plugin/content_for_spec.rb +2 -2
  36. data/spec/plugin/cookies_spec.rb +4 -4
  37. data/spec/plugin/csrf_spec.rb +8 -8
  38. data/spec/plugin/default_headers_spec.rb +6 -6
  39. data/spec/plugin/delay_build_spec.rb +7 -6
  40. data/spec/plugin/delegate_spec.rb +2 -2
  41. data/spec/plugin/delete_empty_headers_spec.rb +2 -2
  42. data/spec/plugin/drop_body_spec.rb +6 -6
  43. data/spec/plugin/empty_root_spec.rb +3 -3
  44. data/spec/plugin/environments_spec.rb +7 -7
  45. data/spec/plugin/error_email_spec.rb +23 -23
  46. data/spec/plugin/error_handler_spec.rb +14 -14
  47. data/spec/plugin/flash_spec.rb +30 -29
  48. data/spec/plugin/h_spec.rb +1 -1
  49. data/spec/plugin/halt_spec.rb +16 -16
  50. data/spec/plugin/hash_matcher_spec.rb +5 -5
  51. data/spec/plugin/head_spec.rb +10 -10
  52. data/spec/plugin/header_matchers_spec.rb +13 -13
  53. data/spec/plugin/heartbeat_spec.rb +74 -0
  54. data/spec/plugin/hooks_spec.rb +20 -20
  55. data/spec/plugin/indifferent_params_spec.rb +1 -1
  56. data/spec/plugin/json_parser_spec.rb +72 -0
  57. data/spec/plugin/json_spec.rb +22 -9
  58. data/spec/plugin/mailer_spec.rb +72 -58
  59. data/spec/plugin/match_affix_spec.rb +2 -2
  60. data/spec/plugin/middleware_spec.rb +7 -7
  61. data/spec/plugin/module_include_spec.rb +4 -4
  62. data/spec/plugin/multi_route_spec.rb +66 -66
  63. data/spec/plugin/multi_run_spec.rb +21 -21
  64. data/spec/plugin/named_templates_spec.rb +6 -6
  65. data/spec/plugin/not_allowed_spec.rb +17 -17
  66. data/spec/plugin/not_found_spec.rb +14 -14
  67. data/spec/plugin/padrino_render_spec.rb +2 -2
  68. data/spec/plugin/param_matchers_spec.rb +6 -6
  69. data/spec/plugin/partials_spec.rb +3 -3
  70. data/spec/plugin/pass_spec.rb +7 -7
  71. data/spec/plugin/path_matchers_spec.rb +6 -6
  72. data/spec/plugin/path_rewriter_spec.rb +37 -0
  73. data/spec/plugin/path_spec.rb +41 -40
  74. data/spec/plugin/per_thread_caching_spec.rb +6 -6
  75. data/spec/plugin/precompile_templates_spec.rb +74 -0
  76. data/spec/plugin/render_each_spec.rb +4 -4
  77. data/spec/plugin/render_spec.rb +179 -76
  78. data/spec/plugin/shared_vars_spec.rb +4 -4
  79. data/spec/plugin/sinatra_helpers_spec.rb +121 -121
  80. data/spec/plugin/slash_path_empty_spec.rb +10 -10
  81. data/spec/plugin/static_spec.rb +4 -4
  82. data/spec/plugin/streaming_spec.rb +11 -11
  83. data/spec/plugin/symbol_matchers_spec.rb +24 -24
  84. data/spec/plugin/symbol_views_spec.rb +3 -3
  85. data/spec/plugin/view_options_spec.rb +10 -10
  86. data/spec/plugin_spec.rb +2 -2
  87. data/spec/redirect_spec.rb +10 -10
  88. data/spec/request_spec.rb +8 -8
  89. data/spec/response_spec.rb +23 -23
  90. data/spec/session_spec.rb +4 -4
  91. data/spec/spec_helper.rb +5 -19
  92. data/spec/version_spec.rb +4 -4
  93. data/spec/views/iv.erb +1 -0
  94. metadata +16 -5
@@ -8,15 +8,15 @@ describe "slash_path_empty" do
8
8
  r.get("b"){"3"}
9
9
  end
10
10
 
11
- body("").should == '1'
12
- body.should == '1'
13
- body("a").should == ''
14
- body("/a").should == '2'
15
- body("/a/").should == '2'
16
- body("/a/b").should == ''
17
- body("b").should == ''
18
- body("/b").should == '3'
19
- body("/b/").should == '3'
20
- body("/b/c").should == ''
11
+ body("").must_equal '1'
12
+ body.must_equal '1'
13
+ body("a").must_equal ''
14
+ body("/a").must_equal '2'
15
+ body("/a/").must_equal '2'
16
+ body("/a/b").must_equal ''
17
+ body("b").must_equal ''
18
+ body("/b").must_equal '3'
19
+ body("/b/").must_equal '3'
20
+ body("/b/c").must_equal ''
21
21
  end
22
22
  end
@@ -10,8 +10,8 @@ describe "static plugin" do
10
10
  end
11
11
  end
12
12
 
13
- body.should == 'a'
14
- body('/about/_test.erb').should == File.read('spec/views/about/_test.erb')
13
+ body.must_equal 'a'
14
+ body('/about/_test.erb').must_equal File.read('spec/views/about/_test.erb')
15
15
  end
16
16
 
17
17
  it "respects the application's :root option" do
@@ -24,7 +24,7 @@ describe "static plugin" do
24
24
  end
25
25
  end
26
26
 
27
- body.should == 'a'
28
- body('/about/_test.erb').should == File.read('spec/views/about/_test.erb')
27
+ body.must_equal 'a'
28
+ body('/about/_test.erb').must_equal File.read('spec/views/about/_test.erb')
29
29
  end
30
30
  end
@@ -9,9 +9,9 @@ describe "streaming plugin" do
9
9
  end
10
10
 
11
11
  s, h, b = req
12
- s.should == 200
13
- h.should == {'Content-Type'=>'text/html'}
14
- b.to_a.should == %w'a b c'
12
+ s.must_equal 200
13
+ h.must_equal('Content-Type'=>'text/html')
14
+ b.to_a.must_equal %w'a b c'
15
15
  end
16
16
 
17
17
  it "should handle errors when streaming, and run callbacks" do
@@ -25,11 +25,11 @@ describe "streaming plugin" do
25
25
  end
26
26
 
27
27
  s, h, b = req
28
- s.should == 200
29
- h.should == {'Content-Type'=>'text/html'}
28
+ s.must_equal 200
29
+ h.must_equal('Content-Type'=>'text/html')
30
30
  b.callback{a << 'd'}
31
- proc{b.each{|v| a << v}}.should raise_error(Roda::RodaError)
32
- a.should == %w'a b e d'
31
+ proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
32
+ a.must_equal %w'a b e d'
33
33
  end
34
34
 
35
35
  it "should handle :loop option to loop" do
@@ -43,10 +43,10 @@ describe "streaming plugin" do
43
43
  end
44
44
 
45
45
  s, h, b = req
46
- s.should == 200
47
- h.should == {'Content-Type'=>'text/html'}
46
+ s.must_equal 200
47
+ h.must_equal('Content-Type'=>'text/html')
48
48
  b.callback{a << 'd'}
49
- proc{b.each{|v| a << v}}.should raise_error(Roda::RodaError)
50
- a.should == %w'a b e d'
49
+ proc{b.each{|v| a << v}}.must_raise(Roda::RodaError)
50
+ a.must_equal %w'a b e d'
51
51
  end
52
52
  end
@@ -45,29 +45,29 @@ describe "symbol_matchers plugin" do
45
45
  end
46
46
  end
47
47
 
48
- status.should == 404
49
- body("/1").should == 'd1'
50
- body("/11232135").should == 'd11232135'
51
- body("/a").should == 'wa'
52
- body("/1az0").should == 'w1az0'
53
- body("/f").should == 'ff'
54
- body("/foo").should == 'foonil'
55
- body("/foo/123").should == 'foo"123"'
56
- status("/foo/bar").should == 404
57
- status("/foo/123/a").should == 404
58
- body("/bar").should == 'barnil'
59
- body("/bar/foo").should == 'bar"foo"'
60
- status("/bar/foo/baz").should == 404
61
- body("/format").should == 'formatnil'
62
- body("/format.json").should == 'format"json"'
63
- status("/format.").should == 404
64
- body("/ffffffffffffffff").should == 'fffffffffffffffff'
65
- status("/-").should == 404
66
- body("/1/1a/f").should == 'dwf11af'
67
- body("/12/1azy/fffff").should == 'dwf121azyfffff'
68
- status("/1/f/a").should == 404
69
- body("/qa/b/c/d//f/g").should == 'resta/b/c/d//f/g'
70
- body('/q').should == 'rest'
71
- body('/thing/q').should == 'thingq'
48
+ status.must_equal 404
49
+ body("/1").must_equal 'd1'
50
+ body("/11232135").must_equal 'd11232135'
51
+ body("/a").must_equal 'wa'
52
+ body("/1az0").must_equal 'w1az0'
53
+ body("/f").must_equal 'ff'
54
+ body("/foo").must_equal 'foonil'
55
+ body("/foo/123").must_equal 'foo"123"'
56
+ status("/foo/bar").must_equal 404
57
+ status("/foo/123/a").must_equal 404
58
+ body("/bar").must_equal 'barnil'
59
+ body("/bar/foo").must_equal 'bar"foo"'
60
+ status("/bar/foo/baz").must_equal 404
61
+ body("/format").must_equal 'formatnil'
62
+ body("/format.json").must_equal 'format"json"'
63
+ status("/format.").must_equal 404
64
+ body("/ffffffffffffffff").must_equal 'fffffffffffffffff'
65
+ status("/-").must_equal 404
66
+ body("/1/1a/f").must_equal 'dwf11af'
67
+ body("/12/1azy/fffff").must_equal 'dwf121azyfffff'
68
+ status("/1/f/a").must_equal 404
69
+ body("/qa/b/c/d//f/g").must_equal 'resta/b/c/d//f/g'
70
+ body('/q').must_equal 'rest'
71
+ body('/thing/q').must_equal 'thingq'
72
72
  end
73
73
  end
@@ -22,11 +22,11 @@ describe "symbol_views plugin" do
22
22
  end
23
23
 
24
24
  it "should call view with the symbol" do
25
- body.should == "vsym"
25
+ body.must_equal "vsym"
26
26
  end
27
27
 
28
28
  it "should not affect other return types" do
29
- body("/string").should == 'string'
30
- body("/foo").should == ''
29
+ body("/string").must_equal 'string'
30
+ body("/foo").must_equal ''
31
31
  end
32
32
  end
@@ -32,15 +32,15 @@ describe "view_options plugin view subdirs" do
32
32
  end
33
33
 
34
34
  it "should use set subdir if template name does not contain a slash" do
35
- body("/home").strip.should == "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
35
+ body("/home").strip.must_equal "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
36
36
  end
37
37
 
38
38
  it "should not use set subdir if template name contains a slash" do
39
- body("/about").strip.should == "<h1>About Roda</h1>"
39
+ body("/about").strip.must_equal "<h1>About Roda</h1>"
40
40
  end
41
41
 
42
42
  it "should not change behavior when subdir is not set" do
43
- body("/path").strip.should == "<h1>Path</h1>"
43
+ body("/path").strip.must_equal "<h1>Path</h1>"
44
44
  end
45
45
  end
46
46
 
@@ -54,7 +54,7 @@ describe "view_options plugin" do
54
54
  view('about')
55
55
  end
56
56
 
57
- body.strip.should == "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
57
+ body.strip.must_equal "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
58
58
  end
59
59
 
60
60
  it "should merge multiple calls to set view and layout options and locals" do
@@ -72,7 +72,7 @@ describe "view_options plugin" do
72
72
  view('multiple')
73
73
  end
74
74
 
75
- body.strip.should == "About Roda:A::Home:B"
75
+ body.strip.must_equal "About Roda:A::Home:B"
76
76
  end
77
77
 
78
78
  it "should have set_view_locals have more precedence than plugin options, but less than view/render method options" do
@@ -107,11 +107,11 @@ describe "view_options plugin" do
107
107
  end
108
108
  end
109
109
 
110
- body('/c').strip.should == "About Roda:A::Home:B"
111
- body('/b/a').strip.should == "Roda:AA::About:BB"
112
- body('/b').strip.should == "Roda:AAA::About:BBB"
113
- body('/a').strip.should == "About Roda:AA::Home:BB"
114
- body.strip.should == "About Roda:AAA::Home:BBB"
110
+ body('/c').strip.must_equal "About Roda:A::Home:B"
111
+ body('/b/a').strip.must_equal "Roda:AA::About:BB"
112
+ body('/b').strip.must_equal "Roda:AAA::About:BBB"
113
+ body('/a').strip.must_equal "About Roda:AA::Home:BB"
114
+ body.strip.must_equal "About Roda:AAA::Home:BBB"
115
115
  end
116
116
  end
117
117
  end
@@ -57,7 +57,7 @@ describe "plugins" do
57
57
  end
58
58
  end
59
59
 
60
- body('/hello').should == 'Foo aDefault'
60
+ body('/hello').must_equal 'Foo aDefault'
61
61
  end
62
62
 
63
63
  it "should support registering plugins and loading them by symbol" do
@@ -66,6 +66,6 @@ describe "plugins" do
66
66
  a
67
67
  end
68
68
 
69
- body.should == '1'
69
+ body.must_equal '1'
70
70
  end
71
71
  end
@@ -24,18 +24,18 @@ describe "redirects" do
24
24
  end
25
25
  end
26
26
 
27
- status.should == 302
28
- header('Location').should == '/hello'
29
- body.should == ''
27
+ status.must_equal 302
28
+ header('Location').must_equal '/hello'
29
+ body.must_equal ''
30
30
 
31
- status("/about").should == 301
32
- header('Location', "/about").should == '/hello'
33
- body("/about").should == ''
31
+ status("/about").must_equal 301
32
+ header('Location', "/about").must_equal '/hello'
33
+ body("/about").must_equal ''
34
34
 
35
- status("/foo", 'REQUEST_METHOD'=>'POST').should == 302
36
- header('Location', "/foo", 'REQUEST_METHOD'=>'POST').should == '/foo'
37
- body("/foo", 'REQUEST_METHOD'=>'POST').should == ''
35
+ status("/foo", 'REQUEST_METHOD'=>'POST').must_equal 302
36
+ header('Location', "/foo", 'REQUEST_METHOD'=>'POST').must_equal '/foo'
37
+ body("/foo", 'REQUEST_METHOD'=>'POST').must_equal ''
38
38
 
39
- proc{req('/foo')}.should raise_error(Roda::RodaError)
39
+ proc{req('/foo')}.must_raise(Roda::RodaError)
40
40
  end
41
41
  end
@@ -8,7 +8,7 @@ describe "request.path, .remaining_path, and .matched_path" do
8
8
  end
9
9
  end
10
10
 
11
- body("/foo/bar").should == "/foo/bar:/foo:/bar"
11
+ body("/foo/bar").must_equal "/foo/bar:/foo:/bar"
12
12
  end
13
13
  end
14
14
 
@@ -18,7 +18,7 @@ describe "request.halt" do
18
18
  r.halt [200, {}, ['foo']]
19
19
  end
20
20
 
21
- body.should == "foo"
21
+ body.must_equal "foo"
22
22
  end
23
23
 
24
24
  it "should use current response if no argument is given" do
@@ -27,7 +27,7 @@ describe "request.halt" do
27
27
  r.halt
28
28
  end
29
29
 
30
- body.should == "foo"
30
+ body.must_equal "foo"
31
31
  end
32
32
  end
33
33
 
@@ -42,7 +42,7 @@ describe "request.scope" do
42
42
  end
43
43
  end
44
44
 
45
- body.should == "a"
45
+ body.must_equal "a"
46
46
  end
47
47
  end
48
48
 
@@ -58,8 +58,8 @@ describe "request.inspect" do
58
58
  end
59
59
  end
60
60
 
61
- body('/a/b').should == "#<Foo::RodaRequest GET /a/b>"
62
- body('REQUEST_METHOD'=>'POST').should == "#<Foo::RodaRequest POST />"
61
+ body('/a/b').must_equal "#<Foo::RodaRequest GET /a/b>"
62
+ body('REQUEST_METHOD'=>'POST').must_equal "#<Foo::RodaRequest POST />"
63
63
  end
64
64
  end
65
65
 
@@ -69,7 +69,7 @@ describe "TERM.inspect" do
69
69
  r.class::TERM.inspect
70
70
  end
71
71
 
72
- body.should == "TERM"
72
+ body.must_equal "TERM"
73
73
  end
74
74
  end
75
75
 
@@ -80,6 +80,6 @@ describe "roda_class" do
80
80
  r.class.roda_class.opts[:a] + r.roda_class.opts[:a]
81
81
  end
82
82
 
83
- body.should == "aa"
83
+ body.must_equal "aa"
84
84
  end
85
85
  end
@@ -7,8 +7,8 @@ describe "response #[] and #[]=" do
7
7
  response['foo'] + response.headers['foo']
8
8
  end
9
9
 
10
- header('foo').should == "bar"
11
- body.should == 'barbar'
10
+ header('foo').must_equal "bar"
11
+ body.must_equal 'barbar'
12
12
  end
13
13
  end
14
14
 
@@ -19,8 +19,8 @@ describe "response #headers and #body" do
19
19
  response.write response.body.is_a?(Array)
20
20
  end
21
21
 
22
- header('foo').should == "bar"
23
- body.should == 'true'
22
+ header('foo').must_equal "bar"
23
+ body.must_equal 'true'
24
24
  end
25
25
  end
26
26
 
@@ -31,7 +31,7 @@ describe "response #write" do
31
31
  response.write 'b'
32
32
  end
33
33
 
34
- body.should == 'ab'
34
+ body.must_equal 'ab'
35
35
  end
36
36
  end
37
37
 
@@ -42,7 +42,7 @@ describe "response #finish" do
42
42
  "#{s}#{h['Content-Type']}#{b.length}"
43
43
  end
44
44
 
45
- body.should == '404text/html0'
45
+ body.must_equal '404text/html0'
46
46
  end
47
47
 
48
48
  it "should set status to 200 if body has been written to" do
@@ -52,17 +52,17 @@ describe "response #finish" do
52
52
  response.write "#{s}#{h['Content-Type']}#{b.length}"
53
53
  end
54
54
 
55
- body.should == 'a200text/html1'
55
+ body.must_equal 'a200text/html1'
56
56
  end
57
57
 
58
58
  it "should set Content-Length header" do
59
59
  app do |r|
60
60
  response.write 'a'
61
- response['Content-Length'].should == nil
61
+ response['Content-Length'].must_equal nil
62
62
  throw :halt, response.finish
63
63
  end
64
64
 
65
- header('Content-Length').should == '1'
65
+ header('Content-Length').must_equal '1'
66
66
  end
67
67
 
68
68
  it "should not overwrite existing status" do
@@ -72,7 +72,7 @@ describe "response #finish" do
72
72
  "#{s}#{h['Content-Type']}#{b.length}"
73
73
  end
74
74
 
75
- body.should == '500text/html0'
75
+ body.must_equal '500text/html0'
76
76
  end
77
77
  end
78
78
 
@@ -82,7 +82,7 @@ describe "response #finish_with_body" do
82
82
  throw :halt, response.finish_with_body(['123'])
83
83
  end
84
84
 
85
- body.should == '123'
85
+ body.must_equal '123'
86
86
  end
87
87
 
88
88
  it "should set status to 200 if status has not been set" do
@@ -90,17 +90,17 @@ describe "response #finish_with_body" do
90
90
  throw :halt, response.finish_with_body([])
91
91
  end
92
92
 
93
- status.should == 200
93
+ status.must_equal 200
94
94
  end
95
95
 
96
96
  it "should not set Content-Length header" do
97
97
  app do |r|
98
98
  response.write 'a'
99
- response['Content-Length'].should == nil
99
+ response['Content-Length'].must_equal nil
100
100
  throw :halt, response.finish_with_body(['123'])
101
101
  end
102
102
 
103
- header('Content-Length').should == nil
103
+ header('Content-Length').must_equal nil
104
104
  end
105
105
 
106
106
  it "should not overwrite existing status" do
@@ -109,7 +109,7 @@ describe "response #finish_with_body" do
109
109
  throw :halt, response.finish_with_body(['123'])
110
110
  end
111
111
 
112
- status.should == 500
112
+ status.must_equal 500
113
113
  end
114
114
  end
115
115
 
@@ -124,10 +124,10 @@ describe "response #redirect" do
124
124
  end
125
125
  end
126
126
 
127
- status('/a').should == 303
128
- status.should == 302
129
- header('Location', '/a').should == '/foo'
130
- header('Location').should == '/bar'
127
+ status('/a').must_equal 303
128
+ status.must_equal 302
129
+ header('Location', '/a').must_equal '/foo'
130
+ header('Location').must_equal '/bar'
131
131
  end
132
132
  end
133
133
 
@@ -143,8 +143,8 @@ describe "response #empty?" do
143
143
  end
144
144
  end
145
145
 
146
- header('foo', '/a').should == 'true'
147
- header('foo').should == 'false'
146
+ header('foo', '/a').must_equal 'true'
147
+ header('foo').must_equal 'false'
148
148
  end
149
149
  end
150
150
 
@@ -161,7 +161,7 @@ describe "response #inspect" do
161
161
  end
162
162
  end
163
163
 
164
- body.should == '#<Foo::RodaResponse 200 {} []>'
164
+ body.must_equal '#<Foo::RodaResponse 200 {} []>'
165
165
  end
166
166
  end
167
167
 
@@ -172,6 +172,6 @@ describe "roda_class" do
172
172
  response.class.roda_class.opts[:a] + response.roda_class.opts[:a]
173
173
  end
174
174
 
175
- body.should == "aa"
175
+ body.must_equal "aa"
176
176
  end
177
177
  end