joshbuddy-usher 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -0
- data/VERSION.yml +2 -2
- data/lib/usher.rb +6 -6
- data/lib/usher/node.rb +7 -33
- data/lib/usher/route/request_method.rb +2 -1
- data/spec/generate_spec.rb +9 -0
- data/spec/grapher_spec.rb +5 -0
- data/spec/path_spec.rb +29 -0
- data/spec/recognize_spec.rb +20 -0
- data/spec/request_method_spec.rb +15 -0
- data/spec/split_spec.rb +10 -0
- metadata +3 -2
data/Rakefile
CHANGED
data/VERSION.yml
CHANGED
data/lib/usher.rb
CHANGED
@@ -44,10 +44,10 @@ class Usher
|
|
44
44
|
# The +request_methods+ are methods that are called against the request object in order to
|
45
45
|
# enforce the +conditions+ segment of the routes. For HTTP routes (and in fact the default), those
|
46
46
|
# methods are <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]</tt>.
|
47
|
-
def initialize(
|
48
|
-
@delimiters =
|
49
|
-
@
|
50
|
-
@
|
47
|
+
def initialize(options = {})
|
48
|
+
@delimiters = options.delete(:options) || ['/', '.']
|
49
|
+
@request_methods = options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
50
|
+
@splitter = Splitter.for_delimiters(@delimiters)
|
51
51
|
reset!
|
52
52
|
end
|
53
53
|
|
@@ -117,7 +117,7 @@ class Usher
|
|
117
117
|
conditions = options.delete(:conditions) || {}
|
118
118
|
requirements = options.delete(:requirements) || {}
|
119
119
|
options.delete_if do |k, v|
|
120
|
-
if v.is_a?(Regexp)
|
120
|
+
if v.is_a?(Regexp) || v.is_a?(Proc)
|
121
121
|
requirements[k] = v
|
122
122
|
true
|
123
123
|
end
|
@@ -173,7 +173,7 @@ class Usher
|
|
173
173
|
else
|
174
174
|
route
|
175
175
|
end
|
176
|
-
|
176
|
+
raise UnrecognizedException.new unless path
|
177
177
|
params_hash = {}
|
178
178
|
param_list = case params
|
179
179
|
when Hash
|
data/lib/usher/node.rb
CHANGED
@@ -16,7 +16,6 @@ class Usher
|
|
16
16
|
@value = value
|
17
17
|
@lookup = FuzzyHash.new
|
18
18
|
@exclusive_type = nil
|
19
|
-
@has_globber = find_parent{|p| p.value && p.value.is_a?(Route::Variable)}
|
20
19
|
end
|
21
20
|
|
22
21
|
def depth
|
@@ -29,28 +28,10 @@ class Usher
|
|
29
28
|
root
|
30
29
|
end
|
31
30
|
|
32
|
-
def has_globber?
|
33
|
-
@has_globber
|
34
|
-
end
|
35
|
-
|
36
31
|
def terminates?
|
37
32
|
@terminates
|
38
33
|
end
|
39
34
|
|
40
|
-
def find_parent(&blk)
|
41
|
-
if @parent.nil? || !@parent.is_a?(Node)
|
42
|
-
nil
|
43
|
-
elsif yield @parent
|
44
|
-
@parent
|
45
|
-
else #keep searching
|
46
|
-
@parent.find_parent(&blk)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def replace(src, dest)
|
51
|
-
@lookup.replace(src, dest)
|
52
|
-
end
|
53
|
-
|
54
35
|
def pp
|
55
36
|
$stdout << " " * depth
|
56
37
|
$stdout << "#{depth}: #{value.inspect} #{!!terminates?}\n"
|
@@ -83,12 +64,7 @@ class Usher
|
|
83
64
|
current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
|
84
65
|
end
|
85
66
|
else
|
86
|
-
|
87
|
-
parts.unshift(key)
|
88
|
-
current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
|
89
|
-
else
|
90
|
-
current_node.lookup[key.is_a?(Route::Variable) ? nil : key] ||= Node.new(current_node, key)
|
91
|
-
end
|
67
|
+
current_node.lookup[key.is_a?(Route::Variable) ? nil : key] ||= Node.new(current_node, key)
|
92
68
|
end
|
93
69
|
current_node = target_node
|
94
70
|
end
|
@@ -109,8 +85,8 @@ class Usher
|
|
109
85
|
elsif path.size.zero? && !part
|
110
86
|
if terminates?
|
111
87
|
Response.new(terminates, params)
|
112
|
-
|
113
|
-
nil
|
88
|
+
elsif params.last.is_a?(Array) && @lookup[nil]
|
89
|
+
Response.new(@lookup[nil].terminates, params)
|
114
90
|
end
|
115
91
|
elsif next_part = @lookup[part]
|
116
92
|
next_part.find(request, path, params)
|
@@ -120,16 +96,14 @@ class Usher
|
|
120
96
|
next_part.value.valid!(part)
|
121
97
|
case next_part.value.type
|
122
98
|
when :*
|
123
|
-
params << [next_part.value.name, []]
|
124
|
-
params.last.last << part
|
99
|
+
params << [next_part.value.name, []] unless params.last && params.last.first == next_part.value.name
|
100
|
+
params.last.last << part unless part.is_a?(Symbol)
|
101
|
+
find(request, path, params)
|
125
102
|
when :':'
|
126
103
|
params << [next_part.value.name, part]
|
104
|
+
next_part.find(request, path, params)
|
127
105
|
end
|
128
106
|
end
|
129
|
-
next_part.find(request, path, params)
|
130
|
-
elsif has_globber? && p = find_parent{|p| p.value.is_a?(Route::Variable) && p.value.type == :*}
|
131
|
-
params.last.last << part
|
132
|
-
find(request, path, params)
|
133
107
|
else
|
134
108
|
nil
|
135
109
|
end
|
data/spec/generate_spec.rb
CHANGED
@@ -80,9 +80,18 @@ describe "Usher URL generation" do
|
|
80
80
|
proc {route_set.generate_url(route_set.add_route('/:controller/:action').primary_path, {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
|
81
81
|
end
|
82
82
|
|
83
|
+
it "should generate from a route" do
|
84
|
+
route_set.generate_url(route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
|
85
|
+
end
|
86
|
+
|
83
87
|
it "should require all the parameters (array) to generate a route" do
|
84
88
|
route_set.add_named_route(:name, '/:controller/:action.:format')
|
85
89
|
proc {route_set.generate_url(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
|
86
90
|
end
|
87
91
|
|
92
|
+
it "should generate a route when only one parameter is given" do
|
93
|
+
route_set.add_named_route(:name, '/:controller')
|
94
|
+
route_set.generate_url(:name, 'controller').should == '/controller'
|
95
|
+
end
|
96
|
+
|
88
97
|
end
|
data/spec/grapher_spec.rb
CHANGED
@@ -19,6 +19,11 @@ describe "Usher grapher" do
|
|
19
19
|
route_set.generate_url(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should fail to generate a route when none matches" do
|
23
|
+
route_set.add_route('/:a/:b')
|
24
|
+
proc {route_set.generate_url(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
|
25
|
+
end
|
26
|
+
|
22
27
|
it "should find the most specific route and append extra parts on as a query string" do
|
23
28
|
route_set.add_route('/:a/:b/:c')
|
24
29
|
route_set.add_route('/:a/:b')
|
data/spec/path_spec.rb
CHANGED
@@ -36,4 +36,33 @@ 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 calculate depths for nodes" do
|
40
|
+
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
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should pp for nodes" do
|
46
|
+
route_set.add_named_route(:route, '/bad/route/three/four')
|
47
|
+
route_set.tree.depth.should == 0
|
48
|
+
old_out = $stdout
|
49
|
+
$stdout = (output = StringIO.new)
|
50
|
+
route_set.tree.lookup[:/].lookup['bad'].lookup[:/].pp
|
51
|
+
$stdout = old_out
|
52
|
+
output.rewind
|
53
|
+
output.read.should == <<-HEREDOC
|
54
|
+
3: :/ false
|
55
|
+
route ==>
|
56
|
+
4: "route" false
|
57
|
+
/ ==>
|
58
|
+
5: :/ false
|
59
|
+
three ==>
|
60
|
+
6: "three" false
|
61
|
+
/ ==>
|
62
|
+
7: :/ false
|
63
|
+
four ==>
|
64
|
+
8: "four" true
|
65
|
+
HEREDOC
|
66
|
+
end
|
67
|
+
|
39
68
|
end
|
data/spec/recognize_spec.rb
CHANGED
@@ -35,6 +35,11 @@ describe "Usher route recognition" do
|
|
35
35
|
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:format , 'html']])
|
36
36
|
end
|
37
37
|
|
38
|
+
it "should recognize a glob-style variable" do
|
39
|
+
target_route = route_set.add_route('/sample/*format', :controller => 'sample', :action => 'action')
|
40
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'})).params.should == [[:format, ['html', 'json', 'apple']]]
|
41
|
+
end
|
42
|
+
|
38
43
|
it "should recognize a format-style literal" do
|
39
44
|
target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
|
40
45
|
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:action , 'sample']])
|
@@ -72,11 +77,26 @@ describe "Usher route recognition" do
|
|
72
77
|
insecure_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com', :user_agent => false})).path.route
|
73
78
|
end
|
74
79
|
|
80
|
+
it "should use conditionals that are arrays" do
|
81
|
+
# hijacking user_agent
|
82
|
+
www_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['www'], :method => 'get'})
|
83
|
+
admin_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['admin'], :method => 'get'})
|
84
|
+
|
85
|
+
admin_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['admin'], :user_agent => true})).path.route
|
86
|
+
www_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['www'], :user_agent => false})).path.route
|
87
|
+
end
|
88
|
+
|
75
89
|
it "should use a transformer (proc) on incoming variables" do
|
76
90
|
route_set.add_route('/:controller/:action/:id', :transformers => {:id => proc{|v| v.to_i}})
|
77
91
|
route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'})).params.rassoc(123).first.should == :id
|
78
92
|
end
|
79
93
|
|
94
|
+
it "should use a requirement (proc) on incoming variables" do
|
95
|
+
route_set.add_route('/:controller/:action/:id', :id => proc{|v| Integer(v)})
|
96
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'}))}.should_not raise_error Usher::ValidationException
|
97
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'}))}.should raise_error Usher::ValidationException
|
98
|
+
end
|
99
|
+
|
80
100
|
it "shouldn't care about mildly weird characters in the URL" do
|
81
101
|
route = route_set.add_route('/!asd,qwe/hjk$qwe/:id')
|
82
102
|
route_set.recognize(build_request({:method => 'get', :path => '/!asd,qwe/hjk$qwe/09AZaz$-_+!*\'', :domain => 'admin.host.com'})).params.rassoc('09AZaz$-_+!*\'').first.should == :id
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
describe "Usher request method" do
|
4
|
+
|
5
|
+
it "support eql? and ==" do
|
6
|
+
Usher::Route::RequestMethod.new(:method, 'blah').should == Usher::Route::RequestMethod.new(:method, 'blah')
|
7
|
+
Usher::Route::RequestMethod.new(:method, 'blah').should.eql?(Usher::Route::RequestMethod.new(:method, 'blah'))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "support hash" do
|
11
|
+
Usher::Route::RequestMethod.new(:method, 'blah').hash.should == (Usher::Route::RequestMethod.new(:method, 'blah')).hash
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
end
|
data/spec/split_spec.rb
CHANGED
@@ -53,5 +53,15 @@ describe "Usher route tokenizing" do
|
|
53
53
|
[:/, "test", :/, "this", :/, "split", '.', Usher::Route::Variable.new(:':', :format)]
|
54
54
|
]
|
55
55
|
end
|
56
|
+
|
57
|
+
it "should to_s all different variable types" do
|
58
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/:split/*splitter').first.collect{|v| v.to_s} ==
|
59
|
+
[ ':split', '*splitter' ]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should == variable types" do
|
63
|
+
parts = Usher::Splitter.for_delimiters(['/', '.']).split('/:split/:split').first
|
64
|
+
parts[1].should == parts[3]
|
65
|
+
end
|
56
66
|
|
57
67
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshbuddy-usher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
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-04-
|
12
|
+
date: 2009-04-07 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- spec/rails/path_spec.rb
|
69
69
|
- spec/rails/recognize_spec.rb
|
70
70
|
- spec/recognize_spec.rb
|
71
|
+
- spec/request_method_spec.rb
|
71
72
|
- spec/spec.opts
|
72
73
|
- spec/split_spec.rb
|
73
74
|
- rails/init.rb
|