roda 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +26 -0
  3. data/README.rdoc +83 -22
  4. data/Rakefile +1 -1
  5. data/doc/release_notes/2.1.0.txt +124 -0
  6. data/lib/roda/plugins/assets.rb +17 -9
  7. data/lib/roda/plugins/class_level_routing.rb +5 -2
  8. data/lib/roda/plugins/delegate.rb +6 -3
  9. data/lib/roda/plugins/indifferent_params.rb +7 -0
  10. data/lib/roda/plugins/mailer.rb +18 -1
  11. data/lib/roda/plugins/multi_route.rb +2 -1
  12. data/lib/roda/plugins/path.rb +75 -6
  13. data/lib/roda/plugins/render.rb +33 -14
  14. data/lib/roda/plugins/static.rb +35 -0
  15. data/lib/roda/plugins/view_options.rb +161 -0
  16. data/lib/roda/plugins/view_subdirs.rb +6 -63
  17. data/lib/roda/version.rb +1 -1
  18. data/spec/composition_spec.rb +12 -0
  19. data/spec/matchers_spec.rb +34 -0
  20. data/spec/plugin/assets_spec.rb +112 -17
  21. data/spec/plugin/delete_empty_headers_spec.rb +12 -0
  22. data/spec/plugin/mailer_spec.rb +46 -3
  23. data/spec/plugin/module_include_spec.rb +17 -0
  24. data/spec/plugin/multi_route_spec.rb +10 -0
  25. data/spec/plugin/named_templates_spec.rb +6 -0
  26. data/spec/plugin/not_found_spec.rb +1 -1
  27. data/spec/plugin/path_spec.rb +76 -0
  28. data/spec/plugin/render_each_spec.rb +6 -0
  29. data/spec/plugin/render_spec.rb +40 -1
  30. data/spec/plugin/sinatra_helpers_spec.rb +5 -0
  31. data/spec/plugin/static_spec.rb +30 -0
  32. data/spec/plugin/view_options_spec.rb +117 -0
  33. data/spec/spec_helper.rb +5 -1
  34. data/spec/views/multiple-layout.erb +1 -0
  35. data/spec/views/multiple.erb +1 -0
  36. metadata +10 -4
  37. data/spec/plugin/static_path_info_spec.rb +0 -56
  38. data/spec/plugin/view_subdirs_spec.rb +0 -44
@@ -1,5 +1,10 @@
1
1
  require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
2
2
 
3
+ begin
4
+ require 'tilt/erb'
5
+ rescue LoadError
6
+ warn "tilt not installed, skipping named_templates plugin test"
7
+ else
3
8
  describe "named_templates plugin" do
4
9
  it "adds template method method for naming templates, and have render recognize it" do
5
10
  app(:bare) do
@@ -88,3 +93,4 @@ describe "named_templates plugin" do
88
93
  body('/bar').should == 'bar43-barfoo42-baz'
89
94
  end
90
95
  end
96
+ end
@@ -102,7 +102,7 @@ describe "not_found plugin" do
102
102
  end
103
103
 
104
104
  o = Object.new
105
- def o.join() '' end
105
+ def o.each; end
106
106
  route do |r|
107
107
  r.halt [404, {}, o]
108
108
  end
@@ -9,6 +9,15 @@ describe "path plugin" do
9
9
  end
10
10
  end
11
11
 
12
+ def path_script_name_app(*args, &block)
13
+ app(:bare) do
14
+ opts[:add_script_name] = true
15
+ plugin :path
16
+ path *args, &block
17
+ route{|r| send(r.path_info)}
18
+ end
19
+ end
20
+
12
21
  def path_block_app(b, *args, &block)
13
22
  path_app(*args, &block)
14
23
  app.route{|r| send(r.path_info, &b)}
@@ -58,6 +67,16 @@ describe "path plugin" do
58
67
  body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/baz/bar/foo"
59
68
  end
60
69
 
