high_voltage 1.2.0 → 1.2.1
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/.travis.yml +3 -3
- data/Gemfile.lock +1 -1
- data/MIT-LICENSE +1 -1
- data/README.md +83 -16
- data/app/controllers/high_voltage/pages_controller.rb +11 -18
- data/config/routes.rb +3 -2
- data/lib/high_voltage.rb +12 -2
- data/lib/high_voltage/constraints/root_route.rb +24 -0
- data/lib/high_voltage/engine.rb +0 -2
- data/lib/high_voltage/page_finder.rb +37 -0
- data/lib/high_voltage/route_drawers/default.rb +15 -0
- data/lib/high_voltage/route_drawers/root.rb +16 -0
- data/lib/high_voltage/version.rb +1 -1
- data/spec/constraints/root_route_spec.rb +21 -0
- data/spec/controllers/alternative_finder_controller_spec.rb +12 -0
- data/spec/controllers/pages_controller_spec.rb +56 -40
- data/spec/controllers/subclassed_pages_controller_spec.rb +19 -20
- data/spec/dummy/app/controllers/alternative_finder_controller.rb +14 -0
- data/spec/dummy/app/controllers/subclassed_pages_controller.rb +0 -4
- data/spec/dummy/app/views/pages/also_dir/also_nested.html.erb +1 -0
- data/spec/dummy/app/views/pages/also_exists.html.erb +1 -0
- data/spec/dummy/app/views/pages/also_exists_but_references_nonexistent_partial.html.erb +2 -0
- data/spec/dummy/app/views/pages/rot13.html.erb +1 -0
- data/spec/dummy/config/application.rb +0 -1
- data/spec/dummy/config/environments/test.rb +0 -5
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/high_voltage/page_finder_spec.rb +52 -0
- data/spec/high_voltage_spec.rb +2 -2
- data/spec/integration/navigation_spec.rb +3 -3
- data/spec/routing/routes_spec.rb +114 -32
- data/spec/spec_helper.rb +4 -16
- metadata +70 -5
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# High Voltage [](http://travis-ci.org/thoughtbot/high_voltage)
|
2
2
|
|
3
3
|
Rails engine for static pages.
|
4
4
|
|
@@ -57,26 +57,59 @@ In that case, you'd need an app/views/pages/home.html.erb file.
|
|
57
57
|
|
58
58
|
Generally speaking, you need to route to the 'show' action with an :id param of the view filename.
|
59
59
|
|
60
|
-
High Voltage will generate a named route method of `page_path` which you can use, as well. If you
|
61
|
-
want to generate a named route (with the :as routing option) for some route which will be handled
|
62
|
-
by High Voltage, make sure not to use :page as the name, because that will conflict with the named
|
63
|
-
route generated by High Voltage itself.
|
60
|
+
High Voltage will generate a named route method of `page_path` which you can use, as well. If you
|
61
|
+
want to generate a named route (with the :as routing option) for some route which will be handled
|
62
|
+
by High Voltage, make sure not to use :page as the name, because that will conflict with the named
|
63
|
+
route generated by High Voltage itself.
|
64
|
+
|
65
|
+
For example, this will work for top-level routes (we will
|
64
66
|
get a named route called `static_path` which does not conflict with the generated `page_path` method):
|
65
67
|
|
66
68
|
match '/:id' => 'high_voltage/pages#show', :as => :static, :via => :get
|
67
69
|
|
70
|
+
#### Specifying a root path
|
71
|
+
|
68
72
|
You can route the root url to a high voltage page like this:
|
69
73
|
|
70
74
|
root :to => 'high_voltage/pages#show', :id => 'home'
|
71
75
|
|
72
76
|
Which will render a homepage from app/views/pages/home.html.erb
|
73
77
|
|
78
|
+
#### Enabling root domain routes
|
79
|
+
|
80
|
+
You can remove the directory `pages` from the URL path and serve up routes from
|
81
|
+
the root of the domain path:
|
82
|
+
|
83
|
+
http://www.example.com/about
|
84
|
+
http://www.example.com/company
|
85
|
+
|
86
|
+
Would look for corresponding files:
|
87
|
+
|
88
|
+
app/views/pages/about.html.erb
|
89
|
+
app/views/pages/company.html.erb
|
90
|
+
|
91
|
+
This is accomplished by changing the `HighVoltage.route_drawer` to `HighVoltage::RouteDrawers::Root`
|
92
|
+
|
93
|
+
# config/initializers/high_voltage.rb
|
94
|
+
HighVoltage.route_drawer = HighVoltage::RouteDrawers::Root
|
95
|
+
|
96
|
+
Note: This is not a catchall route. It will check the `HighVoltage.content_path`
|
97
|
+
(by default this is `app/views/pages`) and validate the view exists.
|
98
|
+
|
99
|
+
#### Disabling routes
|
100
|
+
|
101
|
+
The default routes can be completely removed by changing the
|
102
|
+
`HighVoltage.routes` to `false`
|
103
|
+
|
104
|
+
# config/initializers/high_voltage.rb
|
105
|
+
HighVoltage.routes = false
|
106
|
+
|
74
107
|
Customize
|
75
108
|
--------
|
76
109
|
|
77
110
|
High Voltage uses a default path and folder of 'pages', i.e. 'url.com/pages/contact' , 'app/views/pages'
|
78
111
|
|
79
|
-
You can change this in an initializer:
|
112
|
+
You can change this in an initializer:
|
80
113
|
|
81
114
|
HighVoltage.content_path = "site/"
|
82
115
|
|
@@ -115,25 +148,58 @@ Then modify it to subclass from High Voltage, adding whatever you need:
|
|
115
148
|
end
|
116
149
|
end
|
117
150
|
|
151
|
+
Custom finding
|
152
|
+
--------------
|
153
|
+
|
154
|
+
You can further control the algorithm used to find pages by overriding
|
155
|
+
the `page_finder_factory` method:
|
156
|
+
|
157
|
+
class PagesController < HighVoltage::PagesController
|
158
|
+
private
|
159
|
+
|
160
|
+
def page_finder_factory
|
161
|
+
Rot13PageFinder
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
The easiest thing is to subclass `HighVoltage::PageFinder`, which
|
166
|
+
provides you with `page_id`:
|
167
|
+
|
168
|
+
class Rot13PageFinder < HighVoltage::PageFinder
|
169
|
+
def find
|
170
|
+
paths = super.split('/')
|
171
|
+
directory = paths[0..-2]
|
172
|
+
filename = paths[-1].tr('a-z','n-za-m')
|
173
|
+
|
174
|
+
File.join(*directory, filename)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
Use this to create a custom file mapping, clean filenames for your file
|
179
|
+
system, A/B test, and so on.
|
180
|
+
|
118
181
|
Testing
|
119
182
|
-------
|
120
183
|
|
121
|
-
|
122
|
-
|
123
|
-
class PagesControllerTest < ActionController::TestCase
|
124
|
-
tests PagesController
|
184
|
+
You can test your static pages using [RSpec](https://github.com/rspec/rspec-rails)
|
185
|
+
and [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers):
|
125
186
|
|
187
|
+
# spec/controllers/pages_controller_spec.rb
|
188
|
+
describe PagesController, '#show' do
|
126
189
|
%w(earn_money screencast about contact).each do |page|
|
127
|
-
context
|
128
|
-
|
190
|
+
context 'on GET to /pages/#{page}' do
|
191
|
+
before do
|
192
|
+
get :show, :id => page
|
193
|
+
end
|
129
194
|
|
130
|
-
|
131
|
-
|
195
|
+
it { should respond_with(:success) }
|
196
|
+
it { should render_template(page) }
|
132
197
|
end
|
133
198
|
end
|
134
199
|
end
|
135
200
|
|
136
|
-
If you're not using a custom PagesController be sure to test
|
201
|
+
If you're not using a custom PagesController be sure to test
|
202
|
+
`HighVoltage::PagesController` instead.
|
137
203
|
|
138
204
|
Enjoy!
|
139
205
|
|
@@ -156,4 +222,5 @@ The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
|
156
222
|
License
|
157
223
|
-------
|
158
224
|
|
159
|
-
High Voltage is Copyright © 2009-
|
225
|
+
High Voltage is Copyright © 2009-2012 thoughtbot. It is free software, and may
|
226
|
+
be redistributed under the terms specified in the MIT-LICENSE file.
|
@@ -1,11 +1,9 @@
|
|
1
1
|
class HighVoltage::PagesController < ApplicationController
|
2
|
-
VALID_CHARACTERS = "a-zA-Z0-9~!@$%^&*()#`_+-=<>\"{}|[];',?".freeze
|
3
|
-
|
4
2
|
unloadable
|
5
3
|
layout Proc.new { |_| HighVoltage.layout }
|
6
4
|
|
7
5
|
rescue_from ActionView::MissingTemplate do |exception|
|
8
|
-
if exception.message =~ %r{Missing template #{content_path}}
|
6
|
+
if exception.message =~ %r{Missing template #{page_finder.content_path}}
|
9
7
|
raise ActionController::RoutingError, "No such page: #{params[:id]}"
|
10
8
|
else
|
11
9
|
raise exception
|
@@ -16,22 +14,17 @@ class HighVoltage::PagesController < ApplicationController
|
|
16
14
|
render :template => current_page
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
def current_page
|
22
|
-
"#{content_path}#{clean_path}"
|
23
|
-
end
|
17
|
+
private
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
19
|
+
def current_page
|
20
|
+
page_finder.find
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
def page_finder
|
24
|
+
page_finder_factory.new(params[:id])
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
|
27
|
+
def page_finder_factory
|
28
|
+
HighVoltage::PageFinder
|
29
|
+
end
|
37
30
|
end
|
data/config/routes.rb
CHANGED
data/lib/high_voltage.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
require 'high_voltage/version'
|
2
|
+
require 'high_voltage/constraints/root_route'
|
3
|
+
require 'high_voltage/page_finder'
|
4
|
+
require 'high_voltage/route_drawers/default'
|
5
|
+
require 'high_voltage/route_drawers/root'
|
2
6
|
|
3
7
|
module HighVoltage
|
4
8
|
mattr_accessor :layout
|
5
|
-
@@layout =
|
9
|
+
@@layout = 'application'
|
6
10
|
|
7
11
|
mattr_accessor :content_path
|
8
|
-
@@content_path =
|
12
|
+
@@content_path = 'pages/'
|
13
|
+
|
14
|
+
mattr_accessor :route_drawer
|
15
|
+
@@route_drawer = HighVoltage::RouteDrawers::Default
|
16
|
+
|
17
|
+
mattr_accessor :routes
|
18
|
+
@@routes = true
|
9
19
|
|
10
20
|
def self.setup
|
11
21
|
yield self
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HighVoltage
|
2
|
+
module Constraints
|
3
|
+
# Routing constraint to validate request.path has a corresponding view
|
4
|
+
class RootRoute
|
5
|
+
VIEW_EXTENSIONS = 'html.erb,html.haml,html'
|
6
|
+
|
7
|
+
def self.matches?(request)
|
8
|
+
pattern = file_pattern(request.path)
|
9
|
+
|
10
|
+
Dir.glob(pattern).any?
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def self.file_pattern(page_id)
|
16
|
+
"#{content_path}#{page_id}.{#{VIEW_EXTENSIONS}}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.content_path
|
20
|
+
Rails.root.join('app', 'views', HighVoltage.content_path).to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/high_voltage/engine.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
module HighVoltage
|
2
|
+
# A command for finding pages by id. This encapsulates the concepts of
|
3
|
+
# mapping page names to file names.
|
4
|
+
class PageFinder
|
5
|
+
VALID_CHARACTERS = "a-zA-Z0-9~!@$%^&*()#`_+-=<>\"{}|[];',?".freeze
|
6
|
+
|
7
|
+
def initialize(page_id)
|
8
|
+
@page_id = page_id
|
9
|
+
end
|
10
|
+
|
11
|
+
# Produce a template path to the page, in a format understood by
|
12
|
+
# `render :template => find`
|
13
|
+
def find
|
14
|
+
"#{content_path}#{clean_path}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def content_path
|
18
|
+
HighVoltage.content_path
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
# The raw page id passed in by the user
|
24
|
+
attr_reader :page_id
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def clean_path
|
29
|
+
path = Pathname.new("/#{clean_id}")
|
30
|
+
path.cleanpath.to_s[1..-1]
|
31
|
+
end
|
32
|
+
|
33
|
+
def clean_id
|
34
|
+
@page_id.tr("^#{VALID_CHARACTERS}", '')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module HighVoltage
|
2
|
+
module RouteDrawers
|
3
|
+
# Matches routes in the HighVoltage.content_path directory. By default this looks
|
4
|
+
# for /pages/id. e.g. http://www.example.com/pages/about_us
|
5
|
+
class Default
|
6
|
+
def self.match_attributes
|
7
|
+
{
|
8
|
+
"/#{HighVoltage.content_path}*id" => 'high_voltage/pages#show',
|
9
|
+
:as => :page,
|
10
|
+
:format => false
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module HighVoltage
|
2
|
+
module RouteDrawers
|
3
|
+
# Matches routes from root of the domain e.g. http://www.example.com/about_us
|
4
|
+
# Uses HighVoltage::Constraints::RootRoute to validate view exists.
|
5
|
+
class Root
|
6
|
+
def self.match_attributes
|
7
|
+
{
|
8
|
+
"/*id" => 'high_voltage/pages#show',
|
9
|
+
:as => :page,
|
10
|
+
:format => false,
|
11
|
+
:constraints => HighVoltage::Constraints::RootRoute
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/high_voltage/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HighVoltage::Constraints::RootRoute, '.matches?' do
|
4
|
+
context 'view file exists' do
|
5
|
+
it 'should return true' do
|
6
|
+
request = stub(:path => 'index')
|
7
|
+
Dir.stub!(:glob).and_return(['about.html.erb'])
|
8
|
+
|
9
|
+
HighVoltage::Constraints::RootRoute.matches?(request).should be_true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'view file does not exist' do
|
14
|
+
it 'should return false' do
|
15
|
+
request = stub(:path => 'index')
|
16
|
+
File.stub!(:glob).and_return([])
|
17
|
+
|
18
|
+
HighVoltage::Constraints::RootRoute.matches?(request).should be_false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AlternativeFinderController do
|
4
|
+
render_views
|
5
|
+
|
6
|
+
it 'renders the file from the alternative directory' do
|
7
|
+
get :show, :id => 'ebg13'
|
8
|
+
|
9
|
+
response.should be_success
|
10
|
+
response.should render_template('rot13')
|
11
|
+
end
|
12
|
+
end
|
@@ -1,112 +1,128 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
|
3
2
|
require 'spec_helper'
|
4
3
|
|
5
4
|
describe HighVoltage::PagesController do
|
6
|
-
|
7
5
|
render_views
|
8
6
|
|
9
|
-
context
|
10
|
-
|
11
|
-
describe "on GET to /pages/exists" do
|
7
|
+
context 'using default configuration' do
|
8
|
+
describe 'on GET to /pages/exists' do
|
12
9
|
before { get :show, :id => 'exists' }
|
13
10
|
|
14
|
-
it
|
11
|
+
it 'should respond with success and render template' do
|
15
12
|
response.should be_success
|
16
13
|
response.should render_template('exists')
|
17
14
|
end
|
18
15
|
|
19
|
-
it
|
20
|
-
response.should render_template(
|
16
|
+
it 'should use the default layout used by ApplicationController' do
|
17
|
+
response.should render_template('layouts/application')
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
24
|
-
describe
|
21
|
+
describe 'on GET to /pages/dir/nested' do
|
25
22
|
before { get :show, :id => 'dir/nested' }
|
26
23
|
|
27
|
-
it
|
24
|
+
it 'should respond with success and render template' do
|
28
25
|
response.should be_success
|
29
26
|
response.should render_template('pages/dir/nested')
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
33
|
-
it
|
34
|
-
lambda {
|
30
|
+
it 'should raise a routing error for an invalid page' do
|
31
|
+
lambda {
|
32
|
+
get :show,
|
33
|
+
:id => 'invalid'
|
34
|
+
}.should raise_error(ActionController::RoutingError)
|
35
35
|
end
|
36
36
|
|
37
|
-
it
|
38
|
-
lambda {
|
37
|
+
it 'should raise a routing error for a page in another directory' do
|
38
|
+
lambda {
|
39
|
+
get :show,
|
40
|
+
:id => '../other/wrong'
|
41
|
+
}.should raise_error(ActionController::RoutingError)
|
39
42
|
end
|
40
43
|
|
41
|
-
it
|
42
|
-
lambda {
|
44
|
+
it 'should raise missing template error for valid page with invalid partial' do
|
45
|
+
lambda {
|
46
|
+
get :show,
|
47
|
+
:id => 'exists_but_references_nonexistent_partial'
|
48
|
+
}.should raise_error(ActionView::MissingTemplate)
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
46
|
-
context
|
52
|
+
context 'using custom layout' do
|
47
53
|
before(:all) do
|
48
54
|
@original_layout = HighVoltage.layout
|
49
|
-
HighVoltage.layout =
|
55
|
+
HighVoltage.layout = 'alternate'
|
50
56
|
end
|
51
57
|
|
52
58
|
after(:all) do
|
53
59
|
HighVoltage.layout = @original_layout
|
54
60
|
end
|
55
61
|
|
56
|
-
describe
|
57
|
-
before { get :show, :id =>
|
58
|
-
|
59
|
-
it
|
60
|
-
response.should_not render_template(
|
61
|
-
response.should render_template(
|
62
|
+
describe 'on GET to /pages/exists' do
|
63
|
+
before { get :show, :id => 'exists' }
|
64
|
+
|
65
|
+
it 'should use the custom configured layout' do
|
66
|
+
response.should_not render_template('layouts/application')
|
67
|
+
response.should render_template('layouts/alternate')
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
66
|
-
context
|
72
|
+
context 'using custom content path' do
|
67
73
|
before(:all) do
|
68
74
|
@original_content_path = HighVoltage.content_path
|
69
|
-
HighVoltage.content_path =
|
75
|
+
HighVoltage.content_path = 'other_pages/'
|
70
76
|
end
|
71
77
|
|
72
78
|
after(:all) do
|
73
79
|
HighVoltage.content_path = @original_content_path
|
74
80
|
end
|
75
81
|
|
76
|
-
describe
|
82
|
+
describe 'on GET to /other_pages/also_exists' do
|
77
83
|
before { get :show, :id => 'also_exists' }
|
78
84
|
|
79
|
-
it
|
85
|
+
it 'should respond with success and render template' do
|
80
86
|
response.should be_success
|
81
87
|
response.should render_template('other_pages/also_exists')
|
82
88
|
end
|
83
89
|
end
|
84
90
|
|
85
|
-
describe
|
91
|
+
describe 'on GET to /other_pages/also_dir/nested' do
|
86
92
|
before { get :show, :id => 'also_dir/also_nested' }
|
87
93
|
|
88
|
-
it
|
94
|
+
it 'should respond with success and render template' do
|
89
95
|
response.should be_success
|
90
96
|
response.should render_template('other_pages/also_dir/also_nested')
|
91
97
|
end
|
92
98
|
end
|
93
99
|
|
94
|
-
it
|
95
|
-
lambda {
|
100
|
+
it 'should raise a routing error for an invalid page' do
|
101
|
+
lambda {
|
102
|
+
get :show,
|
103
|
+
:id => 'also_invalid'
|
104
|
+
}.should raise_error(ActionController::RoutingError)
|
96
105
|
end
|
97
106
|
|
98
|
-
it
|
99
|
-
lambda {
|
107
|
+
it 'should raise a routing error for a page in another directory' do
|
108
|
+
lambda {
|
109
|
+
get :show,
|
110
|
+
:id => '../other/wrong'
|
111
|
+
}.should raise_error(ActionController::RoutingError)
|
100
112
|
end
|
101
113
|
|
102
|
-
it
|
103
|
-
lambda {
|
114
|
+
it 'should raise a routing error for a page in another directory when using a Unicode exploit' do
|
115
|
+
lambda {
|
116
|
+
get :show,
|
117
|
+
:id => '/\\../other/wrong'
|
118
|
+
}.should raise_error(ActionController::RoutingError)
|
104
119
|
end
|
105
120
|
|
106
|
-
it
|
107
|
-
lambda {
|
121
|
+
it 'should raise missing template error for valid page with invalid partial' do
|
122
|
+
lambda {
|
123
|
+
get :show,
|
124
|
+
:id => 'also_exists_but_references_nonexistent_partial'
|
125
|
+
}.should raise_error(ActionView::MissingTemplate)
|
108
126
|
end
|
109
127
|
end
|
110
|
-
|
111
|
-
|
112
128
|
end
|
@@ -1,41 +1,40 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SubclassedPagesController do
|
4
|
-
|
5
4
|
render_views
|
6
5
|
|
7
|
-
describe
|
6
|
+
describe 'on GET to /subclassed_pages/also_exists' do
|
8
7
|
before { get :show, :id => 'also_exists' }
|
9
8
|
|
10
|
-
it
|
9
|
+
it 'should respond with success and render template' do
|
11
10
|
response.should be_success
|
12
11
|
response.should render_template('also_exists')
|
13
12
|
end
|
14
13
|
|
15
|
-
it
|
16
|
-
response.should_not render_template(
|
14
|
+
it 'should use the custom configured layout' do
|
15
|
+
response.should_not render_template('layouts/application')
|
17
16
|
response.should render_template('layouts/alternate')
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
response.should render_template('other_pages/also_dir/also_nested')
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should raise a routing error for an invalid page" do
|
31
|
-
lambda { get :show, :id => "invalid" }.should raise_error(ActionController::RoutingError)
|
20
|
+
it 'should raise a routing error for an invalid page' do
|
21
|
+
lambda {
|
22
|
+
get :show,
|
23
|
+
:id => 'invalid'
|
24
|
+
}.should raise_error(ActionController::RoutingError)
|
32
25
|
end
|
33
26
|
|
34
|
-
it
|
35
|
-
lambda {
|
27
|
+
it 'should raise a routing error for a page in another directory' do
|
28
|
+
lambda {
|
29
|
+
get :show,
|
30
|
+
:id => '../other/wrong'
|
31
|
+
}.should raise_error(ActionController::RoutingError)
|
36
32
|
end
|
37
33
|
|
38
|
-
it
|
39
|
-
lambda {
|
34
|
+
it 'should raise missing template error for valid page with invalid partial' do
|
35
|
+
lambda {
|
36
|
+
get :show,
|
37
|
+
:id => 'also_exists_but_references_nonexistent_partial'
|
38
|
+
}.should raise_error(ActionView::MissingTemplate)
|
40
39
|
end
|
41
40
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AlternativeFinderController < HighVoltage::PagesController
|
2
|
+
private
|
3
|
+
|
4
|
+
def page_finder_factory
|
5
|
+
Rot13PageFinder
|
6
|
+
end
|
7
|
+
|
8
|
+
class Rot13PageFinder < HighVoltage::PageFinder
|
9
|
+
def find
|
10
|
+
paths = super.split('/')
|
11
|
+
"#{paths[0..-2].join('/')}/#{paths[-1].tr('a-z','n-za-m')}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
hello <%= 'world' %> from a nested dir
|
@@ -0,0 +1 @@
|
|
1
|
+
hello <%= 'world' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
alternative
|
@@ -20,11 +20,6 @@ Dummy::Application.configure do
|
|
20
20
|
# Disable request forgery protection in test environment
|
21
21
|
config.action_controller.allow_forgery_protection = false
|
22
22
|
|
23
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
24
|
-
# The :test delivery method accumulates sent emails in the
|
25
|
-
# ActionMailer::Base.deliveries array.
|
26
|
-
config.action_mailer.delivery_method = :test
|
27
|
-
|
28
23
|
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
29
24
|
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
30
25
|
# like if you have constraints or database-specific column types
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HighVoltage::PageFinder do
|
4
|
+
it 'produces the name of an existing template' do
|
5
|
+
find('existing').should eq 'pages/existing'
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'produces the name of a nested template' do
|
9
|
+
find('dir/nested').should eq 'pages/dir/nested'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'uses a custom content path' do
|
13
|
+
with_content_path('other_pages/') do
|
14
|
+
find('also_exists').should eq 'other_pages/also_exists'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'exposes the content path' do
|
19
|
+
with_content_path('another_thing/') do
|
20
|
+
page_finder.content_path.should eq 'another_thing/'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'provides the page_id' do
|
25
|
+
subclass = Class.new(HighVoltage::PageFinder) do
|
26
|
+
def page_name
|
27
|
+
"the page is #{page_id}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
subclass.new('sweet page').page_name.should eq 'the page is sweet page'
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def find(page_id)
|
37
|
+
page_finder(page_id).find
|
38
|
+
end
|
39
|
+
|
40
|
+
def page_finder(page_id = 'whatever')
|
41
|
+
HighVoltage::PageFinder.new(page_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def with_content_path(path)
|
45
|
+
original_content_path = HighVoltage.content_path
|
46
|
+
HighVoltage.content_path = path
|
47
|
+
|
48
|
+
yield
|
49
|
+
|
50
|
+
HighVoltage.content_path = original_content_path
|
51
|
+
end
|
52
|
+
end
|
data/spec/high_voltage_spec.rb
CHANGED
data/spec/routing/routes_spec.rb
CHANGED
@@ -1,68 +1,150 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
describe 'routes' do
|
3
|
-
context "using default configuration" do
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
describe 'routes' do
|
4
|
+
context 'using default configuration' do
|
5
|
+
it 'should generate normal resource route with id' do
|
6
|
+
page_path(:id => 'one').should eq '/pages/one'
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
page_path(
|
9
|
+
it 'should generate normal resource route with string' do
|
10
|
+
page_path('one').should eq '/pages/one'
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
page_path(
|
13
|
+
it 'should generate nested route with string' do
|
14
|
+
page_path('one/two').should eq '/pages/one/two'
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
assert_recognizes(
|
17
|
+
it 'should recognize nested route' do
|
18
|
+
assert_recognizes(
|
19
|
+
{
|
20
|
+
:controller => 'high_voltage/pages',
|
21
|
+
:action => 'show',
|
22
|
+
:id => 'one/two'
|
23
|
+
},
|
24
|
+
'/pages/one/two'
|
25
|
+
)
|
19
26
|
end
|
20
27
|
|
21
|
-
it
|
22
|
-
assert_recognizes(
|
28
|
+
it 'should recognize normal route' do
|
29
|
+
assert_recognizes(
|
30
|
+
{
|
31
|
+
:controller => 'high_voltage/pages',
|
32
|
+
:action => 'show',
|
33
|
+
:id => 'one'
|
34
|
+
},
|
35
|
+
'/pages/one'
|
36
|
+
)
|
23
37
|
end
|
24
38
|
|
25
|
-
it
|
26
|
-
assert_recognizes(
|
39
|
+
it 'should recognize normal route with dots' do
|
40
|
+
assert_recognizes(
|
41
|
+
{
|
42
|
+
:controller => 'high_voltage/pages',
|
43
|
+
:action => 'show',
|
44
|
+
:id => 'one.two.three'
|
45
|
+
},
|
46
|
+
'/pages/one.two.three'
|
47
|
+
)
|
27
48
|
end
|
28
49
|
end
|
29
50
|
|
30
|
-
context
|
51
|
+
context 'using root routing configuration' do
|
52
|
+
around do |example|
|
53
|
+
cached_high_voltage_route_drawer = HighVoltage.route_drawer
|
54
|
+
HighVoltage.route_drawer = HighVoltage::RouteDrawers::Root
|
55
|
+
Rails.application.reload_routes!
|
56
|
+
|
57
|
+
example.run
|
31
58
|
|
32
|
-
|
33
|
-
@original_content_path = HighVoltage.content_path
|
34
|
-
HighVoltage.content_path = "other_pages/"
|
59
|
+
HighVoltage.route_drawer = cached_high_voltage_route_drawer
|
35
60
|
Rails.application.reload_routes!
|
36
61
|
end
|
37
62
|
|
38
|
-
|
39
|
-
|
63
|
+
it 'should generate normal resource route with id' do
|
64
|
+
page_path(:id => 'one').should eq '/one'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should generate normal resource route with string' do
|
68
|
+
page_path('one').should eq '/one'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should generate nested route with string' do
|
72
|
+
page_path('one/two').should eq '/one/two'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'using a custom content_path' do
|
77
|
+
around do |example|
|
78
|
+
cached_high_voltage_content_path = HighVoltage.content_path
|
79
|
+
HighVoltage.content_path = 'other_pages/'
|
80
|
+
Rails.application.reload_routes!
|
81
|
+
|
82
|
+
example.run
|
83
|
+
|
84
|
+
HighVoltage.content_path = cached_high_voltage_content_path
|
40
85
|
Rails.application.reload_routes!
|
41
86
|
end
|
42
87
|
|
43
|
-
it
|
44
|
-
page_path(:id =>
|
88
|
+
it 'should generate normal resource route with id' do
|
89
|
+
page_path(:id => 'one').should eq '/other_pages/one'
|
45
90
|
end
|
46
91
|
|
47
|
-
it
|
48
|
-
page_path(
|
92
|
+
it 'should generate normal resource route with string' do
|
93
|
+
page_path('one').should eq '/other_pages/one'
|
49
94
|
end
|
50
95
|
|
51
|
-
it
|
52
|
-
page_path(
|
96
|
+
it 'should generate nested route with string' do
|
97
|
+
page_path('one/two').should eq '/other_pages/one/two'
|
53
98
|
end
|
54
99
|
|
55
|
-
it
|
56
|
-
assert_recognizes(
|
100
|
+
it 'should recognize nested route' do
|
101
|
+
assert_recognizes(
|
102
|
+
{
|
103
|
+
:controller => 'high_voltage/pages',
|
104
|
+
:action => 'show',
|
105
|
+
:id => 'one/two'
|
106
|
+
},
|
107
|
+
'/other_pages/one/two'
|
108
|
+
)
|
57
109
|
end
|
58
110
|
|
59
|
-
it
|
60
|
-
assert_recognizes(
|
111
|
+
it 'should recognize normal route' do
|
112
|
+
assert_recognizes(
|
113
|
+
{
|
114
|
+
:controller => 'high_voltage/pages',
|
115
|
+
:action => 'show',
|
116
|
+
:id => 'one'
|
117
|
+
},
|
118
|
+
'/other_pages/one'
|
119
|
+
)
|
61
120
|
end
|
62
121
|
|
63
|
-
it
|
64
|
-
assert_recognizes(
|
122
|
+
it 'should recognize normal route with dots' do
|
123
|
+
assert_recognizes(
|
124
|
+
{
|
125
|
+
:controller => 'high_voltage/pages',
|
126
|
+
:action => 'show',
|
127
|
+
:id => 'one.two.three'
|
128
|
+
},
|
129
|
+
'/other_pages/one.two.three'
|
130
|
+
)
|
65
131
|
end
|
66
132
|
end
|
67
133
|
|
134
|
+
context 'with default configuration disabled' do
|
135
|
+
around do |example|
|
136
|
+
cached_high_voltage_routes = HighVoltage.routes
|
137
|
+
HighVoltage.routes = false
|
138
|
+
Rails.application.reload_routes!
|
139
|
+
|
140
|
+
example.run
|
141
|
+
|
142
|
+
HighVoltage.routes = cached_high_voltage_routes
|
143
|
+
Rails.application.reload_routes!
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should not recognize routes' do
|
147
|
+
{ :get => '/pages/one/two' }.should_not be_routable
|
148
|
+
end
|
149
|
+
end
|
68
150
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,30 +1,18 @@
|
|
1
|
-
|
2
|
-
ENV["RAILS_ENV"] = "test"
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
3
2
|
|
4
3
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
ActionMailer::Base.delivery_method = :test
|
9
|
-
ActionMailer::Base.perform_deliveries = true
|
10
|
-
ActionMailer::Base.default_url_options[:host] = "test.com"
|
4
|
+
require 'rails/test_help'
|
5
|
+
require 'rspec/rails'
|
6
|
+
require 'capybara/rails'
|
11
7
|
|
12
8
|
Rails.backtrace_cleaner.remove_silencers!
|
13
|
-
|
14
|
-
# Configure capybara for integration testing
|
15
|
-
require "capybara/rails"
|
16
9
|
Capybara.default_driver = :rack_test
|
17
10
|
Capybara.default_selector = :css
|
18
11
|
|
19
|
-
# Load support files
|
20
12
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
21
13
|
|
22
14
|
RSpec.configure do |config|
|
23
|
-
# Remove this line if you don't want RSpec's should and should_not
|
24
|
-
# methods or matchers
|
25
15
|
require 'rspec/expectations'
|
26
16
|
config.include RSpec::Matchers
|
27
|
-
|
28
|
-
# == Mock Framework
|
29
17
|
config.mock_with :rspec
|
30
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: high_voltage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -17,7 +17,7 @@ authors:
|
|
17
17
|
autorequire:
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
|
-
date: 2012-
|
20
|
+
date: 2012-10-30 00:00:00.000000000 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: appraisal
|
@@ -106,11 +106,18 @@ files:
|
|
106
106
|
- gemfiles/rails-3.2.6.gemfile
|
107
107
|
- high_voltage.gemspec
|
108
108
|
- lib/high_voltage.rb
|
109
|
+
- lib/high_voltage/constraints/root_route.rb
|
109
110
|
- lib/high_voltage/engine.rb
|
111
|
+
- lib/high_voltage/page_finder.rb
|
112
|
+
- lib/high_voltage/route_drawers/default.rb
|
113
|
+
- lib/high_voltage/route_drawers/root.rb
|
110
114
|
- lib/high_voltage/version.rb
|
115
|
+
- spec/constraints/root_route_spec.rb
|
116
|
+
- spec/controllers/alternative_finder_controller_spec.rb
|
111
117
|
- spec/controllers/pages_controller_spec.rb
|
112
118
|
- spec/controllers/subclassed_pages_controller_spec.rb
|
113
119
|
- spec/dummy/Rakefile
|
120
|
+
- spec/dummy/app/controllers/alternative_finder_controller.rb
|
114
121
|
- spec/dummy/app/controllers/application_controller.rb
|
115
122
|
- spec/dummy/app/controllers/subclassed_pages_controller.rb
|
116
123
|
- spec/dummy/app/helpers/application_helper.rb
|
@@ -120,9 +127,13 @@ files:
|
|
120
127
|
- spec/dummy/app/views/other_pages/also_dir/also_nested.html.erb
|
121
128
|
- spec/dummy/app/views/other_pages/also_exists.html.erb
|
122
129
|
- spec/dummy/app/views/other_pages/also_exists_but_references_nonexistent_partial.html.erb
|
130
|
+
- spec/dummy/app/views/pages/also_dir/also_nested.html.erb
|
131
|
+
- spec/dummy/app/views/pages/also_exists.html.erb
|
132
|
+
- spec/dummy/app/views/pages/also_exists_but_references_nonexistent_partial.html.erb
|
123
133
|
- spec/dummy/app/views/pages/dir/nested.html.erb
|
124
134
|
- spec/dummy/app/views/pages/exists.html.erb
|
125
135
|
- spec/dummy/app/views/pages/exists_but_references_nonexistent_partial.html.erb
|
136
|
+
- spec/dummy/app/views/pages/rot13.html.erb
|
126
137
|
- spec/dummy/config.ru
|
127
138
|
- spec/dummy/config/application.rb
|
128
139
|
- spec/dummy/config/boot.rb
|
@@ -149,6 +160,7 @@ files:
|
|
149
160
|
- spec/dummy/public/javascripts/rails.js
|
150
161
|
- spec/dummy/public/stylesheets/.gitkeep
|
151
162
|
- spec/dummy/script/rails
|
163
|
+
- spec/high_voltage/page_finder_spec.rb
|
152
164
|
- spec/high_voltage_spec.rb
|
153
165
|
- spec/integration/navigation_spec.rb
|
154
166
|
- spec/routing/routes_spec.rb
|
@@ -167,7 +179,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
179
|
version: '0'
|
168
180
|
segments:
|
169
181
|
- 0
|
170
|
-
hash:
|
182
|
+
hash: 4008834492193111030
|
171
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
184
|
none: false
|
173
185
|
requirements:
|
@@ -176,11 +188,64 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
188
|
version: '0'
|
177
189
|
segments:
|
178
190
|
- 0
|
179
|
-
hash:
|
191
|
+
hash: 4008834492193111030
|
180
192
|
requirements: []
|
181
193
|
rubyforge_project:
|
182
194
|
rubygems_version: 1.8.24
|
183
195
|
signing_key:
|
184
196
|
specification_version: 3
|
185
197
|
summary: Simple static page rendering controller
|
186
|
-
test_files:
|
198
|
+
test_files:
|
199
|
+
- spec/constraints/root_route_spec.rb
|
200
|
+
- spec/controllers/alternative_finder_controller_spec.rb
|
201
|
+
- spec/controllers/pages_controller_spec.rb
|
202
|
+
- spec/controllers/subclassed_pages_controller_spec.rb
|
203
|
+
- spec/dummy/Rakefile
|
204
|
+
- spec/dummy/app/controllers/alternative_finder_controller.rb
|
205
|
+
- spec/dummy/app/controllers/application_controller.rb
|
206
|
+
- spec/dummy/app/controllers/subclassed_pages_controller.rb
|
207
|
+
- spec/dummy/app/helpers/application_helper.rb
|
208
|
+
- spec/dummy/app/views/layouts/alternate.html.erb
|
209
|
+
- spec/dummy/app/views/layouts/application.html.erb
|
210
|
+
- spec/dummy/app/views/other/wrong.html.erb
|
211
|
+
- spec/dummy/app/views/other_pages/also_dir/also_nested.html.erb
|
212
|
+
- spec/dummy/app/views/other_pages/also_exists.html.erb
|
213
|
+
- spec/dummy/app/views/other_pages/also_exists_but_references_nonexistent_partial.html.erb
|
214
|
+
- spec/dummy/app/views/pages/also_dir/also_nested.html.erb
|
215
|
+
- spec/dummy/app/views/pages/also_exists.html.erb
|
216
|
+
- spec/dummy/app/views/pages/also_exists_but_references_nonexistent_partial.html.erb
|
217
|
+
- spec/dummy/app/views/pages/dir/nested.html.erb
|
218
|
+
- spec/dummy/app/views/pages/exists.html.erb
|
219
|
+
- spec/dummy/app/views/pages/exists_but_references_nonexistent_partial.html.erb
|
220
|
+
- spec/dummy/app/views/pages/rot13.html.erb
|
221
|
+
- spec/dummy/config.ru
|
222
|
+
- spec/dummy/config/application.rb
|
223
|
+
- spec/dummy/config/boot.rb
|
224
|
+
- spec/dummy/config/environment.rb
|
225
|
+
- spec/dummy/config/environments/development.rb
|
226
|
+
- spec/dummy/config/environments/production.rb
|
227
|
+
- spec/dummy/config/environments/test.rb
|
228
|
+
- spec/dummy/config/initializers/backtrace_silencers.rb
|
229
|
+
- spec/dummy/config/initializers/inflections.rb
|
230
|
+
- spec/dummy/config/initializers/mime_types.rb
|
231
|
+
- spec/dummy/config/initializers/secret_token.rb
|
232
|
+
- spec/dummy/config/initializers/session_store.rb
|
233
|
+
- spec/dummy/config/locales/en.yml
|
234
|
+
- spec/dummy/config/routes.rb
|
235
|
+
- spec/dummy/public/404.html
|
236
|
+
- spec/dummy/public/422.html
|
237
|
+
- spec/dummy/public/500.html
|
238
|
+
- spec/dummy/public/favicon.ico
|
239
|
+
- spec/dummy/public/javascripts/application.js
|
240
|
+
- spec/dummy/public/javascripts/controls.js
|
241
|
+
- spec/dummy/public/javascripts/dragdrop.js
|
242
|
+
- spec/dummy/public/javascripts/effects.js
|
243
|
+
- spec/dummy/public/javascripts/prototype.js
|
244
|
+
- spec/dummy/public/javascripts/rails.js
|
245
|
+
- spec/dummy/public/stylesheets/.gitkeep
|
246
|
+
- spec/dummy/script/rails
|
247
|
+
- spec/high_voltage/page_finder_spec.rb
|
248
|
+
- spec/high_voltage_spec.rb
|
249
|
+
- spec/integration/navigation_spec.rb
|
250
|
+
- spec/routing/routes_spec.rb
|
251
|
+
- spec/spec_helper.rb
|