joshbuddy-usher 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|