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.
@@ -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
- @url_generator.generate(:sample, {}).should == '/sample'
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
- @url_generator.generate(:sample, {:action => 'action'}).should == '/sample/action'
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
- @url_generator.generate(:sample, {:action => 'action time'}).should == '/sample/action%20time'
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
- @url_generator.generate(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
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
- @url_generator.generate(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
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
- @url_generator.generate(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
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
- @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
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
- @url_generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => 'zanz'}).should == '/sample/maz/zoo?third=zanz'
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?(@url_generator.generate(:sample, ['maz', 'zoo', {:third => 'zanz', :four => 'jane'}])).should == true
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
- @url_generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
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
- @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
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
- @url_generator.generate(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
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
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
76
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action', :format => 'html'}).should == '/controller/action.html'
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
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
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
- @url_generator.generate(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
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
- @url_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'
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 {@url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
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
- @url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
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 {@url_generator.generate(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
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
- @url_generator.generate(:name, 'controller').should == '/controller'
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
- @url_generator.generate(:name, {:controller => 'controller'}).should == '/controller'
116
- @url_generator.generate(:name, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
117
- @url_generator.generate(:name, {:controller => 'controller', :action => 'action', :id => 'id'}).should == '/controller/action/id'
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
- @url_generator.generate(:name, {:one => "1"}).should == '/1/two/three'
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
- @url_generator.generate(:name).should == '/one/two/three'
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
- @url_generator.generate(:opts_with_defaults, {:three => 'three'}).should == '/1/2/three'
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
- @url_generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
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
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
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
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
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 {@url_generator.generate(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
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
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :d => 'C'}).should == '/A/B?d=C'
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
@@ -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.tree.depth.should == 0
42
- route_set.tree.lookup['/'].depth.should == 1
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.tree.depth.should == 0
56
+ route_set.root.depth.should == 0
48
57
  old_out = $stdout
49
58
  $stdout = (output = StringIO.new)
50
- route_set.tree.lookup['/'].lookup['bad'].lookup['/'].pp
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
- it "should dispatch a simple request" do
14
- app = mock 'app'
15
- app.should_receive(:call).once.with {|v| v['usher.params'].should == {} }
16
- route_set.add('/sample').to(app)
17
- route_set.call(Rack::MockRequest.env_for("/sample", :method => 'GET'))
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
- it "should dispatch a POST request" do
21
- bad_app = mock 'bad_app'
22
- app = mock 'app'
23
- app.should_receive(:call).once.with {|v| v['usher.params'].should == {} }
24
- route_set.add('/sample').to(bad_app)
25
- route_set.add('/sample', :requirements => {:request_method => 'POST'}).to(app)
26
- route_set.call(Rack::MockRequest.env_for("/sample", :request_method => 'POST'))
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