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 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
@@ -1,5 +1,5 @@
1
1
  ---
2
+ :major: 0
2
3
  :build:
3
4
  :minor: 5
4
- :patch: 12
5
- :major: 0
5
+ :patch: 13
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
- elsif general_node = request[nil] and ret = general_node.find(usher, request_object, original_path, path.dup, params.dup, position)
170
- ret
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
- nil
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[k] ||= Node.new(node, Route::RequestMethod.new(node.request_method_type, nil)) }
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
@@ -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
- if params.is_a?(Array)
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[??])
@@ -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
- route = parser.generate_route(path, conditions, requirements, default_values, generate_with)
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'
@@ -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")
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.12
4
+ version: 0.5.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Neighman