sinatra_more 0.3.13 → 0.3.14

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.
data/README.rdoc CHANGED
@@ -49,6 +49,7 @@ Here is a small list of what sinatra_more contains:
49
49
  * Generic view and tag helpers (<tt>tag</tt>, <tt>content_tag</tt>, <tt>input_tag</tt>, ...)
50
50
  * Asset tag helpers (<tt>link_to</tt>, <tt>image_tag</tt>, <tt>javascript_include_tag</tt>, ...)
51
51
  * Full form helpers and builders support (<tt>form_tag</tt>, <tt>form_for</tt>, <tt>field_set_tag</tt>, <tt>text_field</tt>, ...)
52
+ * Full url named route support to avoid hardcoding url paths in sinatra (<tt>map</tt>, <tt>url_for</tt>)
52
53
  * Generally useful formatting extensions (<tt>relative_time_ago</tt>, <tt>js_escape_html</tt>, <tt>sanitize_html</tt>)
53
54
  * Simple 'mailer' support for sinatra (akin to <tt>ActionMailer</tt> but simpler and powered by <tt>pony</tt>)
54
55
  * Plug and play setup for the excellent Warden authentication system
@@ -81,6 +82,7 @@ different components based on which pieces are useful for your particular applic
81
82
  register SinatraMore::RenderPlugin
82
83
  register SinatraMore::WardenPlugin
83
84
  register SinatraMore::MailerPlugin
85
+ register SinatraMore::RoutingPlugin
84
86
  end
85
87
 
86
88
  This will then allow you to use the components that have been registered. A breakdown of components is below:
@@ -577,6 +579,84 @@ or perhaps we want to have a short body without the need for a template file:
577
579
  end
578
580
 
579
581
  See the wiki article for additional information: <http://wiki.github.com/nesquena/sinatra_more/mailerplugin>
582
+
583
+ == RoutingPlugin
584
+
585
+ This component provides Sinatra with an enhanced url routing system which enables named route aliases to be defined
586
+ and used throughout your application to refer to urls. The benefits of this is that instead of having to hard-code route urls
587
+ into every area of your application, now we can just define the urls in a single spot and then attach an alias
588
+ which can be used to refer to the url throughout the rest.
589
+
590
+ Let's take a look at how to define named route mappings:
591
+
592
+ # /app/routes/example.rb
593
+ require 'sinatra_more'
594
+
595
+ class RoutingDemo < Sinatra::Application
596
+ register SinatraMore::RoutingPlugin
597
+
598
+ # Define the named route mappings
599
+ map(:account).to("/the/accounts/:name/and/:id")
600
+ map(:accounts).to("/the/accounts/index")
601
+
602
+ # Configure the routes using the named alias
603
+ get(:account) { "name: params[:name] - id: params[:id]" }
604
+ get(:accounts) { "I am the body for the url /the/accounts/index" }
605
+ end
606
+
607
+ Notice we simply create a route alias using the <tt>map</tt> function and then pass in the corresponding url into the <tt>to</tt> method.
608
+ You can then define the routes using the named symbol representing the url. The route aliases can be accessed using <tt>url_for</tt>
609
+
610
+ url_for(:accounts)
611
+ url_for(:account, :id => 1, :name => 'first')
612
+
613
+ You can also refer to the url in views using <tt>url_for</tt>
614
+
615
+ # /app/views/index.erb
616
+ <p>Go to the <%= link_to 'accounts dashboard', url_for(:accounts) %> to view your accounts</p>
617
+ <p>Go to account for <%= link_to 'first account', url_for(:account, :id => 1, :name => 'first') %>
618
+
619
+ Simply invoking <tt>url_for(name, *parameters)</tt> will return the full mapped url for use in links or anywhere else
620
+ that the url might be required.
621
+
622
+ The routing system also supports url route configuration namespaces:
623
+
624
+ # /app/routes/example.rb
625
+ map(:admin, :show).to("/admin/:id/show")
626
+
627
+ namespace :admin do
628
+ get :show do
629
+ "admin show for #{params[:id]}"
630
+ end
631
+ end
632
+
633
+ You could also define the route aliases themselves using a namespace for convenience:
634
+
635
+ # /app/routes/example.rb
636
+ map :admin do |namespace|
637
+ namespace.map(:show).to("/admin/:id/show")
638
+ namespace.map(:destroy).to("/admin/:id/destroy")
639
+ end
640
+
641
+ namespace :admin do
642
+ get :show do
643
+ "admin show for #{params[:id]}"
644
+ end
645
+
646
+ get :destroy do
647
+ "admin destroy for #{params[:id]}"
648
+ end
649
+ end
650
+
651
+ You can then reference the urls using the same <tt>url_for</tt> method:
652
+
653
+ <%= link_to 'admin page', url_for(:admin, :show, :id => 25) %>
654
+ <%= link_to 'admin page', url_for(:admin, :update, :id => 25) %>
655
+ <%= link_to 'admin page', url_for(:admin, :show, :id => 25) %>
656
+
657
+ You can freely use both named route aliases and traditional Sinatra routes in the same application without conflict.
658
+
659
+ See the wiki article for additional information: <http://wiki.github.com/nesquena/sinatra_more/routingplugin>
580
660
 
