usher 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'rbench'
3
3
  require 'lib/usher'
4
+ #require 'usher'
4
5
 
5
6
  u = Usher.new(:generator => Usher::Util::Generators::URL.new)
6
7
  u.add_route('/simple') .name(:simple)
data/lib/usher.rb CHANGED
@@ -51,7 +51,7 @@ class Usher
51
51
  # set.reset!
52
52
  # set.empty? => true
53
53
  def reset!
54
- @root = Node::Root.new(self, request_methods)
54
+ @root = class_for_root.new(self, request_methods)
55
55
  @named_routes = {}
56
56
  @routes = []
57
57
  @grapher = Grapher.new(self)
@@ -254,16 +254,7 @@ class Usher
254
254
  # route = set.add_route('/test')
255
255
  # set.recognize(Request.new('/test')).path.route == route => true
256
256
  def recognize(request, path = request.path)
257
- if ignore_trailing_delimiters? and path.size > 1
258
- path_size = path.size
259
- path = path.gsub(/#{Regexp.quote(delimiters.first)}$/, '')
260
- response = root.find(request, path, splitter.split(path))
261
- response.only_trailing_delimiters = (path.size != path_size) if response
262
- response
263
- else
264
- root.find(request, path, splitter.split(path))
265
- end
266
-
257
+ root.lookup(request, path)
267
258
  end
268
259
 
269
260
  # Recognizes a `path`
@@ -396,4 +387,8 @@ class Usher
396
387
  routes.each{|r| grapher.add_route(r)}
397
388
  end
398
389
 
390
+ def class_for_root
391
+ ignore_trailing_delimiters? ? Node::RootIgnoringTrailingDelimiters : Node::Root
392
+ end
393
+
399
394
  end
data/lib/usher/node.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require File.join('usher', 'node', 'root')
2
+ require File.join('usher', 'node', 'root_ignoring_trailing_delimiters')
2
3
  require File.join('usher', 'node', 'response')
3
4
 
4
5
  class Usher
@@ -51,6 +52,8 @@ class Usher
51
52
  out
52
53
  end
53
54
 
55
+ protected
56
+
54
57
  def find(request_object, original_path, path, params = [])
55
58
  # terminates or is partial
56
59
 
@@ -26,6 +26,10 @@ class Usher
26
26
  routes
27
27
  end
28
28
 
29
+ def lookup(request_object, path)
30
+ find(request_object, path, route_set.splitter.split(path))
31
+ end
32
+
29
33
  private
30
34
 
31
35
  def set_path_with_destination(path, destination = path)
@@ -0,0 +1,24 @@
1
+ class Usher
2
+ class Node
3
+ class RootIgnoringTrailingDelimiters < Root
4
+
5
+ alias_method :lookup_without_stripping, :lookup
6
+
7
+ def initialize(route_set, request_methods)
8
+ super
9
+ @stripper = /#{Regexp.quote(route_set.delimiters.first)}$/
10
+ end
11
+
12
+ def lookup(request_object, path)
13
+ if path.size > 1
14
+ new_path = path.gsub(@stripper, '')
15
+ response = lookup_without_stripping(request_object, new_path)
16
+ response.only_trailing_delimiters = (new_path.size != path.size) if response
17
+ response
18
+ else
19
+ lookup_without_stripping(request_object, path)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -8,6 +8,7 @@ class Usher
8
8
  def initialize(route, parts)
9
9
  self.route = route
10
10
  self.parts = parts
11
+ build_generator
11
12
  end
12
13
 
13
14
  def convert_params_array(ary)
@@ -64,12 +65,81 @@ class Usher
64
65
  Path.new(route, new_parts)
65
66
  end
66
67
 
68
+ def generate
69
+ nil
70
+ end
71
+
72
+ def generate_from_hash(params = nil)
73
+ generate
74
+ end
75
+
67
76
  private
68
77
  def parts=(parts)
69
78
  @parts = parts
70
79
  @dynamic = @parts && @parts.any?{|p| p.is_a?(Variable)}
71
80
  end
72
-
81
+
82
+ def build_generator
83
+ if parts
84
+ interpolating_path = ''
85
+
86
+ parts.each_with_index do |part, index|
87
+ case part
88
+ when String
89
+ interpolating_path << part
90
+ when Static::Greedy
91
+ interpolating_path << part.generate_with
92
+ when Variable::Glob
93
+ interpolating_path << '#{('
94
+ interpolating_path << "Array(arg#{index})"
95
+ if part.default_value
96
+ interpolating_path << ' || '
97
+ interpolating_path << part.default_value.inspect
98
+ end
99
+ interpolating_path << ').join(route.router.delimiters.first)}'
100
+ when Variable
101
+ interpolating_path << '#{'
102
+ interpolating_path << "arg#{index}"
103
+ if part.default_value
104
+ interpolating_path << ' || '
105
+ interpolating_path << part.default_value.inspect
106
+ end
107
+ interpolating_path << '}'
108
+ end
109
+ end
110
+
111
+ generating_method = "def generate"
112
+ if dynamic?
113
+ generating_method << "("
114
+ generating_method << dynamic_indicies.map{|di| "arg#{di}"}.join(", ")
115
+ generating_method << ")\n"
116
+ dynamic_indicies.each do |di|
117
+ dp = parts.at(di)
118
+ generating_method << "@parts.at(#{di}).valid!(arg#{di})\n" if dp.validates?
119
+ end
120
+ else
121
+ generating_method << "\n"
122
+ end
123
+
124
+ generating_method << '"'
125
+ generating_method << interpolating_path
126
+ generating_method << '"'
127
+ generating_method << "\nend\n\n"
128
+ generating_method << "def generate_from_hash(params = nil)\n"
129
+ generating_method << "generate("
130
+ if parts && dynamic?
131
+ generating_method << dynamic_indicies.map { |di|
132
+ dp = parts.at(di)
133
+ arg = "params && params.delete(:#{dp.name}) "
134
+ arg << "|| @parts.at(#{di}).default_value " if dp.default_value
135
+ arg << "|| raise(MissingParameterException.new(\"expected a value for #{dp.name}\"))"
136
+ }.join(', ')
137
+ end
138
+ generating_method << ")\nend\n\n"
139
+ instance_eval generating_method
140
+ end
141
+ end
142
+
73
143
  end
74
144
  end
75
145
  end
@@ -2,7 +2,14 @@ class Usher
2
2
  class Route
3
3
  class Variable
4
4
 
5
+ module Validator
6
+ def validates?
7
+ true
8
+ end
9
+ end
10
+
5
11
  module ProcValidator
12
+ include Validator
6
13
  def valid!(val)
7
14
  begin
8
15
  @validator.call(val)
@@ -13,6 +20,7 @@ class Usher
13
20
  end
14
21
 
15
22
  module CaseEqualsValidator
23
+ include Validator
16
24
  def valid!(val)
17
25
  @validator === val.to_s or raise(ValidationException.new("#{val} does not conform to #{@validator}"))
18
26
  end
@@ -40,6 +48,10 @@ class Usher
40
48
  def valid!(val)
41
49
  end
42
50
 
51
+ def validates?
52
+ false
53
+ end
54
+
43
55
  def ==(o)
44
56
  o && (o.class == self.class && o.name == @name && o.validator == @validator)
45
57
  end
@@ -21,55 +21,11 @@ class Usher
21
21
  end
22
22
 
23
23
  def generate_path_for_base_params_with_hash(path, params)
24
- result = ''
25
- path.parts.each do |part|
26
- case part
27
- when String
28
- result << part
29
- when Route::Variable::Glob
30
- value = (params && params.delete(part.name)) || part.default_value || raise(MissingParameterException.new("expected a value for #{part.name}"))
31
- value.each_with_index do |current_value, index|
32
- part.valid!(current_value)
33
- result << current_value.to_s
34
- result << usher.delimiters.first if index != value.size - 1
35
- end
36
- when Route::Variable
37
- value = (params && params.delete(part.name)) || part.default_value || raise(MissingParameterException.new("expected a value for #{part.name}"))
38
- part.valid!(value)
39
- result << value.to_s
40
- when Route::Static::Greedy
41
- result << part.generate_with
42
- else
43
- raise
44
- end
45
- end
46
- result
24
+ path.generate_from_hash(params)
47
25
  end
48
26
 
49
27
  def generate_path_for_base_params_with_array(path, params)
50
- result = ''
51
- path.parts.each do |part|
52
- case part
53
- when String
54
- result << part
55
- when Route::Variable::Glob
56
- value = (params && params.shift) || part.default_value || raise(MissingParameterException.new)
57
- value.each_with_index do |current_value, index|
58
- part.valid!(current_value)
59
- result << current_value.to_s
60
- result << usher.delimiters.first if index != value.size - 1
61
- end
62
- when Route::Variable
63
- value = (params && params.shift) || part.default_value || raise(MissingParameterException.new)
64
- part.valid!(value)
65
- result << value.to_s
66
- when Route::Static::Greedy
67
- result << value.generate_with
68
- else
69
- raise
70
- end
71
- end
72
- result
28
+ path.generate(*params.slice!(0, path.dynamic_parts.size))
73
29
  end
74
30
 
75
31
  end
@@ -49,6 +49,23 @@ describe "Usher (for Sinatra) route recognition" do
49
49
  response.body.should == "bar"
50
50
  end
51
51
 
52
+ it "should ignore trailing delimiters with an optional param" do
53
+ @app.get("/foo/(:bar)") { params[:bar] }
54
+ @app.get("/bar(/:foo)") { params[:foo] }
55
+ response = @app.call_with_mock_request('/foo/bar')
56
+ response.status.should == 200
57
+ response.body.should == "bar"
58
+ response = @app.call_with_mock_request('/bar/foo')
59
+ response.status.should == 200
60
+ response.body.should == "foo"
61
+ response = @app.call_with_mock_request('/bar')
62
+ response.status.should == 200
63
+ response.body.should == ""
64
+ response = @app.call_with_mock_request('/bar/')
65
+ response.status.should == 200
66
+ response.body.should == ""
67
+ end
68
+
52
69
  it "should use sinatra optionals trailing delimiters" do
53
70
  @app.get("/foo/?") { "foo" }
54
71
  response = @app.call_with_mock_request('/foo')
@@ -99,4 +116,25 @@ describe "Usher (for Sinatra) route recognition" do
99
116
  response.body.should_not match(/__sinatra__/)
100
117
  end
101
118
  end
119
+
120
+ describe "recognize paths" do
121
+
122
+ it "should recognize basic routes" do
123
+ pending "undefined method `request_method' for nil:NilClass"
124
+ @app.get("/foo/:bar") { "foo" }
125
+ @app.router.recognize_path("/foo/:bar").should == nil
126
+ end
127
+ end
128
+
129
+ describe "priority" do
130
+
131
+ it "should set correctly priorities" do
132
+ pending "match the wrong route"
133
+ @app.get("/:id/:right", :priority => 10) { "right" }
134
+ @app.get("/:id/:wrong") { "wrong" }
135
+ response = @app.call_with_mock_request('/foo/bar')
136
+ response.status.should == 200
137
+ response.body.should == "right"
138
+ end
139
+ end
102
140
  end
data/usher.gemspec CHANGED
@@ -5,7 +5,7 @@ require "base64"
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "usher"
8
- s.version = "0.7.2"
8
+ s.version = "0.7.3"
9
9
  s.authors = ["Daniel Neighman", "Daniel Vartanov", "Jakub Šťastný", "Joshua Hull"]
10
10
  s.homepage = "http://github.com/joshbuddy/usher"
11
11
  s.summary = "Pure ruby general purpose router with interfaces for rails, rack, email or choose your own adventure"
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 2
9
- version: 0.7.2
8
+ - 3
9
+ version: 0.7.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Daniel Neighman
@@ -18,7 +18,7 @@ authors:
18
18
  autorequire:
19
19
  bindir: bin
20
20
  cert_chain:
21
- date: 2010-04-29 00:00:00 -04:00
21
+ date: 2010-05-02 00:00:00 -04:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -124,6 +124,7 @@ files:
124
124
  - lib/usher/node.rb
125
125
  - lib/usher/node/response.rb
126
126
  - lib/usher/node/root.rb
127
+ - lib/usher/node/root_ignoring_trailing_delimiters.rb
127
128
  - lib/usher/route.rb
128
129
  - lib/usher/route/path.rb
129
130
  - lib/usher/route/request_method.rb