joshbuddy-usher 0.5.1 → 0.5.2
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 +2 -0
- data/Rakefile +5 -27
- data/VERSION.yml +2 -2
- data/lib/usher.rb +104 -67
- data/lib/usher/grapher.rb +2 -1
- data/lib/usher/interface.rb +12 -5
- data/lib/usher/interface/rack_interface.rb +31 -13
- data/lib/usher/interface/rails2_2_interface.rb +2 -3
- data/lib/usher/interface/rails2_3_interface.rb +2 -3
- data/lib/usher/interface/rails3_interface.rb +57 -0
- data/lib/usher/node.rb +76 -50
- data/lib/usher/route.rb +44 -10
- data/lib/usher/route/path.rb +22 -9
- data/lib/usher/util/generate.rb +12 -14
- data/lib/usher/util/parser.rb +50 -0
- data/spec/private/generate_spec.rb +86 -32
- data/spec/private/grapher_spec.rb +5 -6
- data/spec/private/path_spec.rb +35 -4
- data/spec/private/rack/dispatch_spec.rb +100 -15
- data/spec/private/recognize_spec.rb +68 -50
- data/spec/spec_helper.rb +22 -0
- metadata +6 -3
data/lib/usher/util/parser.rb
CHANGED
@@ -18,6 +18,52 @@ class Usher
|
|
18
18
|
@split_regex = split_regex
|
19
19
|
end
|
20
20
|
|
21
|
+
def generate_route(unprocessed_path, conditions, requirements, default_values, generate_with)
|
22
|
+
match_partially = if unprocessed_path.is_a?(String)
|
23
|
+
unprocessed_path = parse(unprocessed_path, requirements, default_values)
|
24
|
+
if unprocessed_path[-1] == ?*
|
25
|
+
unprocessed_path.slice!(-1)
|
26
|
+
true
|
27
|
+
else
|
28
|
+
false
|
29
|
+
end
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
unless unprocessed_path.first.is_a?(Route::Util::Group)
|
35
|
+
group = Usher::Route::Util::Group.new(:all, nil)
|
36
|
+
unprocessed_path.each{|p| group << p}
|
37
|
+
unprocessed_path = group
|
38
|
+
end
|
39
|
+
|
40
|
+
paths = Route::Util.expand_path(unprocessed_path)
|
41
|
+
|
42
|
+
paths.each do |path|
|
43
|
+
path.each_with_index do |part, index|
|
44
|
+
part.default_value = default_values[part.name] if part.is_a?(Usher::Route::Variable) && default_values && default_values[part.name]
|
45
|
+
case part
|
46
|
+
when Usher::Route::Variable::Glob
|
47
|
+
part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Usher::Route::Variable) && !router.delimiter_chars.include?(p[0])} || nil
|
48
|
+
when Usher::Route::Variable
|
49
|
+
part.look_ahead = path[index + 1, path.size].find{|p| router.delimiter_chars.include?(p[0])} || router.delimiters.first
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Route.new(
|
55
|
+
paths,
|
56
|
+
router,
|
57
|
+
conditions,
|
58
|
+
requirements,
|
59
|
+
default_values,
|
60
|
+
generate_with,
|
61
|
+
match_partially
|
62
|
+
)
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
21
67
|
def parse_and_expand(path, requirements = nil, default_values = nil)
|
22
68
|
Usher::Route::Util.expand_path(parse(path, requirements, default_values))
|
23
69
|
end
|
@@ -88,7 +134,11 @@ class Usher
|
|
88
134
|
parts
|
89
135
|
end
|
90
136
|
|
137
|
+
private
|
138
|
+
attr_reader :router
|
139
|
+
|
91
140
|
end
|
141
|
+
|
92
142
|
|
93
143
|
end
|
94
144
|
end
|
@@ -4,138 +4,192 @@ require 'rack'
|
|
4
4
|
describe "Usher URL generation" do
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
-
@route_set = Usher.new
|
7
|
+
@route_set = Usher.new(:generator => Usher::Util::Generators::URL.new)
|
8
8
|
@route_set.reset!
|
9
|
-
@url_generator = Usher::Util::Generators::URL.new(@route_set)
|
10
9
|
end
|
11
10
|
|
12
11
|
it "should generate a simple URL" do
|
13
12
|
@route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'action')
|
14
|
-
@
|
13
|
+
@route_set.generator.generate(:sample, {}).should == '/sample'
|
15
14
|
end
|
16
15
|
|
17
16
|
it "should generate a simple URL with a single variable" do
|
18
17
|
@route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
|
19
|
-
@
|
18
|
+
@route_set.generator.generate(:sample, {:action => 'action'}).should == '/sample/action'
|
20
19
|
end
|
21
20
|
|
22
21
|
it "should generate a simple URL with a single variable (and escape)" do
|
23
22
|
@route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
|
24
|
-
@
|
23
|
+
@route_set.generator.generate(:sample, {:action => 'action time'}).should == '/sample/action%20time'
|
25
24
|
end
|
26
25
|
|
27
26
|
it "should generate a simple URL with a single variable (thats not a string)" do
|
28
27
|
@route_set.add_named_route(:sample, '/sample/:action/:id', :controller => 'sample')
|
29
|
-
@
|
28
|
+
@route_set.generator.generate(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
|
30
29
|
end
|
31
30
|
|
32
31
|
it "should generate a simple URL with a glob variable" do
|
33
32
|
@route_set.add_named_route(:sample, '/sample/*action', :controller => 'sample')
|
34
|
-
@
|
33
|
+
@route_set.generator.generate(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
|
35
34
|
end
|
36
35
|
|
37
36
|
it "should generate a mutliple vairable URL from a hash" do
|
38
37
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
39
|
-
@
|
38
|
+
@route_set.generator.generate(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
|
40
39
|
end
|
41
40
|
|
42
41
|
it "should generate a mutliple vairable URL from an array" do
|
43
42
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
44
|
-
@
|
43
|
+
@route_set.generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
|
45
44
|
end
|
46
45
|
|
47
46
|
it "should generate append extra hash variables to the end" do
|
48
47
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
49
|
-
@
|
48
|
+
@route_set.generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => 'zanz'}).should == '/sample/maz/zoo?third=zanz'
|
50
49
|
end
|
51
50
|
|
52
51
|
it "should generate append extra hash variables to the end (when the first parts are an array)" do
|
53
52
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
54
|
-
['/sample/maz/zoo?four=jane&third=zanz', '/sample/maz/zoo?third=zanz&four=jane'].include?(@
|
53
|
+
['/sample/maz/zoo?four=jane&third=zanz', '/sample/maz/zoo?third=zanz&four=jane'].include?(@route_set.generator.generate(:sample, ['maz', 'zoo', {:third => 'zanz', :four => 'jane'}])).should == true
|
55
54
|
end
|
56
55
|
|
57
56
|
it "should generate append extra hash variables to the end using [] syntax if its an array" do
|
58
57
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
59
|
-
@
|
58
|
+
@route_set.generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
|
60
59
|
end
|
61
60
|
|
62
61
|
it "should generate a mutliple vairable URL from an array" do
|
63
62
|
@route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
64
|
-
@
|
63
|
+
@route_set.generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
|
65
64
|
end
|
66
65
|
|
67
66
|
it "should generate a simple URL with a format" do
|
68
67
|
@route_set.add_named_route(:sample, '/sample/:action.:format', :controller => 'sample')
|
69
|
-
@
|
68
|
+
@route_set.generator.generate(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
|
70
69
|
end
|
71
70
|
|
72
71
|
it "should generate from parameters" do
|
73
72
|
caf = @route_set.add_route('/:controller/:action.:format')
|
74
73
|
ca = @route_set.add_route('/:controller/:action')
|
75
|
-
@
|
76
|
-
@
|
74
|
+
@route_set.generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
|
75
|
+
@route_set.generator.generate(nil, {:controller => 'controller', :action => 'action', :format => 'html'}).should == '/controller/action.html'
|
77
76
|
end
|
78
77
|
|
79
78
|
it "should use the first route when generating a URL from two ambiguous routes" do
|
80
79
|
@route_set.add_route('/:controller/:action')
|
81
80
|
@route_set.add_route('/:action/:controller')
|
82
|
-
@
|
81
|
+
@route_set.generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
|
83
82
|
end
|
84
83
|
|
85
84
|
it "should accept an array of parameters" do
|
86
85
|
caf = @route_set.add_named_route(:name, '/:controller/:action.:format')
|
87
|
-
@
|
86
|
+
@route_set.generator.generate(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
|
88
87
|
end
|
89
88
|
|
90
89
|
it "should generate a route with a specific host" do
|
91
90
|
caf = @route_set.add_named_route(:name, '/:controller/:action.:format', :generate_with => {:host => 'www.slashdot.org', :port => 80})
|
92
|
-
@
|
91
|
+
@route_set.generator.generate_full(:name, Rack::Request.new(Rack::MockRequest.env_for("http://localhost:8080")), ['controller', 'action', 'html']).should == 'http://www.slashdot.org/controller/action.html'
|
93
92
|
end
|
94
93
|
|
95
94
|
it "should require all the parameters (hash) to generate a route" do
|
96
|
-
proc
|
95
|
+
proc{@route_set.generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller'})}.should raise_error(Usher::MissingParameterException)
|
97
96
|
end
|
98
97
|
|
99
98
|
it "should generate from a route" do
|
100
|
-
@
|
99
|
+
@route_set.generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
|
101
100
|
end
|
102
101
|
|
103
102
|
it "should require all the parameters (array) to generate a route" do
|
104
103
|
@route_set.add_named_route(:name, '/:controller/:action.:format')
|
105
|
-
proc {@
|
104
|
+
proc {@route_set.generator.generate(:name, ['controller', 'action'])}.should raise_error(Usher::MissingParameterException)
|
106
105
|
end
|
107
106
|
|
108
107
|
it "should generate a route when only one parameter is given" do
|
109
108
|
@route_set.add_named_route(:name, '/:controller')
|
110
|
-
@
|
109
|
+
@route_set.generator.generate(:name, 'controller').should == '/controller'
|
111
110
|
end
|
112
111
|
|
113
112
|
it "should generate the correct route from a route containing optional parts" do
|
114
113
|
@route_set.add_named_route(:name, '/:controller(/:action(/:id))')
|
115
|
-
@
|
116
|
-
@
|
117
|
-
@
|
114
|
+
@route_set.generator.generate(:name, {:controller => 'controller'}).should == '/controller'
|
115
|
+
@route_set.generator.generate(:name, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
|
116
|
+
@route_set.generator.generate(:name, {:controller => 'controller', :action => 'action', :id => 'id'}).should == '/controller/action/id'
|
118
117
|
end
|
119
118
|
|
120
119
|
it "should generate a route using defaults for everything but the first parameter" do
|
121
120
|
@route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
|
122
|
-
@
|
121
|
+
@route_set.generator.generate(:name, {:one => "1"}).should == '/1/two/three'
|
123
122
|
end
|
124
123
|
|
125
124
|
it "should generate a route using defaults for everything" do
|
126
125
|
@route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
|
127
|
-
@
|
126
|
+
@route_set.generator.generate(:name).should == '/one/two/three'
|
128
127
|
end
|
129
128
|
|
130
129
|
it "should generate a route using defaults and optionals using the last parameter" do
|
131
130
|
@route_set.add_named_route(:opts_with_defaults, '/:one(/:two(/:three))', {:default_values => {:one => '1', :two => '2', :three => '3'}})
|
132
|
-
@
|
131
|
+
@route_set.generator.generate(:opts_with_defaults, {:three => 'three'}).should == '/1/2/three'
|
133
132
|
end
|
134
133
|
|
135
134
|
it "should generate a route with optional segments given two nested optional parameters" do
|
136
135
|
@route_set.add_named_route(:optionals, '/:controller(/:action(/:id))(.:format)')
|
137
|
-
@
|
136
|
+
@route_set.generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "nested generation" do
|
140
|
+
before do
|
141
|
+
@route_set2 = Usher.new(:generator => Usher::Util::Generators::URL.new)
|
142
|
+
@route_set3 = Usher.new(:generator => Usher::Util::Generators::URL.new)
|
143
|
+
@route_set4 = Usher.new(:generator => Usher::Util::Generators::URL.new)
|
144
|
+
|
145
|
+
@route_set.add_named_route(:simple, "/mount_point").match_partially!.to(@route_set2)
|
146
|
+
@route_set.add_route("/third/:foo", :default_values => {:foo => "foo"}).match_partially!.to(@route_set3)
|
147
|
+
@route_set.add_route("/fourth/:bar").match_partially!.to(@route_set4)
|
148
|
+
|
149
|
+
@route_set2.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
|
150
|
+
@route_set2.add_named_route(:nested_complex, "/another_nested(/:complex)", :controller => "nested", :action => "complex")
|
151
|
+
|
152
|
+
@route_set3.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
|
153
|
+
@route_set3.add_named_route(:nested_complex, "/another_nested(/:complex)", :controller => "nested", :action => "complex")
|
154
|
+
|
155
|
+
@route_set4.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should generate a route for the simple nested route" do
|
159
|
+
@route_set2.generator.generate(:nested_simple).should == "/mount_point/nested/simple"
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should generate a simple route without optional segments" do
|
163
|
+
@route_set2.generator.generate(:nested_complex).should == "/mount_point/another_nested"
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should generate a route with optional segements" do
|
167
|
+
@route_set2.generator.generate(:nested_complex, :complex => "foo").should == "/mount_point/another_nested/foo"
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should genearte a route with the specified value for the parent route" do
|
171
|
+
@route_set3.generator.generate(:nested_simple, :foo => "bar").should == "/third/bar/nested/simple"
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should generate a route with the default value from the parent route" do
|
175
|
+
@route_set3.generator.generate(:nested_simple).should == "/third/foo/nested/simple"
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should generate a route with an optional segement in the parent and child" do
|
179
|
+
@route_set3.generator.generate(:nested_complex, :complex => "complex").should == "/third/foo/another_nested/complex"
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should generate a route without the optional value from the child" do
|
183
|
+
@route_set3.generator.generate(:nested_complex).should == "/third/foo/another_nested"
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should raise an exception when trying to generate a route where the parent variable is not defined and does not have a default value" do
|
187
|
+
lambda do
|
188
|
+
@route_set4.generator.generate(:nested_simple)
|
189
|
+
end.should raise_error(Usher::MissingParameterException)
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
|
138
194
|
end
|
139
|
-
|
140
|
-
|
141
195
|
end
|
@@ -4,31 +4,30 @@ require 'lib/usher'
|
|
4
4
|
describe "Usher grapher" do
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
-
@route_set = Usher.new
|
7
|
+
@route_set = Usher.new(:generator => Usher::Util::Generators::URL.new)
|
8
8
|
@route_set.reset!
|
9
|
-
@url_generator = Usher::Util::Generators::URL.new(@route_set)
|
10
9
|
end
|
11
10
|
|
12
11
|
it "should find a simple path" do
|
13
12
|
@route_set.add_route('/:a/:b/:c')
|
14
|
-
@
|
13
|
+
@route_set.generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
|
15
14
|
end
|
16
15
|
|
17
16
|
it "should pick a more specific route" do
|
18
17
|
@route_set.add_route('/:a/:b')
|
19
18
|
@route_set.add_route('/:a/:b/:c')
|
20
|
-
@
|
19
|
+
@route_set.generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
|
21
20
|
end
|
22
21
|
|
23
22
|
it "should fail to generate a route when none matches" do
|
24
23
|
@route_set.add_route('/:a/:b')
|
25
|
-
proc {@
|
24
|
+
proc {@route_set.generator.generate(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should find the most specific route and append extra parts on as a query string" do
|
29
28
|
@route_set.add_route('/:a/:b/:c')
|
30
29
|
@route_set.add_route('/:a/:b')
|
31
|
-
@
|
30
|
+
@route_set.generator.generate(nil, {:a => 'A', :b => 'B', :d => 'C'}).should == '/A/B?d=C'
|
32
31
|
end
|
33
32
|
|
34
33
|
# FIXME
|
data/spec/private/path_spec.rb
CHANGED
@@ -36,18 +36,27 @@ describe "Usher route adding" do
|
|
36
36
|
route_set.add_named_route(:route, '/bad/route', :controller => 'sample').should == route_set.named_routes[:route]
|
37
37
|
end
|
38
38
|
|
39
|
+
it "should allow named routes to be added" do
|
40
|
+
route_set.add_named_route(:route, '/bad/route', :controller => 'sample').should == route_set.named_routes[:route]
|
41
|
+
route_set.route_count.should == 1
|
42
|
+
route_set.named_routes.size == 1
|
43
|
+
route_set.delete_named_route(:route, '/bad/route', :controller => 'sample')
|
44
|
+
route_set.route_count.should == 0
|
45
|
+
route_set.named_routes.size == 0
|
46
|
+
end
|
47
|
+
|
39
48
|
it "should calculate depths for nodes" do
|
40
49
|
route_set.add_named_route(:route, '/bad/route/three/four')
|
41
|
-
route_set.
|
42
|
-
route_set.
|
50
|
+
route_set.root.depth.should == 0
|
51
|
+
route_set.root.lookup['/'].depth.should == 1
|
43
52
|
end
|
44
53
|
|
45
54
|
it "should pp for nodes" do
|
46
55
|
route_set.add_named_route(:route, '/bad/route/three/four')
|
47
|
-
route_set.
|
56
|
+
route_set.root.depth.should == 0
|
48
57
|
old_out = $stdout
|
49
58
|
$stdout = (output = StringIO.new)
|
50
|
-
route_set.
|
59
|
+
route_set.root.lookup['/'].lookup['bad'].lookup['/'].pp
|
51
60
|
$stdout = old_out
|
52
61
|
output.rewind
|
53
62
|
output.read.should == <<-HEREDOC
|
@@ -64,5 +73,27 @@ describe "Usher route adding" do
|
|
64
73
|
8: "four" true
|
65
74
|
HEREDOC
|
66
75
|
end
|
76
|
+
|
77
|
+
describe "merging paths" do
|
78
|
+
before do
|
79
|
+
@r1 = route_set.add_route("/foo/bar")
|
80
|
+
@r2 = route_set.add_route("/other(/:baz)")
|
81
|
+
@p1 = @r1.paths.first
|
82
|
+
@p2 = @r2.paths.first
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should craete a new path object" do
|
86
|
+
@p1.merge(@p2).should_not eql(@p1)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should mash the parts together" do
|
90
|
+
@p1.merge(@p2).parts.should == (@p1.parts + @p2.parts).flatten
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should maintain the route owner" do
|
94
|
+
@p1.merge(@p2).route.should == @p1.route
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
67
98
|
|
68
99
|
end
|
@@ -1,29 +1,114 @@
|
|
1
1
|
require 'lib/usher'
|
2
|
-
|
3
2
|
require 'rack'
|
4
3
|
|
4
|
+
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper")
|
5
5
|
route_set = Usher::Interface.for(:rack)
|
6
|
+
route_set.extend(CallWithMockRequestMixin)
|
6
7
|
|
7
8
|
describe "Usher (for rack) route dispatching" do
|
8
|
-
|
9
9
|
before(:each) do
|
10
10
|
route_set.reset!
|
11
|
+
@app = MockApp.new("Hello World!")
|
12
|
+
route_set.add('/sample').to(@app)
|
11
13
|
end
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
describe "HTTP GET" do
|
16
|
+
it "should dispatch a request" do
|
17
|
+
response = route_set.call_with_mock_request
|
18
|
+
response.body.should eql("Hello World!")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should write usher.params" do
|
22
|
+
response = route_set.call_with_mock_request
|
23
|
+
@app.env["usher.params"].should == {}
|
24
|
+
end
|
18
25
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
|
27
|
+
describe "HTTP POST" do
|
28
|
+
before(:each) do
|
29
|
+
bad_app = MockApp.new("You shouldn't get here if you are using POST")
|
30
|
+
route_set.add('/sample').to(bad_app)
|
31
|
+
route_set.add('/sample', :requirements => {:request_method => 'POST'}).to(@app)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should dispatch a request" do
|
35
|
+
response = route_set.call_with_mock_request
|
36
|
+
response.body.should eql("Hello World!")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should write usher.params" do
|
40
|
+
response = route_set.call_with_mock_request("/sample", :request_method => 'POST')
|
41
|
+
@app.env["usher.params"].should == {}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should returns HTTP 404 if route doesn't exist" do
|
46
|
+
response = route_set.call_with_mock_request("/not-existing-url")
|
47
|
+
response.status.should eql(404)
|
27
48
|
end
|
28
49
|
|
50
|
+
describe "mounted rack instances" do
|
51
|
+
before do
|
52
|
+
@bad_app = mock("bad_app")
|
53
|
+
|
54
|
+
@usher2 = Usher::Interface.for(:rack)
|
55
|
+
@usher2.add("/good" ).to(@app)
|
56
|
+
@usher2.add("/bad" ).match_partially!.to(@bad_app)
|
57
|
+
@usher2.add("/some(/:foo)").to(@app)
|
58
|
+
|
59
|
+
route_set.add("/foo/:bar", :default_values => {:foo => "foo"}).match_partially!.to(@usher2)
|
60
|
+
route_set.add("/foo", :default_values => {:controller => :foo}).to(@app)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should match the route without nesting" do
|
64
|
+
@app.should_receive(:call).once.with{ |e| e['usher.params'].should == {:controller => :foo}}
|
65
|
+
route_set.call(Rack::MockRequest.env_for("/foo"))
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should route through the first route, and the second to the app" do
|
69
|
+
@app.should_receive(:call).once.with{|e| e['usher.params'].should == {:bar => "bar", :foo => "foo"}}
|
70
|
+
result = route_set.call(Rack::MockRequest.env_for("/foo/bar/good"))
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should go through to the bad app" do
|
74
|
+
@bad_app.should_receive(:call).once.with{|e| e['usher.params'].should == {:bar => "some_bar", :foo => "foo"}}
|
75
|
+
result = route_set.call(Rack::MockRequest.env_for("/foo/some_bar/bad"))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should match optional routes paramters" do
|
79
|
+
@app.should_receive(:call).once.with{|e| e['usher.params'].should == {:bar => "bar", :foo => "a_different_foo"}}
|
80
|
+
route_set.call(Rack::MockRequest.env_for("/foo/bar/some/a_different_foo"))
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "SCRIPT_NAME & PATH_INFO" do
|
84
|
+
it "should update the script name for a fully consumed route" do
|
85
|
+
@app.should_receive(:call).once.with do |e|
|
86
|
+
e['SCRIPT_NAME'].should == "/foo"
|
87
|
+
e['PATH_INFO'].should == ""
|
88
|
+
end
|
89
|
+
route_set.call(Rack::MockRequest.env_for("/foo"))
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should update the script name and path info for a partially consumed route" do
|
93
|
+
@app.should_receive(:call).once.with do |e|
|
94
|
+
e['SCRIPT_NAME'].should == "/partial"
|
95
|
+
e['PATH_INFO'].should == "/bar/baz"
|
96
|
+
end
|
97
|
+
|
98
|
+
route_set.add("/partial").match_partially!.to(@app)
|
99
|
+
route_set.call(Rack::MockRequest.env_for("/partial/bar/baz"))
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should consume the path through a mounted usher" do
|
103
|
+
@bad_app.should_receive(:call).once.with do |e|
|
104
|
+
e['SCRIPT_NAME'].should == "/foo/bar/bad"
|
105
|
+
e['PATH_INFO'].should == "/leftovers"
|
106
|
+
end
|
107
|
+
|
108
|
+
route_set.call(Rack::MockRequest.env_for("/foo/bar/bad/leftovers"))
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
29
114
|
end
|