joshbuddy-usher 0.2.1 → 0.2.2
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/README.rdoc +44 -44
- data/VERSION.yml +2 -2
- data/lib/usher.rb +36 -33
- data/lib/usher/grapher.rb +2 -0
- data/lib/usher/interface.rb +3 -3
- data/lib/usher/route.rb +7 -2
- data/lib/usher/route/variable.rb +1 -1
- data/spec/grapher_spec.rb +34 -0
- metadata +2 -1
data/README.rdoc
CHANGED
@@ -16,50 +16,50 @@ Tree-based router library. Useful for (specifically) for Rails and Rack, but pro
|
|
16
16
|
|
17
17
|
From the rdoc:
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
19
|
+
Creates a route from +path+ and +options+
|
20
|
+
|
21
|
+
=== +path+
|
22
|
+
A path consists a mix of dynamic and static parts delimited by <tt>/</tt>
|
23
|
+
|
24
|
+
==== Dynamic
|
25
|
+
Dynamic parts are prefixed with either :, *. :variable matches only one part of the path, whereas *variable can match one or
|
26
|
+
more parts.
|
27
|
+
|
28
|
+
<b>Example:</b>
|
29
|
+
<tt>/path/:variable/path</tt> would match
|
30
|
+
|
31
|
+
* <tt>/path/test/path</tt>
|
32
|
+
* <tt>/path/something_else/path</tt>
|
33
|
+
* <tt>/path/one_more/path</tt>
|
34
|
+
|
35
|
+
In the above examples, 'test', 'something_else' and 'one_more' respectively would be bound to the key <tt>:variable</tt>.
|
36
|
+
However, <tt>/path/test/one_more/path</tt> would not be matched.
|
37
|
+
|
38
|
+
<b>Example:</b>
|
39
|
+
<tt>/path/*variable/path</tt> would match
|
40
|
+
|
41
|
+
* <tt>/path/one/two/three/path</tt>
|
42
|
+
* <tt>/path/four/five/path</tt>
|
43
|
+
|
44
|
+
In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
45
|
+
|
46
|
+
==== Static
|
47
|
+
|
48
|
+
Static parts of literal character sequences. For instance, <tt>/path/something.html</tt> would match only the same path.
|
49
|
+
|
50
|
+
==== Optional sections
|
51
|
+
|
52
|
+
Sections of a route can be marked as optional by surrounding it with brackets. For instance, in the above static example, <tt>/path/something(.html)</tt> would match both <tt>/path/something</tt> and <tt>/path/something.html</tt>.
|
53
|
+
|
54
|
+
==== One and only one sections
|
55
|
+
|
56
|
+
Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes. For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <tt>/path/something.xml</tt> and <tt>/path/something.html</tt>.
|
57
|
+
|
58
|
+
=== +options+
|
59
|
+
* +transformers+ - Transforms a variable before it gets to the requirements. Takes either a +proc+ or a +symbol+. If its a +symbol+, calls the method on the incoming parameter. If its a +proc+, its called with the variable.
|
60
|
+
* +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
61
|
+
* +conditions+ - Accepts any of the following <tt>:protocol</tt>, <tt>:domain</tt>, <tt>:port</tt>, <tt>:query_string</tt>, <tt>:remote_ip</tt>, <tt>:user_agent</tt>, <tt>:referer</tt> and <tt>:method</tt>. This can be either a <tt>string</tt> or a regular expression.
|
62
|
+
* Any other key is interpreted as a requirement for the variable of its name.
|
63
63
|
|
64
64
|
== Rails
|
65
65
|
|
data/VERSION.yml
CHANGED
data/lib/usher.rb
CHANGED
@@ -61,50 +61,48 @@ class Usher
|
|
61
61
|
|
62
62
|
# Creates a route from +path+ and +options+
|
63
63
|
#
|
64
|
-
#
|
65
|
-
#
|
64
|
+
# === +path+
|
65
|
+
# A path consists a mix of dynamic and static parts delimited by <tt>/</tt>
|
66
66
|
#
|
67
|
-
#
|
67
|
+
# ==== Dynamic
|
68
|
+
# Dynamic parts are prefixed with either :, *. :variable matches only one part of the path, whereas *variable can match one or
|
69
|
+
# more parts.
|
68
70
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
+
# <b>Example:</b>
|
72
|
+
# <tt>/path/:variable/path</tt> would match
|
71
73
|
#
|
72
|
-
#
|
73
|
-
#
|
74
|
+
# * <tt>/path/test/path</tt>
|
75
|
+
# * <tt>/path/something_else/path</tt>
|
76
|
+
# * <tt>/path/one_more/path</tt>
|
74
77
|
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# * <tt>/path/one_more/path</tt>
|
78
|
+
# In the above examples, 'test', 'something_else' and 'one_more' respectively would be bound to the key <tt>:variable</tt>.
|
79
|
+
# However, <tt>/path/test/one_more/path</tt> would not be matched.
|
78
80
|
#
|
79
|
-
#
|
80
|
-
#
|
81
|
+
# <b>Example:</b>
|
82
|
+
# <tt>/path/*variable/path</tt> would match
|
81
83
|
#
|
82
|
-
#
|
83
|
-
#
|
84
|
+
# * <tt>/path/one/two/three/path</tt>
|
85
|
+
# * <tt>/path/four/five/path</tt>
|
84
86
|
#
|
85
|
-
#
|
86
|
-
# * <tt>/path/four/five/path</tt>
|
87
|
+
# In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
87
88
|
#
|
88
|
-
#
|
89
|
+
# ==== Static
|
89
90
|
#
|
90
|
-
#
|
91
|
+
# Static parts of literal character sequences. For instance, <tt>/path/something.html</tt> would match only the same path.
|
91
92
|
#
|
92
|
-
#
|
93
|
+
# ==== Optional sections
|
93
94
|
#
|
94
|
-
#
|
95
|
+
# Sections of a route can be marked as optional by surrounding it with brackets. For instance, in the above static example, <tt>/path/something(.html)</tt> would match both <tt>/path/something</tt> and <tt>/path/something.html</tt>.
|
95
96
|
#
|
96
|
-
#
|
97
|
+
# ==== One and only one sections
|
97
98
|
#
|
98
|
-
#
|
99
|
+
# Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes. For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <tt>/path/something.xml</tt> and <tt>/path/something.html</tt>.
|
99
100
|
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
# <tt
|
103
|
-
#
|
104
|
-
#
|
105
|
-
# * :requirements - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
106
|
-
# * :conditions - Accepts any of the following <tt>:protocol</tt>, <tt>:domain</tt>, <tt>:port</tt>, <tt>:query_string</tt>, <tt>:remote_ip</tt>, <tt>:user_agent</tt>, <tt>:referer</tt> and <tt>:method</tt>. This can be either a <tt>string</tt> or a <tt>regexp</tt>.
|
107
|
-
# * any other key is interpreted as a requirement for the variable of its name.
|
101
|
+
# === +options+
|
102
|
+
# * +transformers+ - Transforms a variable before it gets to the requirements. Takes either a +proc+ or a +symbol+. If its a +symbol+, calls the method on the incoming parameter. If its a +proc+, its called with the variable.
|
103
|
+
# * +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
104
|
+
# * +conditions+ - Accepts any of the following <tt>:protocol</tt>, <tt>:domain</tt>, <tt>:port</tt>, <tt>:query_string</tt>, <tt>:remote_ip</tt>, <tt>:user_agent</tt>, <tt>:referer</tt> and <tt>:method</tt>. This can be either a <tt>string</tt> or a regular expression.
|
105
|
+
# * Any other key is interpreted as a requirement for the variable of its name.
|
108
106
|
def add_route(path, options = {})
|
109
107
|
transformers = options.delete(:transformers) || {}
|
110
108
|
conditions = options.delete(:conditions) || {}
|
@@ -144,14 +142,16 @@ class Usher
|
|
144
142
|
@grapher.find_matching_path(options)
|
145
143
|
end
|
146
144
|
|
147
|
-
# Generates a completed URL based on a +route+ or set of +params+
|
145
|
+
# Generates a completed URL based on a +route+ or set of optional +params+
|
148
146
|
#
|
149
147
|
# set = Usher.new
|
150
148
|
# route = set.add_named_route(:test_route, '/:controller/:action')
|
151
149
|
# set.generate_url(nil, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
152
150
|
# set.generate_url(:test_route, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
153
151
|
# set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
154
|
-
def generate_url(route, params)
|
152
|
+
def generate_url(route, params = {}, options = {})
|
153
|
+
check_variables = options.key?(:check_variables) ? options.delete(:check_variables) : false
|
154
|
+
|
155
155
|
path = case route
|
156
156
|
when Symbol
|
157
157
|
@named_routes[route]
|
@@ -181,10 +181,13 @@ class Usher
|
|
181
181
|
when Route::Variable
|
182
182
|
case p.type
|
183
183
|
when :*
|
184
|
-
|
184
|
+
param_list.first.each {|dp| p.valid!(dp.to_s) } if check_variables
|
185
|
+
generated_path << '/' << param_list.shift.collect{|dp| dp.to_s} * '/'
|
185
186
|
when :'.:'
|
187
|
+
p.valid!(param_list.first.to_s) if check_variables
|
186
188
|
(dp = param_list.shift) && generated_path << '.' << dp.to_s
|
187
189
|
else
|
190
|
+
p.valid!(param_list.first.to_s) if check_variables
|
188
191
|
(dp = param_list.shift) && generated_path << '/' << dp.to_s
|
189
192
|
end
|
190
193
|
else
|
data/lib/usher/grapher.rb
CHANGED
data/lib/usher/interface.rb
CHANGED
@@ -2,17 +2,17 @@ $:.unshift File.dirname(__FILE__)
|
|
2
2
|
|
3
3
|
class Usher
|
4
4
|
module Interface
|
5
|
+
autoload :Rails2Interface, 'interface/rails2_interface'
|
6
|
+
autoload :MerbInterface, 'interface/merb_interface'
|
7
|
+
autoload :RackInterface, 'interface/rack_interface'
|
5
8
|
|
6
9
|
def self.for(type)
|
7
10
|
case type
|
8
11
|
when :rails2
|
9
|
-
require 'interface/rails2_interface'
|
10
12
|
Rails2Interface.new
|
11
13
|
when :merb
|
12
|
-
require 'interface/merb_interface'
|
13
14
|
MerbInterface.new
|
14
15
|
when :rack
|
15
|
-
require 'interface/rack_interface'
|
16
16
|
RackInterface.new
|
17
17
|
end
|
18
18
|
end
|
data/lib/usher/route.rb
CHANGED
@@ -9,7 +9,7 @@ class Usher
|
|
9
9
|
class Route
|
10
10
|
attr_reader :paths, :original_path, :requirements, :conditions, :params, :primary_path
|
11
11
|
|
12
|
-
def initialize(original_path, router, options = {})
|
12
|
+
def initialize(original_path, router, options = {}) # :nodoc:
|
13
13
|
@original_path = original_path
|
14
14
|
@router = router
|
15
15
|
@requirements = options.delete(:requirements)
|
@@ -20,7 +20,7 @@ class Usher
|
|
20
20
|
end
|
21
21
|
|
22
22
|
|
23
|
-
# Sets +options+ on a route
|
23
|
+
# Sets +options+ on a route. Returns +self+.
|
24
24
|
#
|
25
25
|
# Request = Struct.new(:path)
|
26
26
|
# set = Usher.new
|
@@ -32,6 +32,11 @@ class Usher
|
|
32
32
|
self
|
33
33
|
end
|
34
34
|
|
35
|
+
# Sets route as referenceable from +name+. Returns +self+.
|
36
|
+
#
|
37
|
+
# set = Usher.new
|
38
|
+
# route = set.add_route('/test').name(:route)
|
39
|
+
# set.generate_url(:route) => '/test'
|
35
40
|
def name(name)
|
36
41
|
@router.name(name, self)
|
37
42
|
end
|
data/lib/usher/route/variable.rb
CHANGED
@@ -35,7 +35,7 @@ class Usher
|
|
35
35
|
@validator === val or raise
|
36
36
|
end if @validator
|
37
37
|
rescue Exception => e
|
38
|
-
raise ValidationException.new(
|
38
|
+
raise ValidationException.new("#{val} does not conform to #{@validator}, root cause #{e.inspect}")
|
39
39
|
end
|
40
40
|
|
41
41
|
def ==(o)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
route_set = Usher.new
|
4
|
+
|
5
|
+
describe "Usher grapher" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
route_set.reset!
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should find a simple path" do
|
12
|
+
route_set.add_route('/:a/:b/:c')
|
13
|
+
route_set.generate_url(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should pick a more specific route" do
|
17
|
+
route_set.add_route('/:a/:b')
|
18
|
+
route_set.add_route('/:a/:b/:c')
|
19
|
+
route_set.generate_url(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should find the most specific route and append extra parts on as a query string" do
|
23
|
+
route_set.add_route('/:a/:b/:c')
|
24
|
+
route_set.add_route('/:a/:b')
|
25
|
+
route_set.generate_url(nil, {:a => 'A', :b => 'B', :d => 'C'}).should == '/A/B?d=C'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should do a validity check against the incoming variables when asked to" do
|
29
|
+
route_set.add_route('/:a/:b', :b => /\d+/)
|
30
|
+
route_set.generate_url(nil, {:a => 'A', :b => 'B'}).should == '/A/B'
|
31
|
+
proc{ route_set.generate_url(nil, {:a => 'A', :b => 'B'}, :check_variables => true).should == '/A/B?d=C'}.should raise_error Usher::ValidationException
|
32
|
+
end
|
33
|
+
|
34
|
+
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.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/usher/route.rb
|
59
59
|
- lib/usher.rb
|
60
60
|
- spec/generate_spec.rb
|
61
|
+
- spec/grapher_spec.rb
|
61
62
|
- spec/path_spec.rb
|
62
63
|
- spec/rack
|
63
64
|
- spec/rack/dispatch_spec.rb
|