70
+ it "respects :add_script_name app option for automatically adding the script name" do
71
+ path_script_name_app(:foo){"/bar/foo"}
72
+ body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/baz/bar/foo"
73
+ end
74
+
75
+ it "supports :add_script_name=>false option for not automatically adding the script name" do
76
+ path_script_name_app(:foo, :add_script_name=>false){"/bar/foo"}
77
+ body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/bar/foo"
78
+ end
79
+
61
80
  it "supports path method accepting a block when using :add_script_name" do
62
81
  path_block_app(lambda{"c"}, :foo, :add_script_name=>true){|&block| "/bar/foo/#{block.call}"}
63
82
  body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/baz/bar/foo/c"
@@ -91,3 +110,60 @@ describe "path plugin" do
91
110
  body("foo_url", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>81).should == "http://example.org:81/bar/foo"
92
111
  end
93
112
  end
113
+
114
+ describe "path plugin" do
115
+ before do
116
+ app(:bare) do
117
+ plugin :path
118
+ route{|r| path(*env['path'])}
119
+ end
120
+
121
+
122
+ c = Class.new{attr_accessor :a}
123
+ app.path(c){|obj, *args| "/d/#{obj.a}/#{File.join(*args)}"}
124
+ @obj = c.new
125
+ @obj.a = 1
126
+ end
127
+
128
+ it "Roda#path respects classes and symbols registered via Roda.path" do
129
+ # Strings
130
+ body('path'=>'/foo/bar').should == '/foo/bar'
131
+
132
+ # Classes
133
+ body('path'=>@obj).should == '/d/1/'
134
+ body('path'=>[@obj, 'foo']).should == '/d/1/foo'
135
+ body('path'=>[@obj, 'foo', 'bar']).should == '/d/1/foo/bar'
136
+ end
137
+
138
+ it "Roda#path raises an error for an unrecognized class" do
139
+ # Strings
140
+ proc{body('path'=>:foo)}.should raise_error(Roda::RodaError)
141
+ end
142
+
143
+ it "Roda#path respects :add_script_name app option" do
144
+ app.opts[:add_script_name] = true
145
+
146
+ # Strings
147
+ body('path'=>'/foo/bar', 'SCRIPT_NAME'=>'/baz').should == '/baz/foo/bar'
148
+
149
+ # Classes
150
+ body('path'=>@obj, 'SCRIPT_NAME'=>'/baz').should == '/baz/d/1/'
151
+ body('path'=>[@obj, 'foo'], 'SCRIPT_NAME'=>'/baz').should == '/baz/d/1/foo'
152
+ body('path'=>[@obj, 'foo', 'bar'], 'SCRIPT_NAME'=>'/baz').should == '/baz/d/1/foo/bar'
153
+ end
154
+
155
+ it "Roda.path doesn't work with classes without blocks" do
156
+ proc{app.path(Class.new)}.should raise_error(Roda::RodaError)
157
+ end
158
+
159
+ it "Roda.path doesn't work with classes with paths or options" do
160
+ proc{app.path(Class.new, '/a'){}}.should raise_error(Roda::RodaError)
161
+ proc{app.path(Class.new, nil, :a=>1){}}.should raise_error(Roda::RodaError)
162
+ end
163
+
164
+ it "Roda.path doesn't work after freezing the app" do
165
+ app.freeze
166
+ proc{app.path(Class.new){|obj| ''}}.should raise_error
167
+ end
168
+ end
169
+
@@ -1,5 +1,10 @@
1
1
  require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
2
2
 
3
+ begin
4
+ require 'tilt/erb'
5
+ rescue LoadError
6
+ warn "tilt not installed, skipping render_each plugin test"
7
+ else
3
8
  describe "render_each plugin" do
4
9
  it "calls render with each argument, returning joined string with all results" do
5
10
  app(:bare) do
@@ -33,3 +38,4 @@ describe "render_each plugin" do
33
38
  body("/c").should == 'rbar41 rbar42 rbar43 '
34
39
  end
35
40
  end
41
+ end
@@ -107,6 +107,18 @@ describe "render plugin" do
107
107
  body.strip.should == "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
108
108
  end
109
109
 
