usher 0.5.3 → 0.5.4
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/VERSION.yml +2 -2
- data/lib/usher/interface/rack_interface.rb +9 -0
- data/lib/usher/node.rb +148 -72
- data/lib/usher/route/request_method.rb +5 -0
- data/lib/usher.rb +15 -1
- data/spec/private/path_spec.rb +1 -24
- data/spec/private/rack/dispatch_spec.rb +50 -0
- data/spec/private/recognize_spec.rb +53 -3
- metadata +2 -2
data/VERSION.yml
CHANGED
@@ -25,6 +25,15 @@ class Usher
|
|
25
25
|
instance_eval(&blk) if blk
|
26
26
|
end
|
27
27
|
|
28
|
+
def dup
|
29
|
+
new_one = super
|
30
|
+
original = self
|
31
|
+
new_one.instance_eval do
|
32
|
+
@router = router.dup
|
33
|
+
end
|
34
|
+
new_one
|
35
|
+
end
|
36
|
+
|
28
37
|
def add(path, options = nil)
|
29
38
|
@router.add_route(path, options)
|
30
39
|
end
|
data/lib/usher/node.rb
CHANGED
@@ -6,23 +6,40 @@ class Usher
|
|
6
6
|
|
7
7
|
Response = Struct.new(:path, :params, :remaining_path, :matched_path)
|
8
8
|
|
9
|
-
attr_reader :
|
10
|
-
attr_accessor :terminates, :
|
9
|
+
attr_reader :normal, :greedy, :request
|
10
|
+
attr_accessor :terminates, :request_method_type, :parent, :value, :request_methods
|
11
11
|
|
12
12
|
def initialize(parent, value)
|
13
13
|
@parent = parent
|
14
14
|
@value = value
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
15
|
+
@request = nil
|
16
|
+
@normal = nil
|
17
|
+
@greedy = nil
|
18
|
+
@request_method_type = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def activate_normal!
|
22
|
+
@normal ||= Hash.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def activate_greedy!
|
26
|
+
@greedy ||= Hash.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def activate_request!
|
30
|
+
@request ||= Hash.new
|
18
31
|
end
|
19
32
|
|
20
|
-
def
|
21
|
-
@
|
33
|
+
def upgrade_normal!
|
34
|
+
@normal = FuzzyHash.new(@normal)
|
22
35
|
end
|
23
36
|
|
24
|
-
def
|
25
|
-
@
|
37
|
+
def upgrade_greedy!
|
38
|
+
@greedy = FuzzyHash.new(@greedy)
|
39
|
+
end
|
40
|
+
|
41
|
+
def upgrade_request!
|
42
|
+
@request = FuzzyHash.new(@request)
|
26
43
|
end
|
27
44
|
|
28
45
|
def depth
|
@@ -30,7 +47,7 @@ class Usher
|
|
30
47
|
end
|
31
48
|
|
32
49
|
def greedy?
|
33
|
-
!@
|
50
|
+
@greedy && !@greedy.empty?
|
34
51
|
end
|
35
52
|
|
36
53
|
def self.root(route_set, request_methods)
|
@@ -45,12 +62,22 @@ class Usher
|
|
45
62
|
|
46
63
|
def pp
|
47
64
|
$stdout << " " * depth
|
48
|
-
$stdout << "#{depth}: #{value.inspect}
|
49
|
-
|
65
|
+
$stdout << "#{terminates? ? '* ' : ''}#{depth}: #{value.inspect}\n"
|
66
|
+
normal.each do |k,v|
|
50
67
|
$stdout << " " * (depth + 1)
|
51
|
-
$stdout << "#{k} ==> \n"
|
68
|
+
$stdout << ". #{k.inspect} ==> \n"
|
52
69
|
v.pp
|
53
|
-
end
|
70
|
+
end if normal
|
71
|
+
greedy.each do |k,v|
|
72
|
+
$stdout << " " * (depth + 1)
|
73
|
+
$stdout << "g #{k.inspect} ==> \n"
|
74
|
+
v.pp
|
75
|
+
end if greedy
|
76
|
+
request.each do |k,v|
|
77
|
+
$stdout << " " * (depth + 1)
|
78
|
+
$stdout << "r #{k.inspect} ==> \n"
|
79
|
+
v.pp
|
80
|
+
end if request
|
54
81
|
end
|
55
82
|
|
56
83
|
def add(route)
|
@@ -67,37 +94,38 @@ class Usher
|
|
67
94
|
|
68
95
|
def unique_routes(node = self, routes = [])
|
69
96
|
routes << node.terminates.route if node.terminates
|
70
|
-
node.
|
97
|
+
node.normal.values.each do |v|
|
71
98
|
unique_routes(v, routes)
|
72
|
-
end
|
73
|
-
node.
|
99
|
+
end if node.normal
|
100
|
+
node.greedy.values.each do |v|
|
74
101
|
unique_routes(v, routes)
|
75
|
-
end
|
102
|
+
end if node.greedy
|
103
|
+
node.request.values.each do |v|
|
104
|
+
unique_routes(v, routes)
|
105
|
+
end if node.request
|
76
106
|
routes.uniq!
|
77
107
|
routes
|
78
108
|
end
|
79
109
|
|
80
|
-
def find(usher,
|
81
|
-
if
|
82
|
-
[
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
nil
|
88
|
-
elsif terminates? && (path.size.zero? || terminates.route.partial_match?)
|
89
|
-
if terminates.route.partial_match?
|
90
|
-
Response.new(terminates, params, original_path[position, original_path.size], original_path[0, position])
|
110
|
+
def find(usher, request_object, original_path, path, params = [], position = 0)
|
111
|
+
if request_method_type
|
112
|
+
if (specific_node = request[request_object.send(request_method_type)]) && (ret = specific_node.find(usher, request_object, original_path, path.dup, params.dup, position))
|
113
|
+
ret
|
114
|
+
elsif (general_node = request[nil]) && (ret = general_node.find(usher, request_object, original_path, path.dup, params.dup, position))
|
115
|
+
ret
|
91
116
|
else
|
92
|
-
|
117
|
+
nil
|
93
118
|
end
|
94
|
-
|
95
|
-
|
119
|
+
elsif terminates? && (path.empty? || terminates.route.partial_match?)
|
120
|
+
terminates.route.partial_match? ?
|
121
|
+
Response.new(terminates, params, original_path[position, original_path.size], original_path[0, position]) :
|
122
|
+
Response.new(terminates, params, nil, original_path)
|
123
|
+
elsif !path.empty? && (greedy? && (match_with_result_output = greedy.match_with_result(whole_path = original_path[position, original_path.size])))
|
96
124
|
next_path, matched_part = match_with_result_output
|
97
125
|
position += matched_part.size
|
98
126
|
params << [next_path.value.name, whole_path.slice!(0, matched_part.size)]
|
99
|
-
next_path.find(usher,
|
100
|
-
elsif !path.
|
127
|
+
next_path.find(usher, request_object, original_path, whole_path.empty? ? whole_path : usher.splitter.url_split(whole_path), params, position)
|
128
|
+
elsif !path.empty? && normal && (next_part = normal[part = path.shift] || normal[nil])
|
101
129
|
position += part.size
|
102
130
|
case next_part.value
|
103
131
|
when Route::Variable::Glob
|
@@ -115,7 +143,7 @@ class Usher
|
|
115
143
|
next_part.value.valid!(part)
|
116
144
|
params.last.last << part
|
117
145
|
end
|
118
|
-
if path.
|
146
|
+
if path.empty?
|
119
147
|
break
|
120
148
|
else
|
121
149
|
part = path.shift
|
@@ -131,59 +159,107 @@ class Usher
|
|
131
159
|
params.last.last << next_path_part
|
132
160
|
end
|
133
161
|
end
|
134
|
-
next_part.find(usher,
|
162
|
+
next_part.find(usher, request_object, original_path, path, params, position)
|
135
163
|
else
|
136
164
|
nil
|
137
165
|
end
|
138
166
|
end
|
139
167
|
|
140
168
|
private
|
169
|
+
|
141
170
|
def set_path_with_destination(path, destination = path)
|
142
|
-
|
143
|
-
|
144
|
-
|
171
|
+
node = path.parts.inject(self){ |node, key| process_path_part(node, key) }
|
172
|
+
node = process_request_parts(node, request_methods_for_path(path))
|
173
|
+
|
174
|
+
while node.request_method_type
|
175
|
+
node = (node.request[nil] ||= Node.new(node, Route::RequestMethod.new(node.request_method_type, nil)))
|
145
176
|
end
|
146
|
-
|
147
|
-
|
148
|
-
|
177
|
+
|
178
|
+
node.terminates = destination
|
179
|
+
end
|
180
|
+
|
181
|
+
def request_method_index(type)
|
182
|
+
request_methods.index(type)
|
183
|
+
end
|
184
|
+
|
185
|
+
def process_request_parts(node, parts)
|
186
|
+
while parts.any?{ |p| !p.trivial? }
|
149
187
|
key = parts.shift
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
188
|
+
|
189
|
+
next if key.trivial?
|
190
|
+
|
191
|
+
node.activate_request!
|
192
|
+
|
193
|
+
node = if node.request_method_type.nil?
|
194
|
+
node.request_method_type = key.type
|
195
|
+
node.upgrade_request! if key.value.is_a?(Regexp)
|
196
|
+
node.request[key.value] ||= Node.new(node, key)
|
197
|
+
else
|
198
|
+
case request_method_index(node.request_method_type) <=> request_method_index(key.type)
|
199
|
+
when -1
|
159
200
|
parts.unshift(key)
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
when
|
165
|
-
|
166
|
-
|
167
|
-
|
201
|
+
node.request[key.value] ||= Node.new(node, Route::RequestMethod.new(node.request_method_type, nil))
|
202
|
+
when 0
|
203
|
+
node.upgrade_request! if key.value.is_a?(Regexp)
|
204
|
+
node.request[key.value] ||= Node.new(node, key)
|
205
|
+
when 1
|
206
|
+
previous_node = node.parent
|
207
|
+
current_node_entry_key = nil
|
208
|
+
current_node_entry_lookup = nil
|
209
|
+
[previous_node.normal, previous_node.greedy, previous_node.request].compact.each do |l|
|
210
|
+
current_node_entry_key = l.each{|k,v| break k if node == v}
|
211
|
+
current_node_entry_lookup = l and break if current_node_entry_key
|
212
|
+
end
|
213
|
+
|
214
|
+
current_node_entry_lookup.respond_to?(:delete_value) ?
|
215
|
+
current_node_entry_lookup.delete_value(node) : current_node_entry_lookup.delete_if{|k,v| v == node}
|
216
|
+
|
217
|
+
new_node = Node.new(previous_node, Route::RequestMethod.new(key.type, nil))
|
218
|
+
new_node.activate_request!
|
219
|
+
new_node.request_method_type = key.type
|
220
|
+
current_node_entry_lookup[current_node_entry_key] = new_node
|
221
|
+
node.parent = new_node
|
222
|
+
new_node.request[nil] = node
|
223
|
+
parts.unshift(key)
|
224
|
+
|
225
|
+
new_node
|
168
226
|
end
|
169
|
-
|
170
|
-
if key.regex_matcher
|
171
|
-
current_node.send(upgrade_method)
|
172
|
-
current_node.send(lookup_method)[key.regex_matcher] ||= Node.new(current_node, key)
|
173
|
-
else
|
174
|
-
current_node.send(lookup_method)[nil] ||= Node.new(current_node, key)
|
175
|
-
end
|
176
|
-
else
|
177
|
-
|
178
|
-
current_node.upgrade_lookup if key.is_a?(Regexp)
|
179
|
-
current_node.lookup[key] ||= Node.new(current_node, key)
|
180
227
|
end
|
181
|
-
current_node = target_node
|
182
228
|
end
|
229
|
+
node
|
230
|
+
end
|
183
231
|
|
184
|
-
|
232
|
+
|
233
|
+
def process_path_part(node, key)
|
234
|
+
case key
|
235
|
+
when Route::Variable::Greedy
|
236
|
+
node.activate_greedy!
|
237
|
+
if key.regex_matcher
|
238
|
+
node.upgrade_greedy!
|
239
|
+
node.greedy[key.regex_matcher] ||= Node.new(node, key)
|
240
|
+
else
|
241
|
+
node.greedy[nil] ||= Node.new(node, key)
|
242
|
+
end
|
243
|
+
when Route::Variable
|
244
|
+
node.activate_normal!
|
245
|
+
if key.regex_matcher
|
246
|
+
node.upgrade_normal!
|
247
|
+
node.normal[key.regex_matcher] ||= Node.new(node, key)
|
248
|
+
else
|
249
|
+
node.normal[nil] ||= Node.new(node, key)
|
250
|
+
end
|
251
|
+
else
|
252
|
+
node.activate_normal!
|
253
|
+
node.upgrade_normal! if key.is_a?(Regexp)
|
254
|
+
node.normal[key] ||= Node.new(node, key)
|
255
|
+
end
|
185
256
|
end
|
186
257
|
|
258
|
+
def request_methods_for_path(path)
|
259
|
+
request_methods.collect do |type|
|
260
|
+
Route::RequestMethod.new(type, path.route.conditions && path.route.conditions[type])
|
261
|
+
end
|
262
|
+
end
|
187
263
|
|
188
264
|
end
|
189
265
|
end
|
data/lib/usher.rb
CHANGED
@@ -221,6 +221,20 @@ class Usher
|
|
221
221
|
routes.each{|r| r.parent_route = route}
|
222
222
|
end
|
223
223
|
|
224
|
+
def dup
|
225
|
+
replacement = super
|
226
|
+
original = self
|
227
|
+
replacement.instance_eval do
|
228
|
+
reset!
|
229
|
+
original.routes.each do |route|
|
230
|
+
@root.add(route)
|
231
|
+
@routes << route
|
232
|
+
end
|
233
|
+
rebuild_grapher!
|
234
|
+
end
|
235
|
+
replacement
|
236
|
+
end
|
237
|
+
|
224
238
|
private
|
225
239
|
|
226
240
|
attr_accessor :request_methods
|
@@ -255,7 +269,7 @@ class Usher
|
|
255
269
|
if options
|
256
270
|
options.delete_if do |k, v|
|
257
271
|
if v.is_a?(Regexp) || v.is_a?(Proc)
|
258
|
-
(requirements ||= {})[k] = v
|
272
|
+
(requirements ||= {})[k] = v
|
259
273
|
true
|
260
274
|
end
|
261
275
|
end
|
data/spec/private/path_spec.rb
CHANGED
@@ -48,32 +48,9 @@ describe "Usher route adding" do
|
|
48
48
|
it "should calculate depths for nodes" do
|
49
49
|
route_set.add_named_route(:route, '/bad/route/three/four')
|
50
50
|
route_set.root.depth.should == 0
|
51
|
-
route_set.root.
|
51
|
+
route_set.root.normal['/'].depth.should == 1
|
52
52
|
end
|
53
53
|
|
54
|
-
it "should pp for nodes" do
|
55
|
-
route_set.add_named_route(:route, '/bad/route/three/four')
|
56
|
-
route_set.root.depth.should == 0
|
57
|
-
old_out = $stdout
|
58
|
-
$stdout = (output = StringIO.new)
|
59
|
-
route_set.root.lookup['/'].lookup['bad'].lookup['/'].pp
|
60
|
-
$stdout = old_out
|
61
|
-
output.rewind
|
62
|
-
output.read.should == <<-HEREDOC
|
63
|
-
3: "/" false
|
64
|
-
route ==>
|
65
|
-
4: "route" false
|
66
|
-
/ ==>
|
67
|
-
5: "/" false
|
68
|
-
three ==>
|
69
|
-
6: "three" false
|
70
|
-
/ ==>
|
71
|
-
7: "/" false
|
72
|
-
four ==>
|
73
|
-
8: "four" true
|
74
|
-
HEREDOC
|
75
|
-
end
|
76
|
-
|
77
54
|
describe "merging paths" do
|
78
55
|
before do
|
79
56
|
@r1 = route_set.add_route("/foo/bar")
|
@@ -119,5 +119,55 @@ describe "Usher (for rack) route dispatching" do
|
|
119
119
|
|
120
120
|
end
|
121
121
|
|
122
|
+
describe "dupping" do
|
123
|
+
before do
|
124
|
+
@app = mock("app")
|
125
|
+
@u1 = Usher::Interface.for(:rack)
|
126
|
+
@u2 = Usher::Interface.for(:rack)
|
127
|
+
|
128
|
+
@u1.add("/one", :default_values => {:one => :one}).to(@app)
|
129
|
+
@u1.add("/mount").match_partially!.to(@u2)
|
130
|
+
|
131
|
+
@u2.add("/app", :default_values => {:foo => :bar}).to(@app)
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should allow me to dup the router" do
|
136
|
+
@app.should_receive(:call).twice.with{|e| e['usher.params'].should == {:one => :one}}
|
137
|
+
@u1.call(Rack::MockRequest.env_for("/one"))
|
138
|
+
u1_dash = @u1.dup
|
139
|
+
u1_dash.call(Rack::MockRequest.env_for("/one"))
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should allow me to dup the router and add a new route without polluting the original" do
|
143
|
+
@app.should_receive(:call).with{|e| e['usher.params'].should == {:foo => :bar}}
|
144
|
+
u1_dash = @u1.dup
|
145
|
+
u1_dash.add("/foo", :default_values => {:foo => :bar}).to(@app)
|
146
|
+
u1_dash.call(Rack::MockRequest.env_for("/foo"))
|
147
|
+
@app.should_not_receive(:call)
|
148
|
+
@u1.call(Rack::MockRequest.env_for("/foo"))
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should allow me to dup the router and nested routers should remain intact" do
|
152
|
+
@app.should_receive(:call).with{|e| e['usher.params'].should == {:foo => :bar}}
|
153
|
+
u1_dash = @u1.dup
|
154
|
+
u1_dash.call(Rack::MockRequest.env_for("/mount/app"))
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should allow me to dup the router and add more routes" do
|
158
|
+
@app.should_receive(:call).with{|e| e['usher.params'].should == {:another => :bar}}
|
159
|
+
|
160
|
+
u3 = Usher::Interface.for(:rack)
|
161
|
+
u1_dash = @u1.dup
|
162
|
+
|
163
|
+
u3.add("/another_bar", :default_values => {:another => :bar}).to(@app)
|
164
|
+
u1_dash.add("/some/mount").match_partially!.to(u3)
|
165
|
+
|
166
|
+
u1_dash.call(Rack::MockRequest.env_for("/some/mount/another_bar"))
|
167
|
+
|
168
|
+
@app.should_not_receive(:call)
|
169
|
+
@u1.call(Rack::MockRequest.env_for("/some/mount/another_bar"))
|
170
|
+
end
|
171
|
+
end
|
122
172
|
end
|
123
173
|
end
|
@@ -31,14 +31,17 @@ describe "Usher route recognition" do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should recognize a specific route when several http-style restrictions are used" do
|
34
|
+
target_route_http_admin_generic = route_set.add_route('/sample', :conditions => {:domain => 'admin.spec.com'})
|
34
35
|
target_route_http_admin = route_set.add_route('/sample', :conditions => {:protocol => 'http', :domain => 'admin.spec.com'})
|
35
36
|
target_route_http_www = route_set.add_route('/sample', :conditions => {:protocol => 'http', :domain => 'www.spec.com'})
|
36
|
-
target_route_https_msie = route_set.add_route('/sample', :conditions => {:protocol => 'https', :user_agent => 'MSIE 6.0'})
|
37
|
+
target_route_https_msie = route_set.add_route('/sample', :conditions => {:protocol => 'https', :domain => 'admin.spec.com', :user_agent => 'MSIE 6.0'})
|
37
38
|
target_route_https_admin = route_set.add_route('/sample', :conditions => {:protocol => 'https', :domain => 'admin.spec.com'})
|
38
39
|
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'http', :domain => 'admin.spec.com', :user_agent => nil})).path.route.should == target_route_http_admin
|
39
40
|
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'http', :domain => 'www.spec.com', :user_agent => nil})).path.route.should == target_route_http_www
|
40
41
|
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'https', :domain => 'admin.spec.com', :user_agent => 'MSIE 6.0'})).path.route.should == target_route_https_msie
|
41
42
|
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'https', :domain => 'admin.spec.com', :user_agent => nil})).path.route.should == target_route_https_admin
|
43
|
+
route_set.recognize(build_request({:method => 'put', :path => '/sample', :protocol => 'wacky', :domain => 'admin.spec.com', :user_agent => nil})).path.route.should == target_route_http_admin_generic
|
44
|
+
|
42
45
|
end
|
43
46
|
|
44
47
|
it "should correctly fix that tree if conditionals are used later" do
|
@@ -178,8 +181,8 @@ describe "Usher route recognition" do
|
|
178
181
|
|
179
182
|
it "should use a requirement (proc) on incoming variables" do
|
180
183
|
route_set.add_route('/:controller/:action/:id', :id => proc{|v| Integer(v)})
|
181
|
-
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'}))}.should_not raise_error
|
182
|
-
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'}))}.should raise_error
|
184
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'}))}.should_not raise_error(Usher::ValidationException)
|
185
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'}))}.should raise_error(Usher::ValidationException)
|
183
186
|
end
|
184
187
|
|
185
188
|
it "shouldn't care about mildly weird characters in the URL" do
|
@@ -213,4 +216,51 @@ describe "Usher route recognition" do
|
|
213
216
|
end
|
214
217
|
|
215
218
|
end
|
219
|
+
|
220
|
+
describe "dup safety" do
|
221
|
+
before do
|
222
|
+
route_set.add_route("/foo", :foo => "foo")
|
223
|
+
@r2 = route_set.dup
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should provide a different object" do
|
227
|
+
route_set.should_not eql(@r2)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should recognize the originals routes in the dup" do
|
231
|
+
route_set.recognize(build_request(:path => "/foo")).path.route.destination.should == {:foo =>"foo"}
|
232
|
+
@r2.recognize( build_request(:path => "/foo")).path.route.destination.should == {:foo =>"foo"}
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should not add routes added to the dup to the original" do
|
236
|
+
@r2.add_route("/bar", :bar => "bar")
|
237
|
+
@r2.recognize( build_request(:path => "/bar")).path.route.destination.should == {:bar => "bar"}
|
238
|
+
route_set.recognize( build_request(:path => "/bar")).should == nil
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should not delete routes added to the dup to the original" do
|
242
|
+
@r2.delete_route("/foo")
|
243
|
+
route_set.recognize( build_request(:path => "/foo")).path.route.destination.should == {:foo => "foo"}
|
244
|
+
@r2.recognize( build_request(:path => "/foo")).should == nil
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
it "should safely dup with nested ushers" do
|
249
|
+
r1 = Usher.new
|
250
|
+
r2 = Usher.new
|
251
|
+
r3 = Usher.new
|
252
|
+
|
253
|
+
r1.add_route("/mounted" ).match_partially!.to(r2)
|
254
|
+
r2.add_route("/inner" ).match_partially!.to(r3)
|
255
|
+
r3.add_route("/baz", :baz => :baz )
|
256
|
+
|
257
|
+
r1.recognize(build_request(:path => "/mounted/inner")).path.route.destination.should == r2
|
258
|
+
r4 = r1.dup
|
259
|
+
r4.recognize(build_request(:path => "/mounted/inner")).path.route.destination.should == r2
|
260
|
+
r4.add_route("/r3").match_partially!.to(r3)
|
261
|
+
r4.recognize(build_request(:path => "/r3")).path.route.destination.should == r3
|
262
|
+
r1.recognize(build_request(:path => "/r3")).should be_nil
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
216
266
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-28 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|