581
661
  == Sinatra Generators
582
662
 
@@ -642,6 +722,7 @@ See the wiki article for additional information: <http://wiki.github.com/nesquen
642
722
  * Thanks to sbfaulkner for the <tt>sinatra-helpers</tt> code that I browsed through many times while starting this library.
643
723
  * Thanks to vestel for the excellent modified <tt>pony</tt> fork which in part powers the mailer_plugin (http://github.com/vestel/pony)
644
724
  * Thanks to focat and sinatra-content-for library (http://github.com/focat/sinatra-content-for) for a good content_for starting point
725
+ * Thanks to bcarlso for the snap sinatra library (http://github.com/bcarlso/snap) which was a starting point for named routes
645
726
  * Thanks to wycats and others for the awesome Thor gem which made creating the sinatra generator relatively painless
646
727
  * Thanks to wycats and others for the bundler gem which made bundling the required gems for an application easy
647
728
 
data/ROADMAP CHANGED
@@ -18,37 +18,9 @@ Framework structure:
18
18
  * sinatra-mailer (mail handling for sinatra applications) <= from MailerPlugin
19
19
  * sinatra-gen (easy generation of and for sinatra apps) <= from Generator
20
20
  * sinatra-admin (admin management dashboard for content) <= from Lipsiadmin (ported)
21
+ * sinatra-routing (sinatra route mapping system) <= from RoutingPlugin
21
22
  * sinatra-cache (page and fragment caching support)
22
- * sinatra-mapping (sinatra route mapping system)
23
23
 
24
- 'sinatra-mapping' Routing Concept:
25
-
26
- namespace :admin do
27
- get :show do
28
- ...
29
- end
30
- end
31
-
32
- get :accounts do
33
- ...
34
- end
35
-
36
- map(:admin, :show).to("/my-admin/:id/show")
37
- map(:accounts).to("/show-me-my/accounts")
38
-
39
- # or
40
-
41
- map :admin do |namespace|
42
- namespace.map(:show).to("/my-admin/:id/show")
43
- end
44
-
45
- # and to use
46
- link_to "Show Admin", admin_show_path(:id => 5)
47
- link_to "Accounts", accounts_path
48
- # or maybe
49
- link_to "Show Admin", url_for(:admin, :show, :id => 5)
50
- link_to "Accounts", url_for(:accounts)
51
-
52
24
  'sinatra-cache' Caching concept:
53
25
 
54
26
  # in models
@@ -75,4 +47,29 @@ Framework structure:
75
47
  # page
76
48
  get '/example', :cache => true do
77
49
  haml_template 'accounts/index'
78
- end
50
+ end
51
+
52
+ 'sinatra-routing' Routing Concept:
53
+
54
+ namespace :admin do
55
+ get :show do
56
+ ...
57
+ end
58
+ end
59
+
60
+ get :accounts do
61
+ ...
62
+ end
63
+
64
+ map(:admin, :show).to("/my-admin/:id/show")
65
+ map(:accounts).to("/show-me-my/accounts")
66
+
67
+ # or
68
+
69
+ map :admin do |namespace|
70
+ namespace.map(:show).to("/my-admin/:id/show")
71
+ end
72
+
73
+ # and to use
74
+ link_to "Show Admin", url_for(:admin, :show, :id => 5)
75
+ link_to "Accounts", url_for(:accounts)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.13
1
+ 0.3.14
@@ -6,6 +6,12 @@ class <%= @class_name %> < Sinatra::Application
6
6
  # Required middleware
7
7
  use Rack::Session::Cookie
8
8
  use Rack::Flash
9
+
10
+ # Includes all necessary sinatra_more helpers
11
+ register SinatraMore::MarkupPlugin
12
+ register SinatraMore::RenderPlugin
13
+ register SinatraMore::MailerPlugin
14
+ register SinatraMore::RoutingPlugin
9
15
 
10
16
  # Requires the initializer modules which configure specific components
11
17
  Dir[File.dirname(__FILE__) + '/initializers/*.rb'].each do |file|
@@ -23,10 +29,7 @@ class <%= @class_name %> < Sinatra::Application
23
29
  # Require all the folders and files necessary to run the application
24
30
  file_loading_paths.each { |load_path| Dir[root_path(load_path)].each { |file| require file } }
25
31
 
26
- # Includes all necessary sinatra_more helpers
27
- register SinatraMore::MarkupPlugin
28
- register SinatraMore::RenderPlugin
29
- register SinatraMore::MailerPlugin
32
+ # Require Warden plugin below to allow User to be loaded
30
33
  register SinatraMore::WardenPlugin
31
34
 
32
35
  # Required helpers
@@ -0,0 +1,25 @@
1
+ module SinatraMore
2
+ class NamedRoute
3
+ # Constructs the NamedRoute which accepts the application and
4
+ # the route alias names to register (i.e [:account] or [:admin, :show])
5
+ # NamedRoute.new(@app, :admin, :show)
6
+ def initialize(app, *names)
7
+ @app = app
8
+ @names = names.flatten
9
+ end
10
+
11
+ # Used to define the url mapping to the supplied alias
12
+ # NamedRoute.new(@app, :account).to('/account/path')
13
+ def to(path)
14
+ @app.named_paths[@names] = path
15
+ end
16
+
17
+ # Used to define the url mappings for child aliases within a namespace
18
+ # Invokes map on the application itself, appending the namespace to the route
19
+ # NamedRoute.new(@app, :admin).map(:show).to('/admin/show')
20
+ # is equivalent to NamedRoute.new(@app, :admin, :show).to('/admin/show')
21
+ def map(*args, &block)
22
+ @app.map(*args.unshift(@names), &block)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ module SinatraMore
2
+ module RoutingHelpers
3
+ # Used to retrieve the full url for a given named route alias from the named_paths data
4
+ # Accepts parameters which will be substituted into the url if necessary
5
+ # url_for(:accounts) => '/accounts'
6
+ # url_for(:account, :id => 5) => '/account/5'
7
+ # url_for(:admin, show, :id => 5, :name => "demo") => '/admin/path/5/demo'
8
+ def url_for(*names)
9
+ values = names.extract_options!
10
+ mapped_url = self.class.named_paths[names]
11
+ result_url = String.new(mapped_url)
12
+ result_url.scan(%r{/?(:\S+?)(?:/|$)}).each do |placeholder|
13
+ value_key = placeholder[0][1..-1].to_sym
14
+ result_url.gsub!(Regexp.new(placeholder[0]), values[value_key].to_s)
15
+ end
16
+ result_url
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/support_lite'
2
+ Dir[File.dirname(__FILE__) + '/routing_plugin/**/*.rb'].each {|file| load file }
3
+
4
+ module SinatraMore
5
+ module RoutingPlugin
6
+ def self.registered(app)
7
+ # Named paths stores the named route aliases mapping to the url
8
+ # i.e { [:account] => '/account/path', [:admin, :show] => '/admin/show/:id' }
9
+ app.set :named_paths, {}
10
+ app.helpers SinatraMore::RoutingHelpers
11
+
12
+ # map constructs a mapping between a named route and a specified alias
13
+ # the mapping url can contain url query parameters
14
+ # map(:accounts).to('/accounts/url')
15
+ # map(:admin, :show).to('/admin/show/:id')
16
+ # map(:admin) { |namespace| namespace.map(:show).to('/admin/show/:id') }
17
+ def map(*args, &block)
18
+ named_router = SinatraMore::NamedRoute.new(self, *args)
19
+ block_given? ? block.call(named_router) : named_router
20
+ end
21
+
22
+ # Used to define namespaced route configurations in order to group similar routes
23
+ # Class evals the routes but with the namespace assigned which will append to each route
24
+ # namespace(:admin) { get(:show) { "..." } }
25
+ def namespace(name, &block)
26
+ original, @_namespace = @_namespace, name
27
+ self.class_eval(&block)
28
+ @_namespace = original
29
+ end
30
+
31
+ # Hijacking route method in sinatra to replace a route alias (i.e :account) with the full url string mapping
32
+ # Supports namespaces by accessing the instance variable and appending this to the route alias name
33
+ # If the path is not a symbol, nothing is changed and the original route method is invoked
34
+ def route(verb, path, options={}, &block)
35
+ route_name = [@_namespace, path].flatten.compact
36
+ path = named_paths[route_name] if path.kind_of? Symbol
37
+ super verb, path, options, &block
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/sinatra_more.rb CHANGED
@@ -3,4 +3,5 @@ require 'sinatra/base'
3
3
  require File.join(File.dirname(__FILE__) + '/sinatra_more/markup_plugin')
4
4
  require File.join(File.dirname(__FILE__) + '/sinatra_more/render_plugin')
5
5
  require File.join(File.dirname(__FILE__) + '/sinatra_more/warden_plugin')
6
- require File.join(File.dirname(__FILE__) + '/sinatra_more/mailer_plugin')
6
+ require File.join(File.dirname(__FILE__) + '/sinatra_more/mailer_plugin')
7
+ require File.join(File.dirname(__FILE__) + '/sinatra_more/routing_plugin')
data/sinatra_more.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra_more}
8
- s.version = "0.3.13"
8
+ s.version = "0.3.14"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nathan Esquenazi"]
12
- s.date = %q{2009-11-12}
12
+ s.date = %q{2009-11-13}
13
13
  s.default_executable = %q{sinatra_gen}
14
14
  s.description = %q{Expands sinatra with standard helpers and tools to allow for complex applications}
15
15
  s.email = %q{nesquena@gmail.com}
@@ -84,6 +84,9 @@ Gem::Specification.new do |s|
84
84
  "lib/sinatra_more/markup_plugin/tag_helpers.rb",
85
85
  "lib/sinatra_more/render_plugin.rb",
86
86
  "lib/sinatra_more/render_plugin/render_helpers.rb",
87
+ "lib/sinatra_more/routing_plugin.rb",
88
+ "lib/sinatra_more/routing_plugin/named_route.rb",
89
+ "lib/sinatra_more/routing_plugin/routing_helpers.rb",
87
90
  "lib/sinatra_more/support_lite.rb",
88
91
  "lib/sinatra_more/warden_plugin.rb",
89
92
  "lib/sinatra_more/warden_plugin/warden_helpers.rb",
@@ -116,6 +119,8 @@ Gem::Specification.new do |s|
116
119
  "test/fixtures/render_app/views/template/_user.haml",
117
120
  "test/fixtures/render_app/views/template/haml_template.haml",
118
121
  "test/fixtures/render_app/views/template/some_template.haml",
122
+ "test/fixtures/routing_app/app.rb",
123
+ "test/fixtures/routing_app/views/index.haml",
119
124
  "test/fixtures/warden_app/app.rb",
120
125
  "test/fixtures/warden_app/views/dashboard.haml",
121
126
  "test/generators/test_skeleton_generator.rb",
@@ -130,6 +135,7 @@ Gem::Specification.new do |s|
130
135
  "test/markup_plugin/test_tag_helpers.rb",
131
136
  "test/test_mailer_plugin.rb",
132
137
  "test/test_render_plugin.rb",
138
+ "test/test_routing_plugin.rb",
133
139
  "test/test_warden_plugin.rb",
134
140
  "vendor/pony/lib/pony.rb",
135
141
  "vendor/pony/spec/base.rb",
@@ -145,6 +151,7 @@ Gem::Specification.new do |s|
145
151
  "test/fixtures/mailer_app/app.rb",
146
152
  "test/fixtures/markup_app/app.rb",
147
153
  "test/fixtures/render_app/app.rb",
154
+ "test/fixtures/routing_app/app.rb",
148
155
  "test/fixtures/warden_app/app.rb",
149
156
  "test/generators/test_skeleton_generator.rb",
150
157
  "test/helper.rb",
@@ -158,6 +165,7 @@ Gem::Specification.new do |s|
158
165
  "test/markup_plugin/test_tag_helpers.rb",
159
166
  "test/test_mailer_plugin.rb",
160
167
  "test/test_render_plugin.rb",
168
+ "test/test_routing_plugin.rb",
161
169
  "test/test_warden_plugin.rb"
162
170
  ]
163
171
 
@@ -0,0 +1,44 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra_more'
3
+ require 'haml'
4
+
5
+ class RoutingDemo < Sinatra::Base
6
+ register SinatraMore::RoutingPlugin
7
+
8
+ configure do
9
+ set :root, File.dirname(__FILE__)
10
+ end
11
+
12
+ map(:admin, :show).to("/admin/:id/show")
13
+ map :admin do |namespace|
14
+ namespace.map(:update).to("/admin/:id/update/:name")
15
+ namespace.map(:destroy).to("/admin/:id/destroy")
16
+ end
17
+ map(:account).to("/the/accounts/:name/path/:id/end")
18
+ map(:accounts).to("/the/accounts/index/?")
19
+
20
+ namespace :admin do
21
+ get :show do
22
+ "<p>admin show for id #{params[:id]}</p>"
23
+ end
24
+
25
+ get :update do
26
+ "<p>updated admin with id #{params[:id]} and name #{params[:name]}</p>"
27
+ end
28
+
29
+ get :destroy do
30
+ "<p>destroy admin with id #{params[:id]}</p>"
31
+ end
32
+ end
33
+ get :account do
34
+ "<h1>the account url for #{params[:name]} and id #{params[:id]}</h1>"
35
+ end
36
+
37
+ get :accounts do
38
+ "<h1>the accounts index</h1>"
39
+ end
40
+
41
+ get '/links' do
42
+ haml :index
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ %p.admin_url= url_for(:admin, :show, :id => 25)
2
+ %p.admin_url2= url_for(:admin, :update, :id => 10, :name => "test")
3
+ %p.admin_url3= url_for(:admin, :destroy, :id => 12)
4
+ %p.account_url= url_for(:account, :name => 'foobar', :id => 10)
5
+ %p.accounts_index=url_for(:accounts)
@@ -0,0 +1,56 @@
1
+ require 'helper'
2
+ require 'fixtures/routing_app/app'
3
+
4
+ class TestRoutingPlugin < Test::Unit::TestCase
5
+ def app
6
+ RoutingDemo.tap { |app| app.set :environment, :test }
7
+ end
8
+
9
+ context 'for links list displaying routes' do
10
+ setup { visit '/links' }
11
+ should 'display account route links' do
12
+ assert_have_selector :p, :class => 'account_url', :content => '/the/accounts/foobar/path/10/end'
13
+ assert_have_selector :p, :class => 'accounts_index', :content => '/the/accounts/index'
14
+ end
15
+ should "display admin route links" do
16
+ assert_have_selector :p, :class => 'admin_url', :content => '/admin/25/show'
17
+ assert_have_selector :p, :class => 'admin_url2', :content => '/admin/10/update/test'
18
+ assert_have_selector :p, :class => 'admin_url3', :content => '/admin/12/destroy'
19
+ end
20
+ end
21
+
22
+ context 'for no namespaced account route' do
23
+ setup { visit '/the/accounts/demo/path/5/end'}
24
+ should "return proper account text" do
25
+ assert_have_selector :h1, :content => "the account url for demo and id 5"
26
+ end
27
+ end
28
+
29
+ context 'for no namespaced accounts index route' do
30
+ setup { visit '/the/accounts/index/'}
31
+ should "return proper account text" do
32
+ assert_have_selector :h1, :content => "the accounts index"
33
+ end
34
+ end
35
+
36
+ context 'for admin show url' do
37
+ setup { visit '/admin/50/show' }
38
+ should "return proper admin test" do
39
+ assert_have_selector :p, :content => "admin show for id 50"
40
+ end
41
+ end
42
+
43
+ context 'for admin update url' do
44
+ setup { visit '/admin/15/update/demo' }
45
+ should "return proper update text" do
46
+ assert_have_selector :p, :content => "updated admin with id 15 and name demo"
47
+ end
48
+ end
49
+
50
+ context 'for admin destroy url' do
51
+ setup { visit '/admin/60/destroy' }
52
+ should "return proper destroy text" do
53
+ assert_have_selector :p, :content => "destroy admin with id 60"
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra_more
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Esquenazi
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-12 00:00:00 -08:00
12
+ date: 2009-11-13 00:00:00 -08:00
13
13
  default_executable: sinatra_gen
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -187,6 +187,9 @@ files:
187
187
  - lib/sinatra_more/markup_plugin/tag_helpers.rb
188
188
  - lib/sinatra_more/render_plugin.rb
189
189
  - lib/sinatra_more/render_plugin/render_helpers.rb
190
+ - lib/sinatra_more/routing_plugin.rb
191
+ - lib/sinatra_more/routing_plugin/named_route.rb
192
+ - lib/sinatra_more/routing_plugin/routing_helpers.rb
190
193
  - lib/sinatra_more/support_lite.rb
191
194
  - lib/sinatra_more/warden_plugin.rb
192
195
  - lib/sinatra_more/warden_plugin/warden_helpers.rb
@@ -219,6 +222,8 @@ files:
219
222
  - test/fixtures/render_app/views/template/_user.haml
220
223
  - test/fixtures/render_app/views/template/haml_template.haml
221
224
  - test/fixtures/render_app/views/template/some_template.haml
225
+ - test/fixtures/routing_app/app.rb
226
+ - test/fixtures/routing_app/views/index.haml
222
227
  - test/fixtures/warden_app/app.rb
223
228
  - test/fixtures/warden_app/views/dashboard.haml
224
229
  - test/generators/test_skeleton_generator.rb
@@ -233,6 +238,7 @@ files:
233
238
  - test/markup_plugin/test_tag_helpers.rb
234
239
  - test/test_mailer_plugin.rb
235
240
  - test/test_render_plugin.rb
241
+ - test/test_routing_plugin.rb
236
242
  - test/test_warden_plugin.rb
237
243
  - vendor/pony/lib/pony.rb
238
244
  - vendor/pony/spec/base.rb
@@ -270,6 +276,7 @@ test_files:
270
276
  - test/fixtures/mailer_app/app.rb
271
277
  - test/fixtures/markup_app/app.rb
272
278
  - test/fixtures/render_app/app.rb
279
+ - test/fixtures/routing_app/app.rb
273
280
  - test/fixtures/warden_app/app.rb
274
281
  - test/generators/test_skeleton_generator.rb
275
282
  - test/helper.rb
@@ -283,4 +290,5 @@ test_files:
283
290
  - test/markup_plugin/test_tag_helpers.rb
284
291
  - test/test_mailer_plugin.rb
285
292
  - test/test_render_plugin.rb
293
+ - test/test_routing_plugin.rb
286
294
  - test/test_warden_plugin.rb