110
+ it "locals overrides" do
111
+ app(:bare) do
112
+ plugin :render, :views=>"./spec/views", :locals=>{:title=>'Home', :b=>'B'}, :layout_opts=>{:template=>'multiple-layout', :locals=>{:title=>'Roda', :a=>'A'}}
113
+
114
+ route do |r|
115
+ view("multiple", :locals=>{:b=>"BB"}, :layout_opts=>{:locals=>{:a=>'AA'}})
116
+ end
117
+ end
118
+
119
+ body.strip.should == "Roda:AA::Home:BB"
120
+ end
121
+
110
122
  it ":layout=>true/false/string/hash/not-present respects plugin layout switch and template" do
111
123
  app(:bare) do
112
124
  plugin :render, :views=>"./spec/views", :layout_opts=>{:template=>'layout-yield', :locals=>{:title=>'a'}}
@@ -149,13 +161,20 @@ describe "render plugin" do
149
161
  body('/h').gsub("\n", '').should == "<title>Roda: a</title>bar"
150
162
 
151
163
  app.plugin :render, :layout=>nil
152
- body.gsub("\n", '').should == "<title>Alternative Layout: a</title>bar"
164
+ body.gsub("\n", '').should == "HeaderbarFooter"
153
165
  body('/a').gsub("\n", '').should == "bar"
154
166
  body('/f').gsub("\n", '').should == "bar"
155
167
  body('/s').gsub("\n", '').should == "<title>Roda: a</title>bar"
156
168
  body('/h').gsub("\n", '').should == "<title>Roda: a</title>bar"
157
169
 
158
170
  app.plugin :render, :layout=>false
171
+ body.gsub("\n", '').should == "HeaderbarFooter"
172
+ body('/a').gsub("\n", '').should == "bar"
173
+ body('/f').gsub("\n", '').should == "bar"
174
+ body('/s').gsub("\n", '').should == "<title>Roda: a</title>bar"
175
+ body('/h').gsub("\n", '').should == "<title>Roda: a</title>bar"
176
+
177
+ app.plugin :render, :layout_opts=>{:template=>'layout-alternative', :locals=>{:title=>'a'}}
159
178
  body.gsub("\n", '').should == "<title>Alternative Layout: a</title>bar"
160
179
  body('/a').gsub("\n", '').should == "bar"
161
180
  body('/f').gsub("\n", '').should == "bar"
@@ -163,6 +182,26 @@ describe "render plugin" do
163
182
  body('/h').gsub("\n", '').should == "<title>Roda: a</title>bar"
164
183
  end
165
184
 
185
+ it "app :root option affects :views default" do
186
+ app
187
+ app.plugin :render
188
+ app.render_opts[:views].should == File.join(Dir.pwd, 'views')
189
+
190
+ app.opts[:root] = '/foo'
191
+ app.plugin :render
192
+ app.render_opts[:views].should == '/foo/views'
193
+
194
+ app.opts[:root] = '/foo/bar'
195
+ app.plugin :render
196
+ app.render_opts[:views].should == '/foo/bar/views'
197
+
198
+ app.opts[:root] = nil
199
+ app.plugin :render
200
+ app.render_opts[:views].should == File.join(Dir.pwd, 'views')
201
+ app.plugin :render, :views=>'bar'
202
+ app.render_opts[:views].should == File.join(Dir.pwd, 'bar')
203
+ end
204
+
166
205
  it "inline layouts and inline views" do
167
206
  app(:render) do
168
207
  view({:inline=>'bar'}, :layout=>{:inline=>'Foo: <%= yield %>'})
@@ -83,6 +83,11 @@ describe "sinatra_helpers plugin" do
83
83
  header('Content-Length').should == '11'
84
84
  end
85
85
 
86
+ it 'supports #join' do
87
+ sin_app{body{'Hello World'}; nil}
88
+ req[2].join.should == 'Hello World'
89
+ end
90
+
86
91
  it 'takes a String, Array, or other object responding to #each' do
87
92
  sin_app{body 'Hello World'; nil}
88
93
  body.should == 'Hello World'
