joshbuddy-usher 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/lib/usher.rb +20 -14
- data/lib/usher/interface/rack_interface.rb +1 -1
- data/lib/usher/interface/rails2_interface.rb +9 -6
- data/lib/usher/node.rb +7 -9
- data/lib/usher/route.rb +2 -1
- data/lib/usher/splitter.rb +18 -9
- data/spec/path_spec.rb +6 -6
- data/spec/rack/dispatch_spec.rb +1 -1
- data/spec/rails/generate_spec.rb +3 -3
- data/spec/recognize_spec.rb +12 -3
- data/spec/split_spec.rb +22 -22
- metadata +3 -3
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
s.homepage = "http://github.com/joshbuddy/usher"
|
10
10
|
s.authors = ["Joshua Hull"]
|
11
11
|
s.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"]
|
12
|
-
s.add_dependency 'joshbuddy-fuzzy_hash'
|
12
|
+
s.add_dependency 'joshbuddy-fuzzy_hash', '>=0.0.2'
|
13
13
|
end
|
14
14
|
rescue LoadError
|
15
15
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
data/VERSION.yml
CHANGED
data/lib/usher.rb
CHANGED
@@ -30,7 +30,7 @@ class Usher
|
|
30
30
|
# set.reset!
|
31
31
|
# set.empty? => true
|
32
32
|
def reset!
|
33
|
-
@tree = Node.root(self)
|
33
|
+
@tree = Node.root(self, @request_methods)
|
34
34
|
@named_routes = {}
|
35
35
|
@routes = []
|
36
36
|
@route_count = 0
|
@@ -38,9 +38,16 @@ class Usher
|
|
38
38
|
end
|
39
39
|
alias clear! reset!
|
40
40
|
|
41
|
-
# Creates a route set
|
42
|
-
|
43
|
-
|
41
|
+
# Creates a route set, with optional Array of +delimiters+ and +request_methods+
|
42
|
+
#
|
43
|
+
# The +delimiters+ must be one character. By default <tt>['/', '.']</tt> are used.
|
44
|
+
# The +request_methods+ are methods that are called against the request object in order to
|
45
|
+
# enforce the +conditions+ segment of the routes. For HTTP routes (and in fact the default), those
|
46
|
+
# methods are <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]</tt>.
|
47
|
+
def initialize(delimiters = ['/', '.'], request_methods = [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method])
|
48
|
+
@delimiters = delimiters
|
49
|
+
@splitter = Splitter.for_delimiters(delimiters)
|
50
|
+
@request_methods = request_methods
|
44
51
|
reset!
|
45
52
|
end
|
46
53
|
|
@@ -103,7 +110,7 @@ class Usher
|
|
103
110
|
# === +options+
|
104
111
|
# * +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.
|
105
112
|
# * +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
106
|
-
# * +conditions+ - Accepts any of the
|
113
|
+
# * +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.
|
107
114
|
# * Any other key is interpreted as a requirement for the variable of its name.
|
108
115
|
def add_route(path, options = {})
|
109
116
|
transformers = options.delete(:transformers) || {}
|
@@ -116,7 +123,8 @@ class Usher
|
|
116
123
|
end
|
117
124
|
end
|
118
125
|
|
119
|
-
route = Route.new(path, self, {:transformers => transformers, :conditions => conditions, :requirements => requirements})
|
126
|
+
route = Route.new(path, self, {:transformers => transformers, :conditions => conditions, :requirements => requirements})
|
127
|
+
route.to(options) unless options.empty?
|
120
128
|
|
121
129
|
@tree.add(route)
|
122
130
|
@routes << route
|
@@ -131,8 +139,8 @@ class Usher
|
|
131
139
|
# set = Usher.new
|
132
140
|
# route = set.add_route('/test')
|
133
141
|
# set.recognize(Request.new('/test')).path.route == route => true
|
134
|
-
def recognize(request)
|
135
|
-
@tree.find(request, @splitter.url_split(
|
142
|
+
def recognize(request, path = request.path)
|
143
|
+
@tree.find(request, @splitter.url_split(path))
|
136
144
|
end
|
137
145
|
|
138
146
|
# Recognizes a set of +parameters+ and gets the closest matching Usher::Route::Path or +nil+ if no route exists.
|
@@ -153,6 +161,7 @@ class Usher
|
|
153
161
|
# set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
154
162
|
def generate_url(route, params = {}, options = {})
|
155
163
|
check_variables = options.key?(:check_variables) ? options.delete(:check_variables) : false
|
164
|
+
delimiter = options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
|
156
165
|
|
157
166
|
path = case route
|
158
167
|
when Symbol
|
@@ -184,16 +193,13 @@ class Usher
|
|
184
193
|
case p.type
|
185
194
|
when :*
|
186
195
|
param_list.first.each {|dp| p.valid!(dp.to_s) } if check_variables
|
187
|
-
generated_path <<
|
188
|
-
when :'.:'
|
189
|
-
p.valid!(param_list.first.to_s) if check_variables
|
190
|
-
(dp = param_list.shift) && generated_path << '.' << dp.to_s
|
196
|
+
generated_path << param_list.shift.collect{|dp| dp.to_s} * delimiter
|
191
197
|
else
|
192
198
|
p.valid!(param_list.first.to_s) if check_variables
|
193
|
-
(dp = param_list.shift) && generated_path <<
|
199
|
+
(dp = param_list.shift) && generated_path << dp.to_s
|
194
200
|
end
|
195
201
|
else
|
196
|
-
generated_path <<
|
202
|
+
generated_path << p.to_s
|
197
203
|
end
|
198
204
|
end
|
199
205
|
unless params_hash.empty?
|
@@ -23,7 +23,7 @@ class Usher
|
|
23
23
|
def call(env)
|
24
24
|
response = @routes.recognize(Request.new(env['REQUEST_URI'], env['REQUEST_METHOD']))
|
25
25
|
env['usher.params'] = response.params.inject({}){|h,(k,v)| h[k]=v; h }
|
26
|
-
response.path.route.params.call(env)
|
26
|
+
response.path.route.params.first.call(env)
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
@@ -34,18 +34,19 @@ class Usher
|
|
34
34
|
add_route('/:controller', options.merge({:action => 'index'}))
|
35
35
|
@controller_route_added = true
|
36
36
|
end
|
37
|
-
|
38
|
-
options[:action] = 'index' unless options[:action]
|
39
37
|
|
38
|
+
options[:action] = 'index' unless options[:action]
|
39
|
+
|
40
|
+
path[0, 0] = '/' unless path[0] == ?/
|
40
41
|
route = @usher.add_route(path, options)
|
41
|
-
raise "your route must include a controller" unless route.primary_path.dynamic_set.include?(:controller) || route.params.include?(:controller)
|
42
|
+
raise "your route must include a controller" unless route.primary_path.dynamic_set.include?(:controller) || route.params.first.include?(:controller)
|
42
43
|
route
|
43
44
|
end
|
44
45
|
|
45
46
|
def recognize(request)
|
46
47
|
node = @usher.recognize(request)
|
47
48
|
params = node.params.inject({}){|h,(k,v)| h[k]=v; h }
|
48
|
-
request.path_parameters = (node.params.empty? ? node.path.route.params : node.path.route.params.merge(params)).with_indifferent_access
|
49
|
+
request.path_parameters = (node.params.empty? ? node.path.route.params.first : node.path.route.params.first.merge(params)).with_indifferent_access
|
49
50
|
"#{request.path_parameters[:controller].camelize}Controller".constantize
|
50
51
|
rescue
|
51
52
|
raise ActionController::RoutingError, "No route matches #{request.path.inspect} with #{request.inspect}"
|
@@ -70,14 +71,16 @@ class Usher
|
|
70
71
|
merged_options = options
|
71
72
|
merged_options[:controller] = recall[:controller] unless options.key?(:controller)
|
72
73
|
unless options.key?(:action)
|
73
|
-
options[:action] =
|
74
|
+
options[:action] = ''
|
74
75
|
end
|
75
76
|
route_for_options(merged_options)
|
76
77
|
end
|
77
78
|
case method
|
78
79
|
when :generate
|
79
80
|
merged_options ||= recall.merge(options)
|
80
|
-
generate_url(route, merged_options)
|
81
|
+
url = generate_url(route, merged_options)
|
82
|
+
url.slice!(-1) if url[-1] == ?/
|
83
|
+
url
|
81
84
|
else
|
82
85
|
raise "method #{method} not recognized"
|
83
86
|
end
|
data/lib/usher/node.rb
CHANGED
@@ -6,11 +6,10 @@ class Usher
|
|
6
6
|
|
7
7
|
class Node
|
8
8
|
|
9
|
-
ConditionalTypes = [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]
|
10
9
|
Response = Struct.new(:path, :params)
|
11
10
|
|
12
11
|
attr_reader :lookup
|
13
|
-
attr_accessor :terminates, :exclusive_type, :parent, :value
|
12
|
+
attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods
|
14
13
|
|
15
14
|
def initialize(parent, value)
|
16
15
|
@parent = parent
|
@@ -24,8 +23,10 @@ class Usher
|
|
24
23
|
@depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
|
25
24
|
end
|
26
25
|
|
27
|
-
def self.root(route_set)
|
28
|
-
self.new(route_set, nil)
|
26
|
+
def self.root(route_set, request_methods)
|
27
|
+
root = self.new(route_set, nil)
|
28
|
+
root.request_methods = request_methods
|
29
|
+
root
|
29
30
|
end
|
30
31
|
|
31
32
|
def has_globber?
|
@@ -63,8 +64,8 @@ class Usher
|
|
63
64
|
def add(route)
|
64
65
|
route.paths.each do |path|
|
65
66
|
parts = path.parts.dup
|
66
|
-
|
67
|
-
parts.push(Route::RequestMethod.new(type, route.conditions[type])) if route.conditions
|
67
|
+
request_methods.each do |type|
|
68
|
+
parts.push(Route::RequestMethod.new(type, route.conditions[type])) if route.conditions.key?(type)
|
68
69
|
end
|
69
70
|
|
70
71
|
current_node = self
|
@@ -123,9 +124,6 @@ class Usher
|
|
123
124
|
params.last.last << part
|
124
125
|
when :':'
|
125
126
|
params << [next_part.value.name, part]
|
126
|
-
when:'.:'
|
127
|
-
part.slice!(0)
|
128
|
-
params << [next_part.value.name, part]
|
129
127
|
end
|
130
128
|
end
|
131
129
|
next_part.find(request, path, params)
|
data/lib/usher/route.rb
CHANGED
@@ -16,6 +16,7 @@ class Usher
|
|
16
16
|
@transformers = options.delete(:transformers)
|
17
17
|
@paths = @router.splitter.split(@original_path, @requirements, @transformers).collect {|path| Path.new(self, path)}
|
18
18
|
@primary_path = @paths.first
|
19
|
+
@params = []
|
19
20
|
end
|
20
21
|
|
21
22
|
|
@@ -27,7 +28,7 @@ class Usher
|
|
27
28
|
# route.to(:controller => 'testing', :action => 'index')
|
28
29
|
# set.recognize(Request.new('/test')).first.params => {:controller => 'testing', :action => 'index'}
|
29
30
|
def to(options)
|
30
|
-
@params
|
31
|
+
@params << options
|
31
32
|
self
|
32
33
|
end
|
33
34
|
|
data/lib/usher/splitter.rb
CHANGED
@@ -3,11 +3,13 @@ require 'strscan'
|
|
3
3
|
class Usher
|
4
4
|
class Splitter
|
5
5
|
|
6
|
-
def self.
|
6
|
+
def self.for_delimiters(delimiters)
|
7
|
+
delimiters_regex = delimiters.collect{|d| Regexp.quote(d)} * '|'
|
8
|
+
|
7
9
|
SplitterInstance.new(
|
8
|
-
|
9
|
-
Regexp.new('((
|
10
|
-
Regexp.new(
|
10
|
+
delimiters,
|
11
|
+
Regexp.new('((:|\*)?[0-9A-Za-z\$\-_\+!\*\',]+|' + delimiters_regex + '|\(|\)|\|)'),
|
12
|
+
Regexp.new(delimiters_regex + '|[0-9A-Za-z\$\-_\+!\*\',]+')
|
11
13
|
)
|
12
14
|
end
|
13
15
|
|
@@ -15,8 +17,9 @@ class Usher
|
|
15
17
|
|
16
18
|
class SplitterInstance
|
17
19
|
|
18
|
-
def initialize(
|
19
|
-
@
|
20
|
+
def initialize(delimiters, split_regex, url_split_regex)
|
21
|
+
@delimiters = delimiters
|
22
|
+
@delimiter_chars = delimiters.collect{|d| d[0]}
|
20
23
|
@split_regex = split_regex
|
21
24
|
@url_split_regex = url_split_regex
|
22
25
|
end
|
@@ -26,7 +29,12 @@ class Usher
|
|
26
29
|
ss = StringScanner.new(path)
|
27
30
|
while !ss.eos?
|
28
31
|
if part = ss.scan(@url_split_regex)
|
29
|
-
parts <<
|
32
|
+
parts << case part[0]
|
33
|
+
when *@delimiter_chars
|
34
|
+
part.to_sym
|
35
|
+
else
|
36
|
+
part
|
37
|
+
end
|
30
38
|
end
|
31
39
|
end if path && !path.empty?
|
32
40
|
parts
|
@@ -39,7 +47,7 @@ class Usher
|
|
39
47
|
while !ss.eos?
|
40
48
|
part = ss.scan(@split_regex)
|
41
49
|
case part[0]
|
42
|
-
when ?*,
|
50
|
+
when ?*, ?:
|
43
51
|
type = (part[1] == ?: ? part.slice!(0,2) : part.slice!(0).chr).to_sym
|
44
52
|
current_group << Usher::Route::Variable.new(type, part, :validator => requirements[part.to_sym], :transformer => transformers[part.to_sym])
|
45
53
|
when ?(
|
@@ -59,7 +67,8 @@ class Usher
|
|
59
67
|
end
|
60
68
|
current_group.parent << Group.new(:all, current_group.parent)
|
61
69
|
current_group = current_group.parent.last
|
62
|
-
when
|
70
|
+
when *@delimiter_chars
|
71
|
+
current_group << part.to_sym
|
63
72
|
else
|
64
73
|
current_group << part
|
65
74
|
end
|
data/spec/path_spec.rb
CHANGED
@@ -22,12 +22,12 @@ describe "Usher route adding" do
|
|
22
22
|
it "should add every kind of optional route possible" do
|
23
23
|
route_set.add_route('/a/b(/c)(/d(/e))')
|
24
24
|
route_set.routes.first.paths.collect{|a| a.parts }.should == [
|
25
|
-
["a", "b"],
|
26
|
-
["a", "b", "c", "d"],
|
27
|
-
["a", "b", "d", "e"],
|
28
|
-
["a", "b", "c"],
|
29
|
-
["a", "b", "d"],
|
30
|
-
["a", "b", "c", "d", "e"]
|
25
|
+
[:/, "a", :/, "b"],
|
26
|
+
[:/, "a", :/, "b", :/, "c", :/, "d"],
|
27
|
+
[:/, "a", :/, "b", :/, "d", :/, "e"],
|
28
|
+
[:/, "a", :/, "b", :/, "c"],
|
29
|
+
[:/, "a", :/, "b", :/, "d"],
|
30
|
+
[:/, "a", :/, "b", :/, "c", :/, "d", :/, "e"]
|
31
31
|
]
|
32
32
|
|
33
33
|
end
|
data/spec/rack/dispatch_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe "Usher (for rack) route dispatching" do
|
|
28
28
|
|
29
29
|
it "should dispatch a simple request" do
|
30
30
|
env = {'REQUEST_URI' => '/sample', 'REQUEST_METHOD' => 'get', 'usher.params' => {}}
|
31
|
-
route_set.add('/sample'
|
31
|
+
route_set.add('/sample').to(build_app_mock(env.dup))
|
32
32
|
route_set.call(env)
|
33
33
|
end
|
34
34
|
|
data/spec/rails/generate_spec.rb
CHANGED
@@ -10,17 +10,17 @@ describe "Usher (for rails) URL generation" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should fill in the controller from recall" do
|
13
|
-
route_set.add_route('
|
13
|
+
route_set.add_route('/:controller/:action/:id')
|
14
14
|
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should skip the action if not provided" do
|
18
|
-
route_set.add_route('
|
18
|
+
route_set.add_route('/:controller/:action/:id')
|
19
19
|
route_set.generate({:controller => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/thingy'
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should pick the correct param from optional parts" do
|
23
|
-
route_set.add_route('
|
23
|
+
route_set.add_route('/:controller/:action(.:format)')
|
24
24
|
route_set.generate({:action => 'thingy', :format => 'html'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy.html'
|
25
25
|
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
26
26
|
end
|
data/spec/recognize_spec.rb
CHANGED
@@ -36,12 +36,12 @@ describe "Usher route recognition" do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should recognize a format-style literal" do
|
39
|
-
target_route = route_set.add_route('
|
39
|
+
target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
|
40
40
|
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']])
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should recognize a format-style variable along side another variable" do
|
44
|
-
target_route = route_set.add_route('
|
44
|
+
target_route = route_set.add_route('/:action.:format', :controller => 'sample', :action => 'action')
|
45
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'], [:format, 'html']])
|
46
46
|
end
|
47
47
|
|
@@ -57,12 +57,21 @@ describe "Usher route recognition" do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should correctly fix that tree if conditionals are used later" do
|
60
|
-
noop_route = route_set.add_route('noop', :controller => 'products', :action => 'noop')
|
60
|
+
noop_route = route_set.add_route('/noop', :controller => 'products', :action => 'noop')
|
61
61
|
product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:method => 'get'})
|
62
62
|
noop_route.paths.include?(route_set.recognize(build_request({:method => 'get', :path => '/noop', :domain => 'admin.host.com'})).first).should == true
|
63
63
|
product_show_route.paths.include?(route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'})).first).should == true
|
64
64
|
end
|
65
65
|
|
66
|
+
it "should use conditionals that are boolean" do
|
67
|
+
# hijacking user_agent
|
68
|
+
insecure_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:user_agent => false, :method => 'get'})
|
69
|
+
secure_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:user_agent => true, :method => 'get'})
|
70
|
+
|
71
|
+
secure_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com', :user_agent => true})).path.route
|
72
|
+
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
|
+
end
|
74
|
+
|
66
75
|
it "should use a transformer (proc) on incoming variables" do
|
67
76
|
route_set.add_route('/:controller/:action/:id', :transformers => {:id => proc{|v| v.to_i}})
|
68
77
|
route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'})).params.rassoc(123).first.should == :id
|
data/spec/split_spec.rb
CHANGED
@@ -4,53 +4,53 @@ describe "Usher route tokenizing" do
|
|
4
4
|
|
5
5
|
|
6
6
|
it "should split / delimited routes" do
|
7
|
-
Usher::Splitter.
|
7
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this/split').should == [[:/, 'test', :/,'this', :/, 'split']]
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should split on ' ' delimited routes as well" do
|
11
|
-
Usher::Splitter.
|
11
|
+
Usher::Splitter.for_delimiters([' ']).split('test this split').should == [['test', :' ', 'this', :' ', 'split']]
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should split on ' ' delimited routes for more complex routes as well" do
|
15
|
-
Usher::Splitter.
|
15
|
+
Usher::Splitter.for_delimiters([' ']).split('(test|this) split').should == [['test', :' ', 'split'], ['this', :' ', 'split']]
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should group optional parts with brackets" do
|
19
|
-
Usher::Splitter.
|
20
|
-
['test', 'this'],
|
21
|
-
['test', 'this', 'split']
|
19
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split)').should == [
|
20
|
+
[:/, 'test', :/, 'this'],
|
21
|
+
[:/, 'test', :/, 'this', :/, 'split']
|
22
22
|
]
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should group exclusive optional parts with brackets and pipes" do
|
26
|
-
Usher::Splitter.
|
27
|
-
['test', 'this'
|
28
|
-
['test', 'this'
|
26
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split|/split2)').should == [
|
27
|
+
[:/, 'test', :/, 'this',:/, 'split'],
|
28
|
+
[:/, 'test', :/, 'this',:/, 'split2']
|
29
29
|
]
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should group exclusive optional-optional parts with brackets and pipes" do
|
33
|
-
Usher::Splitter.
|
34
|
-
['test'
|
35
|
-
['test'
|
36
|
-
['test'
|
33
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this((/split|/split2))').should == [
|
34
|
+
[:/, 'test',:/, 'this'],
|
35
|
+
[:/, 'test',:/, 'this', :/, 'split'],
|
36
|
+
[:/, 'test',:/, 'this', :/, 'split2']
|
37
37
|
]
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should group optional parts with brackets (for non overlapping groups)" do
|
41
|
-
Usher::Splitter.
|
42
|
-
["test", "this"],
|
43
|
-
["test", "this", "split"],
|
44
|
-
["test", "this", "split2"],
|
45
|
-
["test", "this", "split", "split2"]
|
41
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split)(/split2)') == [
|
42
|
+
[:/, "test", :/, "this"],
|
43
|
+
[:/, "test", :/, "this", :/, "split"],
|
44
|
+
[:/, "test", :/, "this", :/, "split2"],
|
45
|
+
[:/, "test", :/, "this", :/, "split", :/, "split2"]
|
46
46
|
]
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should group nested-optional parts with brackets" do
|
50
|
-
Usher::Splitter.
|
51
|
-
["test", "this"],
|
52
|
-
["test", "this", "split"],
|
53
|
-
["test", "this", "split", Usher::Route::Variable.new(:'
|
50
|
+
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split(.:format))') == [
|
51
|
+
[:/, "test", :/, "this"],
|
52
|
+
[:/, "test", :/, "this", :/, "split"],
|
53
|
+
[:/, "test", :/, "this", :/, "split", '.', Usher::Route::Variable.new(:':', :format)]
|
54
54
|
]
|
55
55
|
end
|
56
56
|
|
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.2
|
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-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 0.0.2
|
24
24
|
version:
|
25
25
|
description: A general purpose routing library
|
26
26
|
email: joshbuddy@gmail.com
|