usher 0.5.12 → 0.5.13
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -0
- data/VERSION.yml +2 -2
- data/lib/usher/node.rb +14 -9
- data/lib/usher/route.rb +3 -3
- data/lib/usher/util/generate.rb +10 -3
- data/lib/usher/util/parser.rb +3 -2
- data/lib/usher.rb +15 -2
- data/spec/private/generate_spec.rb +5 -0
- data/spec/private/parser_spec.rb +1 -1
- data/spec/private/recognize_spec.rb +16 -0
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -88,6 +88,7 @@ For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <t
|
|
88
88
|
=== +options+
|
89
89
|
* +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
90
90
|
* +conditions+ - Accepts any of the +request_methods+ specificied in the construction of Usher. This can be either a <tt>string</tt> or a regular expression.
|
91
|
+
* +default_values+ - Provides values for variables in your route for generation. If you're using URL generation, then any values supplied here that aren't included in your path will be appended to the query string.
|
91
92
|
* Any other key is interpreted as a requirement for the variable of its name.
|
92
93
|
|
93
94
|
== Rails
|
data/VERSION.yml
CHANGED
data/lib/usher/node.rb
CHANGED
@@ -164,12 +164,20 @@ class Usher
|
|
164
164
|
end
|
165
165
|
next_part.find(usher, request_object, original_path, path, params, position)
|
166
166
|
elsif request_method_type
|
167
|
-
if specific_node = request[request_object.send(request_method_type)] and ret = specific_node.find(usher, request_object, original_path, path.dup, params.dup, position)
|
168
|
-
ret
|
169
|
-
|
170
|
-
|
167
|
+
return_value = if (specific_node = request[request_object.send(request_method_type)] and ret = specific_node.find(usher, request_object, original_path, path.dup, params.dup, position))
|
168
|
+
usher.priority_lookups? ? [ret] : ret
|
169
|
+
end
|
170
|
+
|
171
|
+
if usher.priority_lookups? || return_value.nil? and general_node = request[nil] and ret = general_node.find(usher, request_object, original_path, path.dup, params.dup, position)
|
172
|
+
return_value = usher.priority_lookups? && return_value ? [return_value, ret] : ret
|
173
|
+
end
|
174
|
+
|
175
|
+
unless usher.priority_lookups?
|
176
|
+
return_value
|
171
177
|
else
|
172
|
-
|
178
|
+
return_value = Array(return_value).flatten.compact
|
179
|
+
return_value.sort!{|r1, r2| r1.path.route.priority <=> r2.path.route.priority}
|
180
|
+
return_value.last
|
173
181
|
end
|
174
182
|
else
|
175
183
|
nil
|
@@ -199,11 +207,8 @@ class Usher
|
|
199
207
|
key = parts.shift
|
200
208
|
|
201
209
|
next if key.trivial?
|
202
|
-
|
203
210
|
nodes.map! do |node|
|
204
|
-
|
205
211
|
node.activate_request!
|
206
|
-
|
207
212
|
if node.request_method_type.nil?
|
208
213
|
node.request_method_type = key.type
|
209
214
|
node.upgrade_request! if key.value.is_a?(Regexp)
|
@@ -212,7 +217,7 @@ class Usher
|
|
212
217
|
case request_method_index(node.request_method_type) <=> request_method_index(key.type)
|
213
218
|
when -1
|
214
219
|
parts.unshift(key)
|
215
|
-
Array(key.value).map{|k| node.request[
|
220
|
+
Array(key.value).map{|k| node.request[nil] ||= Node.new(node, Route::RequestMethod.new(node.request_method_type, nil)) }
|
216
221
|
when 0
|
217
222
|
node.upgrade_request! if key.value.is_a?(Regexp)
|
218
223
|
Array(key.value).map{|k| node.request[k] ||= Node.new(node, key) }
|
data/lib/usher/route.rb
CHANGED
@@ -6,7 +6,7 @@ require File.join('usher', 'route', 'request_method')
|
|
6
6
|
|
7
7
|
class Usher
|
8
8
|
class Route
|
9
|
-
attr_reader :paths, :requirements, :conditions, :named, :generate_with, :default_values, :match_partially, :destination
|
9
|
+
attr_reader :paths, :requirements, :conditions, :named, :generate_with, :default_values, :match_partially, :destination, :priority
|
10
10
|
attr_accessor :parent_route, :router, :recognizable
|
11
11
|
|
12
12
|
class GenerateWith < Struct.new(:scheme, :port, :host)
|
@@ -15,8 +15,8 @@ class Usher
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def initialize(parsed_paths, router, conditions, requirements, default_values, generate_with, match_partially)
|
19
|
-
@router, @requirements, @conditions, @default_values, @match_partially = router, requirements, conditions, default_values, match_partially
|
18
|
+
def initialize(parsed_paths, router, conditions, requirements, default_values, generate_with, match_partially, priority)
|
19
|
+
@router, @requirements, @conditions, @default_values, @match_partially, @priority = router, requirements, conditions, default_values, match_partially, priority
|
20
20
|
@recognizable = true
|
21
21
|
@paths = parsed_paths.collect {|path| Path.new(self, path)}
|
22
22
|
@generate_with = GenerateWith.new(generate_with[:scheme], generate_with[:port], generate_with[:host]) if generate_with
|
data/lib/usher/util/generate.rb
CHANGED
@@ -104,13 +104,20 @@ class Usher
|
|
104
104
|
|
105
105
|
def generate_path(path, params = nil, generate_extra = true)
|
106
106
|
params = Array(params) if params.is_a?(String)
|
107
|
-
|
107
|
+
case params
|
108
|
+
when nil
|
109
|
+
params = path && path.route.default_values
|
110
|
+
when Hash
|
111
|
+
params = path.route.default_values.merge(params) if path && path.route.default_values
|
112
|
+
when String, Array
|
113
|
+
params = Array(params)
|
108
114
|
given_size = params.size
|
109
115
|
extra_params = params.last.is_a?(Hash) ? params.pop : nil
|
110
|
-
params = Hash[*path.dynamic_parts.inject([]){|a, dynamic_part| a.concat([dynamic_part.name, params.shift || raise(MissingParameterException.new("got #{given_size}, expected #{path.dynamic_parts.size} parameters"))]); a}]
|
116
|
+
params = Hash[*path.dynamic_parts.inject(path.route.default_values ? path.route.default_values.to_a : []){|a, dynamic_part| a.concat([dynamic_part.name, params.shift || raise(MissingParameterException.new("got #{given_size}, expected #{path.dynamic_parts.size} parameters"))]); a}]
|
111
117
|
params.merge!(extra_params) if extra_params
|
112
118
|
end
|
113
|
-
|
119
|
+
|
120
|
+
|
114
121
|
result = Rack::Utils.uri_escape(generate_path_for_base_params(path, params))
|
115
122
|
unless !generate_extra || params.nil? || params.empty?
|
116
123
|
extra_params = generate_extra_params(params, result[??])
|
data/lib/usher/util/parser.rb
CHANGED
@@ -18,7 +18,7 @@ class Usher
|
|
18
18
|
@delimiters_regex = Regexp.new(router.delimiters_regex)
|
19
19
|
end
|
20
20
|
|
21
|
-
def generate_route(unprocessed_path, conditions, requirements, default_values, generate_with)
|
21
|
+
def generate_route(unprocessed_path, conditions, requirements, default_values, generate_with, priority)
|
22
22
|
match_partially = if unprocessed_path.is_a?(String)
|
23
23
|
unprocessed_path = parse(unprocessed_path, requirements, default_values)
|
24
24
|
if unprocessed_path[-1] == ?*
|
@@ -73,7 +73,8 @@ class Usher
|
|
73
73
|
requirements,
|
74
74
|
default_values,
|
75
75
|
generate_with,
|
76
|
-
match_partially
|
76
|
+
match_partially,
|
77
|
+
priority
|
77
78
|
)
|
78
79
|
|
79
80
|
end
|
data/lib/usher.rb
CHANGED
@@ -11,9 +11,11 @@ require File.join('usher', 'delimiters')
|
|
11
11
|
|
12
12
|
class Usher
|
13
13
|
attr_reader :root, :named_routes, :routes, :splitter,
|
14
|
-
:delimiters, :delimiters_regex,
|
14
|
+
:delimiters, :delimiters_regex, :priority_lookups,
|
15
15
|
:parent_route, :generator, :grapher
|
16
16
|
|
17
|
+
alias_method :priority_lookups?, :priority_lookups
|
18
|
+
|
17
19
|
# Returns whether the route set is empty
|
18
20
|
#
|
19
21
|
# set = Usher.new
|
@@ -40,6 +42,7 @@ class Usher
|
|
40
42
|
@named_routes = {}
|
41
43
|
@routes = []
|
42
44
|
@grapher = Grapher.new
|
45
|
+
@priority_lookups = false
|
43
46
|
end
|
44
47
|
alias clear! reset!
|
45
48
|
|
@@ -168,6 +171,7 @@ class Usher
|
|
168
171
|
# === +options+
|
169
172
|
# * +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
170
173
|
# * +conditions+ - Accepts any of the +request_methods+ specificied in the construction of Usher. This can be either a <tt>string</tt> or a regular expression.
|
174
|
+
# * +default_values+ - Provides values for variables in your route for generation. If you're using URL generation, then any values supplied here that aren't included in your path will be appended to the query string.
|
171
175
|
# * Any other key is interpreted as a requirement for the variable of its name.
|
172
176
|
def add_route(path, options = nil)
|
173
177
|
route = get_route(path, options)
|
@@ -271,11 +275,16 @@ class Usher
|
|
271
275
|
@valid_regex
|
272
276
|
end
|
273
277
|
|
278
|
+
def enable_priority_lookups!
|
279
|
+
@priority_lookups = true
|
280
|
+
end
|
281
|
+
|
274
282
|
def get_route(path, options = nil)
|
275
283
|
conditions = options && options.delete(:conditions) || nil
|
276
284
|
requirements = options && options.delete(:requirements) || nil
|
277
285
|
default_values = options && options.delete(:default_values) || nil
|
278
286
|
generate_with = options && options.delete(:generate_with) || nil
|
287
|
+
priority = options && options.delete(:priority) || nil
|
279
288
|
if options
|
280
289
|
options.delete_if do |k, v|
|
281
290
|
if v.is_a?(Regexp) || v.is_a?(Proc)
|
@@ -289,7 +298,11 @@ class Usher
|
|
289
298
|
conditions.keys.all?{|k| request_methods.include?(k)} or raise
|
290
299
|
end
|
291
300
|
|
292
|
-
|
301
|
+
if priority
|
302
|
+
enable_priority_lookups!
|
303
|
+
end
|
304
|
+
|
305
|
+
route = parser.generate_route(path, conditions, requirements, default_values, generate_with, priority)
|
293
306
|
route.to(options) if options && !options.empty?
|
294
307
|
route
|
295
308
|
end
|
@@ -137,6 +137,11 @@ describe "Usher URL generation" do
|
|
137
137
|
@route_set.generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
|
138
138
|
end
|
139
139
|
|
140
|
+
it "should generate a route with default values that aren't represented in the path" do
|
141
|
+
@route_set.add_named_route(:default_values_not_in_path, '/:controller', :default_values => {:page => 1})
|
142
|
+
@route_set.generator.generate(:default_values_not_in_path, {:controller => "foo"}).should == '/foo?page=1'
|
143
|
+
end
|
144
|
+
|
140
145
|
describe "when named route was added with string key" do
|
141
146
|
before :each do
|
142
147
|
@route_set.add_named_route 'items', '/items', :controller => 'items', :action => 'index'
|
data/spec/private/parser_spec.rb
CHANGED
@@ -92,7 +92,7 @@ describe "Usher route tokenizing" do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should correctly generate route with a variable" do
|
95
|
-
route = @parser.generate_route('/cheese\(:kind\)', nil, nil, nil, nil)
|
95
|
+
route = @parser.generate_route('/cheese\(:kind\)', nil, nil, nil, nil, nil)
|
96
96
|
variable = route.paths[0].parts[3]
|
97
97
|
|
98
98
|
variable.should be_kind_of(Usher::Route::Variable::Single)
|
@@ -276,6 +276,22 @@ describe "Usher route recognition" do
|
|
276
276
|
@route_set.recognize(build_request({:method => 'get', :path => '/foo'})).path.route.should == route
|
277
277
|
end
|
278
278
|
|
279
|
+
it "should match between two routes where one has a higher priroty" do
|
280
|
+
route_lower = @route_set.add_route("/foo", :conditions => {:protocol => 'https'}, :priority => 1)
|
281
|
+
route_higher = @route_set.add_route("/foo", :conditions => {:method => 'post'}, :priority => 2)
|
282
|
+
|
283
|
+
@route_set.recognize(build_request({:method => 'post', :protocol => 'https', :path => '/foo'})).path.route.should == route_higher
|
284
|
+
|
285
|
+
@route_set.clear!
|
286
|
+
|
287
|
+
route_higher = @route_set.add_route("/foo", :conditions => {:protocol => 'https'}, :priority => 2)
|
288
|
+
route_lower = @route_set.add_route("/foo", :conditions => {:method => 'post'}, :priority => 1)
|
289
|
+
|
290
|
+
@route_set.recognize(build_request({:method => 'post', :protocol => 'https', :path => '/foo'})).path.route.should == route_higher
|
291
|
+
|
292
|
+
@route_set.clear!
|
293
|
+
end
|
294
|
+
|
279
295
|
it "should only match the specified path of the route when a condition is specified" do
|
280
296
|
@route_set.add_route("/", :conditions => {:method => "get"})
|
281
297
|
@route_set.add_route("/foo")
|