usher 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -0
- data/README.markdown +158 -0
- data/Rakefile +47 -12
- data/benchmarks/rack_recognition_bm.rb +48 -0
- data/lib/usher/delimiters.rb +20 -8
- data/lib/usher/exceptions.rb +4 -0
- data/lib/usher/grapher.rb +38 -32
- data/lib/usher/interface/rack/builder.rb +39 -0
- data/lib/usher/interface/rack/middleware.rb +22 -0
- data/lib/usher/interface/rack.rb +6 -55
- data/lib/usher/interface/sinatra.rb +115 -56
- data/lib/usher/interface.rb +12 -22
- data/lib/usher/node/response.rb +3 -1
- data/lib/usher/node.rb +56 -75
- data/lib/usher/route/static.rb +2 -0
- data/lib/usher/route/variable.rb +1 -1
- data/lib/usher/route.rb +21 -18
- data/lib/usher/splitter.rb +4 -6
- data/lib/usher/util/generate.rb +50 -34
- data/lib/usher/util/parser.rb +12 -9
- data/lib/usher.rb +204 -162
- data/spec/private/generate_spec.rb +5 -0
- data/spec/private/recognize_spec.rb +12 -12
- data/spec/private/sinatra/recognize_spec.rb +102 -0
- data/spec/spec_helper.rb +1 -1
- data/usher.gemspec +8 -5
- metadata +75 -19
- data/README.rdoc +0 -158
- data/spec/rails2_2/compat.rb +0 -3
- data/spec/rails2_2/generate_spec.rb +0 -28
- data/spec/rails2_2/path_spec.rb +0 -16
- data/spec/rails2_2/recognize_spec.rb +0 -78
- data/spec/rails2_3/compat.rb +0 -2
- data/spec/rails2_3/generate_spec.rb +0 -28
- data/spec/rails2_3/path_spec.rb +0 -16
- data/spec/rails2_3/recognize_spec.rb +0 -78
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require "usher"
|
3
|
+
require "sinatra"
|
4
|
+
|
5
|
+
describe "Usher (for Sinatra) route recognition" do
|
6
|
+
before(:each) do
|
7
|
+
@app = Sinatra.new { register Usher::Interface::Sinatra::Extension }
|
8
|
+
@app.extend(CallWithMockRequestMixin)
|
9
|
+
@app.reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "basic functionality" do
|
13
|
+
it "should map not found" do
|
14
|
+
response = @app.call_with_mock_request('/bar')
|
15
|
+
response.status.should == 404
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should map index" do
|
19
|
+
@app.get("/") { "index" }
|
20
|
+
response = @app.call_with_mock_request('/')
|
21
|
+
response.status.should == 200
|
22
|
+
response.body.should == "index"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should ignore trailing delimiters" do
|
26
|
+
@app.get("/foo") { "foo" }
|
27
|
+
response = @app.call_with_mock_request('/foo')
|
28
|
+
response.status.should == 200
|
29
|
+
response.body.should == "foo"
|
30
|
+
response = @app.call_with_mock_request('/foo/')
|
31
|
+
response.status.should == 200
|
32
|
+
response.body.should == "foo"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should ignore trailing delimiters in a more advanced route" do
|
36
|
+
@app.get("/foo") { "foo" }
|
37
|
+
@app.get("/foo/bar") { "bar" }
|
38
|
+
response = @app.call_with_mock_request('/foo')
|
39
|
+
response.status.should == 200
|
40
|
+
response.body.should == "foo"
|
41
|
+
response = @app.call_with_mock_request('/foo/bar')
|
42
|
+
response.status.should == 200
|
43
|
+
response.body.should == "bar"
|
44
|
+
response = @app.call_with_mock_request('/foo/')
|
45
|
+
response.status.should == 200
|
46
|
+
response.body.should == "foo"
|
47
|
+
response = @app.call_with_mock_request('/foo/bar/')
|
48
|
+
response.status.should == 200
|
49
|
+
response.body.should == "bar"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should use sinatra optionals trailing delimiters" do
|
53
|
+
@app.get("/foo/?") { "foo" }
|
54
|
+
response = @app.call_with_mock_request('/foo')
|
55
|
+
response.status.should == 200
|
56
|
+
response.body.should == "foo"
|
57
|
+
response = @app.call_with_mock_request('/foo/')
|
58
|
+
response.status.should == 200
|
59
|
+
response.body.should == "foo"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "mapping functionality" do
|
64
|
+
|
65
|
+
it "should map a basic route" do
|
66
|
+
@app.get('/hi', :name => :hi) { generate(:hi) }
|
67
|
+
response = @app.call_with_mock_request('/hi')
|
68
|
+
response.status.should == 200
|
69
|
+
response.body.should == "/hi"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should map a basic route ignoring trailing delimiters" do
|
73
|
+
@app.get('/hi', :name => :hi) { generate(:hi) }
|
74
|
+
response = @app.call_with_mock_request('/hi/')
|
75
|
+
response.status.should == 200
|
76
|
+
response.body.should == "/hi"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should map a basic route with params" do
|
80
|
+
@app.get('/hi/:id', :name => :hi) { generate(:hi, :id => 18) }
|
81
|
+
response = @app.call_with_mock_request('/hi/1')
|
82
|
+
response.status.should == 200
|
83
|
+
response.body.should == "/hi/18"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should map route with params" do
|
87
|
+
@app.get('/hi-:id', :name => :hi) { generate(:hi, :id => 18) }
|
88
|
+
response = @app.call_with_mock_request('/hi-1')
|
89
|
+
response.status.should == 200
|
90
|
+
response.body.should == "/hi-18"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "not found" do
|
95
|
+
|
96
|
+
it "should correctly generate a not found page without images" do
|
97
|
+
response = @app.call_with_mock_request('/bar')
|
98
|
+
response.status.should == 404
|
99
|
+
response.body.should_not match(/__sinatra__/)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/usher.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "base64"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "usher"
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.2"
|
9
9
|
s.authors = ["Daniel Neighman", "Daniel Vartanov", "Jakub Šťastný", "Joshua Hull"]
|
10
10
|
s.homepage = "http://github.com/joshbuddy/usher"
|
11
11
|
s.summary = "Pure ruby general purpose router with interfaces for rails, rack, email or choose your own adventure"
|
@@ -14,12 +14,15 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.has_rdoc = true
|
15
15
|
|
16
16
|
# files
|
17
|
-
s.files = `git ls-files`.split("\n") - `git ls-files spec/rails2_2
|
17
|
+
s.files = `git ls-files`.split("\n") - `git ls-files spec/rails2_2`.split("\n") - `git ls-files spec/rails2_3`.split("\n")
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
# dependencies
|
21
21
|
s.add_dependency "fuzzyhash", ">= 0.0.11"
|
22
|
-
|
23
|
-
#
|
24
|
-
s.
|
22
|
+
|
23
|
+
# development dependencies
|
24
|
+
s.add_development_dependency "yard"
|
25
|
+
s.add_development_dependency "rspec"
|
26
|
+
s.add_development_dependency "code_stats"
|
27
|
+
s.add_development_dependency "rake"
|
25
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 7
|
8
|
+
- 2
|
9
|
+
version: 0.7.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Daniel Neighman
|
@@ -13,19 +18,71 @@ authors:
|
|
13
18
|
autorequire:
|
14
19
|
bindir: bin
|
15
20
|
cert_chain:
|
16
|
-
date: 2010-
|
21
|
+
date: 2010-04-29 00:00:00 -04:00
|
17
22
|
default_executable:
|
18
23
|
dependencies:
|
19
24
|
- !ruby/object:Gem::Dependency
|
20
25
|
name: fuzzyhash
|
21
|
-
|
22
|
-
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
28
|
requirements:
|
25
29
|
- - ">="
|
26
30
|
- !ruby/object:Gem::Version
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
- 11
|
27
35
|
version: 0.0.11
|
28
|
-
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: yard
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: code_stats
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
type: :development
|
73
|
+
version_requirements: *id004
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: rake
|
76
|
+
prerelease: false
|
77
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id005
|
29
86
|
description:
|
30
87
|
email: joshbuddy@gmail.com
|
31
88
|
executables: []
|
@@ -37,11 +94,13 @@ extra_rdoc_files: []
|
|
37
94
|
files:
|
38
95
|
- .gitignore
|
39
96
|
- CHANGES.rdoc
|
97
|
+
- Gemfile
|
40
98
|
- History.txt
|
41
99
|
- Manifest.txt
|
42
|
-
- README.
|
100
|
+
- README.markdown
|
43
101
|
- Rakefile
|
44
102
|
- benchmarks/generation_bm.rb
|
103
|
+
- benchmarks/rack_recognition_bm.rb
|
45
104
|
- benchmarks/recognition_bm.rb
|
46
105
|
- lib/usher.rb
|
47
106
|
- lib/usher/delimiters.rb
|
@@ -51,6 +110,8 @@ files:
|
|
51
110
|
- lib/usher/interface/email.rb
|
52
111
|
- lib/usher/interface/merb.rb
|
53
112
|
- lib/usher/interface/rack.rb
|
113
|
+
- lib/usher/interface/rack/builder.rb
|
114
|
+
- lib/usher/interface/rack/middleware.rb
|
54
115
|
- lib/usher/interface/rack/route.rb
|
55
116
|
- lib/usher/interface/rails20.rb
|
56
117
|
- lib/usher/interface/rails22.rb
|
@@ -88,16 +149,9 @@ files:
|
|
88
149
|
- spec/private/rack/route_spec.rb
|
89
150
|
- spec/private/recognize_spec.rb
|
90
151
|
- spec/private/request_method_spec.rb
|
152
|
+
- spec/private/sinatra/recognize_spec.rb
|
91
153
|
- spec/private/splitter_spec.rb
|
92
154
|
- spec/private/url_parts_spec.rb
|
93
|
-
- spec/rails2_2/compat.rb
|
94
|
-
- spec/rails2_2/generate_spec.rb
|
95
|
-
- spec/rails2_2/path_spec.rb
|
96
|
-
- spec/rails2_2/recognize_spec.rb
|
97
|
-
- spec/rails2_3/compat.rb
|
98
|
-
- spec/rails2_3/generate_spec.rb
|
99
|
-
- spec/rails2_3/path_spec.rb
|
100
|
-
- spec/rails2_3/recognize_spec.rb
|
101
155
|
- spec/spec.opts
|
102
156
|
- spec/spec_helper.rb
|
103
157
|
- tasks/routes.rake
|
@@ -115,18 +169,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
169
|
requirements:
|
116
170
|
- - ">="
|
117
171
|
- !ruby/object:Gem::Version
|
172
|
+
segments:
|
173
|
+
- 0
|
118
174
|
version: "0"
|
119
|
-
version:
|
120
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
176
|
requirements:
|
122
177
|
- - ">="
|
123
178
|
- !ruby/object:Gem::Version
|
179
|
+
segments:
|
180
|
+
- 0
|
124
181
|
version: "0"
|
125
|
-
version:
|
126
182
|
requirements: []
|
127
183
|
|
128
|
-
rubyforge_project:
|
129
|
-
rubygems_version: 1.3.
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 1.3.6
|
130
186
|
signing_key:
|
131
187
|
specification_version: 3
|
132
188
|
summary: Pure ruby general purpose router with interfaces for rails, rack, email or choose your own adventure
|
data/README.rdoc
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
= Usher
|
2
|
-
|
3
|
-
Tree-based router library. Useful for (specifically) for Rails and Rack, but probably generally useful for anyone interested in doing routing. Based on Ilya Grigorik suggestion, turns out looking up in a hash and following a tree is faster than Krauter's massive regex approach.
|
4
|
-
|
5
|
-
== Features
|
6
|
-
|
7
|
-
* Understands single and path-globbing variables
|
8
|
-
* Understands arbitrary regex variables
|
9
|
-
* Arbitrary HTTP header requirements
|
10
|
-
* No optimization phase, so routes are always alterable after the fact
|
11
|
-
* Understands Proc and Regex transformations, validations
|
12
|
-
* Really, really fast
|
13
|
-
* Relatively light and happy code-base, should be easy and fun to alter (it hovers around 1,000 LOC, 800 for the core)
|
14
|
-
* Interface and implementation are separate, encouraging cross-pollination
|
15
|
-
* Works in 1.9!
|
16
|
-
|
17
|
-
== Projects using or other references to Usher
|
18
|
-
|
19
|
-
* http://github.com/Tass/CRUDtree - RESTful resource mapper
|
20
|
-
* http://github.com/padrino/padrino-framework - Web framework
|
21
|
-
* http://github.com/botanicus/rango - Web framework
|
22
|
-
* http://github.com/hassox/pancake - Web framework
|
23
|
-
* http://github.com/eddanger/junior - Web framework
|
24
|
-
* http://github.com/lifo/cramp - Web framework
|
25
|
-
* http://yehudakatz.com/2009/08/26/how-to-build-sinatra-on-rails-3/ - How to Build Sinatra on Rails 3
|
26
|
-
|
27
|
-
Any probably more!
|
28
|
-
|
29
|
-
== Route format
|
30
|
-
|
31
|
-
From the rdoc:
|
32
|
-
|
33
|
-
Creates a route from +path+ and +options+
|
34
|
-
|
35
|
-
=== +path+
|
36
|
-
A path consists a mix of dynamic and static parts delimited by <tt>/</tt>
|
37
|
-
|
38
|
-
==== Dynamic
|
39
|
-
Dynamic parts are prefixed with either :, *. :variable matches only one part of the path, whereas *variable can match one or
|
40
|
-
more parts.
|
41
|
-
|
42
|
-
<b>Example:</b>
|
43
|
-
<tt>/path/:variable/path</tt> would match
|
44
|
-
|
45
|
-
* <tt>/path/test/path</tt>
|
46
|
-
* <tt>/path/something_else/path</tt>
|
47
|
-
* <tt>/path/one_more/path</tt>
|
48
|
-
|
49
|
-
In the above examples, 'test', 'something_else' and 'one_more' respectively would be bound to the key <tt>:variable</tt>.
|
50
|
-
However, <tt>/path/test/one_more/path</tt> would not be matched.
|
51
|
-
|
52
|
-
<b>Example:</b>
|
53
|
-
<tt>/path/*variable/path</tt> would match
|
54
|
-
|
55
|
-
* <tt>/path/one/two/three/path</tt>
|
56
|
-
* <tt>/path/four/five/path</tt>
|
57
|
-
|
58
|
-
In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
59
|
-
|
60
|
-
As well, variables can have a regex matcher.
|
61
|
-
|
62
|
-
<b>Example:</b>
|
63
|
-
<tt>/product/{:id,\d+}</tt> would match
|
64
|
-
|
65
|
-
* <tt>/product/123</tt>
|
66
|
-
* <tt>/product/4521</tt>
|
67
|
-
|
68
|
-
But not
|
69
|
-
* <tt>/product/AE-35</tt>
|
70
|
-
|
71
|
-
As well, the same logic applies for * variables as well, where only parts matchable by the supplied regex will
|
72
|
-
actually be bound to the variable
|
73
|
-
|
74
|
-
Variables can also have a greedy regex matcher. These matchers ignore all delimiters, and continue matching for as long as much as their
|
75
|
-
regex allows.
|
76
|
-
|
77
|
-
<b>Example:</b>
|
78
|
-
<tt>/product/{!id,hello/world|hello}</tt> would match
|
79
|
-
|
80
|
-
* <tt>/product/hello/world</tt>
|
81
|
-
* <tt>/product/hello</tt>
|
82
|
-
|
83
|
-
|
84
|
-
==== Static
|
85
|
-
|
86
|
-
Static parts of literal character sequences. For instance, <tt>/path/something.html</tt> would match only the same path.
|
87
|
-
As well, static parts can have a regex pattern in them as well, such as <tt>/path/something.{html|xml}</tt> which would match only
|
88
|
-
<tt>/path/something.html</tt> and <tt>/path/something.xml</tt>
|
89
|
-
|
90
|
-
==== Optional sections
|
91
|
-
|
92
|
-
Sections of a route can be marked as optional by surrounding it with brackets. For instance, in the above static example, <tt>/path/something(.html)</tt> would match both <tt>/path/something</tt> and <tt>/path/something.html</tt>.
|
93
|
-
|
94
|
-
==== One and only one sections
|
95
|
-
|
96
|
-
Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes.
|
97
|
-
For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <tt>/path/something.xml</tt> and
|
98
|
-
<tt>/path/something.html</tt>. Generally its more efficent to use one and only sections over using regex.
|
99
|
-
|
100
|
-
=== +options+
|
101
|
-
* +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
102
|
-
* +conditions+ - Accepts any of the +request_methods+ specificied in the construction of Usher. This can be either a <tt>string</tt> or a regular expression.
|
103
|
-
* +default_values+ - Provides values for variables in your route for generation. If you're using URL generation, then any values supplied here that aren't included in your path will be appended to the query string.
|
104
|
-
* +priority+ - If there are two routes which equally match, the route with the highest priority will match first.
|
105
|
-
* Any other key is interpreted as a requirement for the variable of its name.
|
106
|
-
|
107
|
-
== Rails
|
108
|
-
|
109
|
-
script/plugin install git://github.com/joshbuddy/usher.git
|
110
|
-
|
111
|
-
In your config/initializers/usher.rb (create if it doesn't exist) add:
|
112
|
-
|
113
|
-
Usher::Util::Rails.activate
|
114
|
-
|
115
|
-
== Rack
|
116
|
-
|
117
|
-
=== config.ru
|
118
|
-
|
119
|
-
require 'usher'
|
120
|
-
app = proc do |env|
|
121
|
-
body = "Hi there #{env['usher.params'][:name]}"
|
122
|
-
[
|
123
|
-
200, # Status code
|
124
|
-
{ # Response headers
|
125
|
-
'Content-Type' => 'text/plain',
|
126
|
-
'Content-Length' => body.size.to_s,
|
127
|
-
},
|
128
|
-
[body] # Response body
|
129
|
-
]
|
130
|
-
end
|
131
|
-
|
132
|
-
routes = Usher::Interface.for(:rack) do
|
133
|
-
add('/hello/:name').to(app)
|
134
|
-
end
|
135
|
-
|
136
|
-
run routes
|
137
|
-
|
138
|
-
------------
|
139
|
-
|
140
|
-
>> curl http://127.0.0.1:3000/hello/samueltanders
|
141
|
-
<< Hi there samueltanders
|
142
|
-
|
143
|
-
|
144
|
-
== Sinatra
|
145
|
-
|
146
|
-
In Sinatra, you get the extra method, +generate+, which lets you generate a url. Name your routes with <tt>:name</tt> when you define them.
|
147
|
-
|
148
|
-
require 'rubygems'
|
149
|
-
require 'usher'
|
150
|
-
require 'sinatra'
|
151
|
-
|
152
|
-
Usher::Interface.for(:sinatra)
|
153
|
-
|
154
|
-
get '/hi', :name => :hi do
|
155
|
-
"Hello World! #{generate(:hi)}"
|
156
|
-
end
|
157
|
-
|
158
|
-
(Let me show you to your request)
|
data/spec/rails2_2/compat.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
|
2
|
-
require "usher"
|
3
|
-
|
4
|
-
route_set = Usher::Interface.for(:rails22)
|
5
|
-
|
6
|
-
describe "Usher (for rails 2.2) URL generation" do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
route_set.reset!
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should fill in the controller from recall" do
|
13
|
-
route_set.add_route('/:controller/:action/:id')
|
14
|
-
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should skip the action if not provided" do
|
18
|
-
route_set.add_route('/:controller/:action/:id')
|
19
|
-
route_set.generate({:controller => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/thingy'
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should pick the correct param from optional parts" do
|
23
|
-
route_set.add_route('/:controller/:action(.:format)')
|
24
|
-
route_set.generate({:action => 'thingy', :format => 'html'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy.html'
|
25
|
-
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
data/spec/rails2_2/path_spec.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
|
2
|
-
require "usher"
|
3
|
-
|
4
|
-
route_set = Usher::Interface.for(:rails22)
|
5
|
-
|
6
|
-
describe "Usher (for rails 2.2) route adding" do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
route_set.reset!
|
10
|
-
end
|
11
|
-
|
12
|
-
it "shouldn't allow routes without a controller to be added" do
|
13
|
-
proc { route_set.add_route('/bad/route') }.should raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
|
2
|
-
require "usher"
|
3
|
-
|
4
|
-
route_set = Usher::Interface.for(:rails22)
|
5
|
-
|
6
|
-
def build_request_mock_rails22(path, method, params)
|
7
|
-
request = mock "Request"
|
8
|
-
request.should_receive(:path).any_number_of_times.and_return(path)
|
9
|
-
request.should_receive(:method).any_number_of_times.and_return(method)
|
10
|
-
params = params.with_indifferent_access
|
11
|
-
request.should_receive(:path_parameters=).any_number_of_times.with(params)
|
12
|
-
request.should_receive(:path_parameters).any_number_of_times.and_return(params)
|
13
|
-
request
|
14
|
-
end
|
15
|
-
|
16
|
-
SampleController = Object.new
|
17
|
-
|
18
|
-
describe "Usher (for rails 2.2) route recognition" do
|
19
|
-
|
20
|
-
before(:each) do
|
21
|
-
route_set.reset!
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should recognize a simple request" do
|
25
|
-
route_set.add_route('/sample', :controller => 'sample', :action => 'action')
|
26
|
-
route_set.recognize(build_request_mock_rails22('/sample', 'get', {:controller => 'sample', :action => 'action'})).should == SampleController
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should interpolate action :index" do
|
30
|
-
route_set.add_route('/sample', :controller => 'sample')
|
31
|
-
route_set.recognize(build_request_mock_rails22('/sample', 'get', {:controller => 'sample', :action => 'index'})).should == SampleController
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should correctly distinguish between multiple request methods" do
|
35
|
-
route_set.add_route('/sample', :controller => 'not_sample', :conditions => {:method => :get})
|
36
|
-
correct_route = route_set.add_route('/sample', :controller => 'sample', :conditions => {:method => :post})
|
37
|
-
route_set.add_route('/sample', :controller => 'not_sample', :conditions => {:method => :put})
|
38
|
-
route_set.recognize(build_request_mock_rails22('/sample', :post, {:controller => 'sample', :action => 'index'})).should == SampleController
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should prefer the static route to the dynamic route" do
|
42
|
-
route_set.add_route('/sample/:action', :controller => 'not_sample')
|
43
|
-
route_set.add_route('/sample/test', :controller => 'sample', :action => 'action')
|
44
|
-
route_set.recognize(build_request_mock_rails22('/sample/test', 'get', {:controller => 'sample', :action => 'action'})).should == SampleController
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should raise based upon an invalid param" do
|
48
|
-
route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample', :requirements => {:action => /\d+/})
|
49
|
-
proc { route_set.recognize(build_request_mock_rails22('/sample/asdqwe', :post, {})) }.should raise_error
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should raise based upon an invalid route" do
|
53
|
-
route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'test')
|
54
|
-
proc { route_set.recognize(build_request_mock_rails22('/test/asdqwe', :post, {})) }.should raise_error
|
55
|
-
end
|
56
|
-
|
57
|
-
it "should add /:controller and /:controller/:action if /:controller/:action/:id is added" do
|
58
|
-
route_set.add_route('/:controller/:action/:id')
|
59
|
-
route_set.route_count.should == 3
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should correctly recognize a format (dynamic path path with . delimiter)" do
|
63
|
-
route_set.add_route('/:controller/:action/:id.:format')
|
64
|
-
route_set.recognize(build_request_mock_rails22('/sample/test/123.html', 'get', {:controller => 'sample', :action => 'test', :id => '123', :format => 'html'})).should == SampleController
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should support root nodes" do
|
68
|
-
route_set.add_route('/', :controller => 'sample')
|
69
|
-
route_set.recognize(build_request_mock_rails22('/', :get, {:controller => 'sample', :action => 'index'})).should == SampleController
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should default action to 'index' when controller (and not index) is specified" do
|
73
|
-
route_set.add_route('/:controller/:action')
|
74
|
-
route_set.recognize(build_request_mock_rails22('/sample', :get, {:controller => 'sample', :action => 'index'})).should == SampleController
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
end
|
data/spec/rails2_3/compat.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
|
2
|
-
require "usher"
|
3
|
-
|
4
|
-
route_set = Usher::Interface.for(:rails23)
|
5
|
-
|
6
|
-
describe "Usher (for rails 2.3) URL generation" do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
route_set.reset!
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should fill in the controller from recall" do
|
13
|
-
route_set.add_route('/:controller/:action/:id')
|
14
|
-
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should skip the action if not provided" do
|
18
|
-
route_set.add_route('/:controller/:action/:id')
|
19
|
-
route_set.generate({:controller => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/thingy'
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should pick the correct param from optional parts" do
|
23
|
-
route_set.add_route('/:controller/:action(.:format)')
|
24
|
-
route_set.generate({:action => 'thingy', :format => 'html'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy.html'
|
25
|
-
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
data/spec/rails2_3/path_spec.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
|
2
|
-
require "usher"
|
3
|
-
|
4
|
-
route_set = Usher::Interface.for(:rails23)
|
5
|
-
|
6
|
-
describe "Usher (for rails 2.3) route adding" do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
route_set.reset!
|
10
|
-
end
|
11
|
-
|
12
|
-
it "shouldn't allow routes without a controller to be added" do
|
13
|
-
proc { route_set.add_route('/bad/route') }.should raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|