@@ -0,0 +1,30 @@
1
+ require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
2
+
3
+ describe "static plugin" do
4
+ it "adds support for serving static files" do
5
+ app(:bare) do
6
+ plugin :static, ['/about'], :root=>'spec/views'
7
+
8
+ route do
9
+ 'a'
10
+ end
11
+ end
12
+
13
+ body.should == 'a'
14
+ body('/about/_test.erb').should == File.read('spec/views/about/_test.erb')
15
+ end
16
+
17
+ it "respects the application's :root option" do
18
+ app(:bare) do
19
+ opts[:root] = File.expand_path('../../', __FILE__)
20
+ plugin :static, ['/about'], :root=>'views'
21
+
22
+ route do
23
+ 'a'
24
+ end
25
+ end
26
+
27
+ body.should == 'a'
28
+ body('/about/_test.erb').should == File.read('spec/views/about/_test.erb')
29
+ end
30
+ end
@@ -0,0 +1,117 @@
1
+ require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
2
+
3
+ begin
4
+ require 'tilt/erb'
5
+ rescue LoadError
6
+ warn "tilt not installed, skipping view_options plugin test"
7
+ else
8
+ describe "view_options plugin view subdirs" do
9
+ before do
10
+ app(:bare) do
11
+ plugin :render, :views=>"."
12
+ plugin :view_options
13
+
14
+ route do |r|
15
+ append_view_subdir 'spec'
16
+
17
+ r.on "home" do
18
+ set_view_subdir 'spec/views'
19
+ view("home", :locals=>{:name => "Agent Smith", :title => "Home"}, :layout_opts=>{:locals=>{:title=>"Home"}})
20
+ end
21
+
22
+ r.on "about" do
23
+ append_view_subdir 'views'
24
+ render("about", :locals=>{:title => "About Roda"})
25
+ end
26
+
27
+ r.on "path" do
28
+ render('spec/views/about', :locals=>{:title => "Path"}, :layout_opts=>{:locals=>{:title=>"Home"}})
29
+ end
30
+ end
31
+ end
32
+ end
33
+
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>"
36
+ end
37
+
38
+ it "should not use set subdir if template name contains a slash" do
39
+ body("/about").strip.should == "<h1>About Roda</h1>"
40
+ end
41
+
42
+ it "should not change behavior when subdir is not set" do
43
+ body("/path").strip.should == "<h1>Path</h1>"
44
+ end
45
+ end
46
+
47
+ describe "view_options plugin" do
48
+ it "should set view and layout options and locals to use" do
49
+ app(:view_options) do
50
+ set_view_options :views=>'spec/views'
51
+ set_view_locals :title=>'About Roda'
52
+ set_layout_options :views=>'spec/views', :template=>'layout-alternative'
53
+ set_layout_locals :title=>'Home'
54
+ view('about')
55
+ end
56
+
57
+ body.strip.should == "<title>Alternative Layout: Home</title>\n<h1>About Roda</h1>"
58
+ end
59
+
60
+ it "should merge multiple calls to set view and layout options and locals" do
61
+ app(:view_options) do
62
+ set_layout_options :views=>'spec/views', :template=>'multiple-layout', :ext=>'str'
63
+ set_view_options :views=>'spec/views', :ext=>'str'
64
+ set_layout_locals :title=>'About Roda'
65
+ set_view_locals :title=>'Home'
66
+
67
+ set_layout_options :ext=>'erb'
68
+ set_view_options :ext=>'erb'
69
+ set_layout_locals :a=>'A'
70
+ set_view_locals :b=>'B'
71
+
72
+ view('multiple')
73
+ end
74
+
75
+ body.strip.should == "About Roda:A::Home:B"
76
+ end
77
+
78
+ it "should have set_view_locals have more precedence than plugin options, but less than view/render method options" do
79
+ app(:bare) do
80
+ plugin :render, :views=>"./spec/views", :locals=>{:title=>'Home', :b=>'B'}, :layout_opts=>{:template=>'multiple-layout', :locals=>{:title=>'About Roda', :a=>'A'}}
81
+ plugin :view_options
82
+
83
+ route do |r|
84
+ r.is 'c' do
85
+ view(:multiple)
86
+ end
87
+
88
+ set_view_locals :b=>'BB'
89
+ set_layout_locals :a=>'AA'
90
+
91
+ r.on 'b' do
92
+ set_view_locals :title=>'About'
93
+ set_layout_locals :title=>'Roda'
94
+
95
+ r.is 'a' do
96
+ view(:multiple)
97
+ end
98
+
99
+ view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
100
+ end
101
+
102
+ r.is 'a' do
103
+ view(:multiple)
104
+ end
105
+
106
+ view("multiple", :locals=>{:b => "BBB"}, :layout_opts=>{:locals=>{:a=>'AAA'}})
107
+ end
108
+ end
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"
115
+ end
116
+ end
117
+ end
data/spec/spec_helper.rb CHANGED
@@ -80,7 +80,11 @@ class RSPEC_EXAMPLE_GROUP
80
80
  end
81
81
 
82
82
  def body(path='/', env={})
83
- req(path, env)[2].join
83
+ s = ''
84
+ b = req(path, env)[2]
85
+ b.each{|x| s << x}
86
+ b.close if b.respond_to?(:close)
87
+ s
84
88
  end
85
89
 
86
90
  def _app(&block)
@@ -0,0 +1 @@
1
+ <%= title %>:<%= a %>::<%= yield %>
@@ -0,0 +1 @@
1
+ <%= title %>:<%= b %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-13 00:00:00.000000000 Z
11
+ date: 2015-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -137,6 +137,7 @@ extra_rdoc_files:
137
137
  - doc/release_notes/1.2.0.txt
138
138
  - doc/release_notes/1.3.0.txt
139
139
  - doc/release_notes/2.0.0.txt
140
+ - doc/release_notes/2.1.0.txt
140
141
  files:
141
142
  - CHANGELOG
142
143
  - MIT-LICENSE
@@ -148,6 +149,7 @@ files:
148
149
  - doc/release_notes/1.2.0.txt
149
150
  - doc/release_notes/1.3.0.txt
150
151
  - doc/release_notes/2.0.0.txt
152
+ - doc/release_notes/2.1.0.txt
151
153
  - lib/roda.rb
152
154
  - lib/roda/plugins/_erubis_escaping.rb
153
155
  - lib/roda/plugins/all_verbs.rb
@@ -196,10 +198,12 @@ files:
196
198
  - lib/roda/plugins/render_each.rb
197
199
  - lib/roda/plugins/sinatra_helpers.rb
198
200
  - lib/roda/plugins/slash_path_empty.rb
201
+ - lib/roda/plugins/static.rb
199
202
  - lib/roda/plugins/static_path_info.rb
200
203
  - lib/roda/plugins/streaming.rb
201
204
  - lib/roda/plugins/symbol_matchers.rb
202
205
  - lib/roda/plugins/symbol_views.rb
206
+ - lib/roda/plugins/view_options.rb
203
207
  - lib/roda/plugins/view_subdirs.rb
204
208
  - lib/roda/version.rb
205
209
  - spec/assets/css/app.scss
@@ -259,11 +263,11 @@ files:
259
263
  - spec/plugin/render_spec.rb
260
264
  - spec/plugin/sinatra_helpers_spec.rb
261
265
  - spec/plugin/slash_path_empty_spec.rb
262
- - spec/plugin/static_path_info_spec.rb
266
+ - spec/plugin/static_spec.rb
263
267
  - spec/plugin/streaming_spec.rb
264
268
  - spec/plugin/symbol_matchers_spec.rb
265
269
  - spec/plugin/symbol_views_spec.rb
266
- - spec/plugin/view_subdirs_spec.rb
270
+ - spec/plugin/view_options_spec.rb
267
271
  - spec/plugin_spec.rb
268
272
  - spec/redirect_spec.rb
269
273
  - spec/request_spec.rb
@@ -281,6 +285,8 @@ files:
281
285
  - spec/views/layout-yield.erb
282
286
  - spec/views/layout.erb
283
287
  - spec/views/layout.str
288
+ - spec/views/multiple-layout.erb
289
+ - spec/views/multiple.erb
284
290
  homepage: http://roda.jeremyevans.net
285
291
  licenses:
286
292
  - MIT