joshbuddy-usher 0.3.6 → 0.4.0
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 +5 -3
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/lib/usher/grapher.rb +0 -1
- data/lib/usher/interface/rack_interface.rb +1 -1
- data/lib/usher/interface/rails2_interface/mapper.rb +2 -2
- data/lib/usher/node.rb +45 -7
- data/lib/usher/route/variable.rb +5 -4
- data/lib/usher/route.rb +7 -6
- data/lib/usher/splitter.rb +35 -15
- data/lib/usher.rb +21 -18
- data/spec/recognize_spec.rb +44 -0
- data/spec/split_spec.rb +6 -1
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -67,7 +67,7 @@ Sections of a route can be marked as "one and only one" by surrounding it with b
|
|
67
67
|
|
68
68
|
== Rack
|
69
69
|
|
70
|
-
===
|
70
|
+
=== config.ru
|
71
71
|
|
72
72
|
require 'usher'
|
73
73
|
app = proc do |env|
|
@@ -82,8 +82,10 @@ Sections of a route can be marked as "one and only one" by surrounding it with b
|
|
82
82
|
]
|
83
83
|
end
|
84
84
|
|
85
|
-
routes = Usher::Interface.for(:rack)
|
86
|
-
|
85
|
+
routes = Usher::Interface.for(:rack) do
|
86
|
+
add('/hello/:name').to(app)
|
87
|
+
end
|
88
|
+
|
87
89
|
run routes
|
88
90
|
|
89
91
|
------------
|
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', '>=0.0.
|
12
|
+
s.add_dependency 'joshbuddy-fuzzy_hash', '>=0.0.3'
|
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/grapher.rb
CHANGED
@@ -7,7 +7,7 @@ class Usher
|
|
7
7
|
@set = set
|
8
8
|
end
|
9
9
|
|
10
|
-
def connect(path, options =
|
10
|
+
def connect(path, options = nil)
|
11
11
|
@set.add_route(path, options)
|
12
12
|
end
|
13
13
|
|
@@ -21,7 +21,7 @@ class Usher
|
|
21
21
|
named_route(:root, '/', options)
|
22
22
|
end
|
23
23
|
|
24
|
-
def named_route(name, path, options =
|
24
|
+
def named_route(name, path, options = nil)
|
25
25
|
@set.add_named_route(name, path, options)
|
26
26
|
end
|
27
27
|
|
data/lib/usher/node.rb
CHANGED
@@ -14,10 +14,14 @@ class Usher
|
|
14
14
|
def initialize(parent, value)
|
15
15
|
@parent = parent
|
16
16
|
@value = value
|
17
|
-
@lookup =
|
17
|
+
@lookup = Hash.new
|
18
18
|
@exclusive_type = nil
|
19
19
|
end
|
20
20
|
|
21
|
+
def upgrade_lookup
|
22
|
+
@lookup = FuzzyHash.new(@lookup)
|
23
|
+
end
|
24
|
+
|
21
25
|
def depth
|
22
26
|
@depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
|
23
27
|
end
|
@@ -54,6 +58,7 @@ class Usher
|
|
54
58
|
key = parts.shift
|
55
59
|
target_node = case key
|
56
60
|
when Route::RequestMethod
|
61
|
+
current_node.upgrade_lookup if key.value.is_a?(Regexp)
|
57
62
|
if current_node.exclusive_type == key.type
|
58
63
|
current_node.lookup[key.value] ||= Node.new(current_node, key)
|
59
64
|
elsif current_node.lookup.empty?
|
@@ -64,7 +69,15 @@ class Usher
|
|
64
69
|
current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
|
65
70
|
end
|
66
71
|
else
|
67
|
-
|
72
|
+
if !key.is_a?(Route::Variable)
|
73
|
+
current_node.upgrade_lookup if key.is_a?(Regexp)
|
74
|
+
current_node.lookup[key] ||= Node.new(current_node, key)
|
75
|
+
elsif key.regex_matcher
|
76
|
+
current_node.upgrade_lookup
|
77
|
+
current_node.lookup[key.regex_matcher] ||= Node.new(current_node, key)
|
78
|
+
else
|
79
|
+
current_node.lookup[nil] ||= Node.new(current_node, key)
|
80
|
+
end
|
68
81
|
end
|
69
82
|
current_node = target_node
|
70
83
|
end
|
@@ -86,20 +99,45 @@ class Usher
|
|
86
99
|
if terminates?
|
87
100
|
Response.new(terminates, params)
|
88
101
|
elsif params.last.is_a?(Array) && @lookup[nil]
|
89
|
-
|
102
|
+
if @lookup[nil].exclusive_type
|
103
|
+
@lookup[nil].find(request, path, params)
|
104
|
+
else
|
105
|
+
Response.new(@lookup[nil].terminates, params)
|
106
|
+
end
|
90
107
|
end
|
91
108
|
elsif next_part = @lookup[part]
|
92
|
-
next_part.find(request, path, params)
|
93
|
-
elsif next_part = @lookup[nil]
|
94
109
|
if next_part.value.is_a?(Route::Variable)
|
95
110
|
part = next_part.value.transform!(part)
|
96
111
|
next_part.value.valid!(part)
|
112
|
+
var = next_part.value
|
113
|
+
params << [next_part.value.name, part]
|
114
|
+
until (path.first == var.look_ahead) || path.empty?
|
115
|
+
params.last.last << path.shift.to_s
|
116
|
+
end
|
117
|
+
next_part.find(request, path, params)
|
118
|
+
else
|
119
|
+
next_part.find(request, path, params)
|
120
|
+
end
|
121
|
+
elsif next_part = @lookup[part] || next_part = @lookup[nil]
|
122
|
+
if next_part.value.is_a?(Route::Variable)
|
97
123
|
case next_part.value.type
|
98
124
|
when :*
|
99
125
|
params << [next_part.value.name, []] unless params.last && params.last.first == next_part.value.name
|
100
|
-
|
101
|
-
|
126
|
+
if next_part.value.look_ahead === part
|
127
|
+
path.unshift(part)
|
128
|
+
path.unshift(next_part.parent.value) if next_part.parent.value.is_a?(Symbol)
|
129
|
+
next_part.find(request, path, params)
|
130
|
+
else
|
131
|
+
unless part.is_a?(Symbol)
|
132
|
+
part = next_part.value.transform!(part)
|
133
|
+
next_part.value.valid!(part)
|
134
|
+
params.last.last << part
|
135
|
+
end
|
136
|
+
find(request, path, params)
|
137
|
+
end
|
102
138
|
when :':'
|
139
|
+
part = next_part.value.transform!(part)
|
140
|
+
next_part.value.valid!(part)
|
103
141
|
var = next_part.value
|
104
142
|
params << [next_part.value.name, part]
|
105
143
|
until (path.first == var.look_ahead) || path.empty?
|
data/lib/usher/route/variable.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
class Usher
|
2
2
|
class Route
|
3
3
|
class Variable
|
4
|
-
attr_reader :type, :name, :validator, :transformer
|
4
|
+
attr_reader :type, :name, :validator, :transformer, :regex_matcher
|
5
5
|
attr_accessor :look_ahead
|
6
6
|
|
7
|
-
def initialize(type, name,
|
7
|
+
def initialize(type, name, validator = nil, transformer = nil, regex_matcher = nil)
|
8
8
|
@type = type
|
9
9
|
@name = :"#{name}"
|
10
|
-
@validator =
|
11
|
-
@transformer =
|
10
|
+
@validator = validator
|
11
|
+
@transformer = transformer
|
12
|
+
@regex_matcher = regex_matcher
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_s
|
data/lib/usher/route.rb
CHANGED
@@ -8,14 +8,15 @@ class Usher
|
|
8
8
|
class Route
|
9
9
|
attr_reader :paths, :original_path, :requirements, :conditions, :params, :primary_path
|
10
10
|
|
11
|
-
def initialize(original_path, router, options =
|
11
|
+
def initialize(original_path, router, options = nil) # :nodoc:
|
12
12
|
@original_path = original_path
|
13
13
|
@router = router
|
14
|
-
@requirements = options.delete(:requirements)
|
15
|
-
@conditions = options.delete(:conditions)
|
16
|
-
@transformers = options.delete(:transformers)
|
14
|
+
@requirements = options && options.delete(:requirements)
|
15
|
+
@conditions = options && options.delete(:conditions)
|
16
|
+
@transformers = options && 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
|
+
#FIXME params is poorly named. this shouldn't be an array
|
19
20
|
@params = []
|
20
21
|
end
|
21
22
|
|
@@ -27,8 +28,8 @@ class Usher
|
|
27
28
|
# route = set.add_route('/test')
|
28
29
|
# route.to(:controller => 'testing', :action => 'index')
|
29
30
|
# set.recognize(Request.new('/test')).first.params => {:controller => 'testing', :action => 'index'}
|
30
|
-
def to(options)
|
31
|
-
@params << options
|
31
|
+
def to(options = nil, &block)
|
32
|
+
@params << (block_given? ? block : options)
|
32
33
|
self
|
33
34
|
end
|
34
35
|
|
data/lib/usher/splitter.rb
CHANGED
@@ -8,7 +8,7 @@ class Usher
|
|
8
8
|
|
9
9
|
SplitterInstance.new(
|
10
10
|
delimiters,
|
11
|
-
Regexp.new('((:|\*)?[0-9A-Za-z\$\-_\+!\*\',]+|' + delimiters_regex + '|\(|\)
|
11
|
+
Regexp.new('((:|\*)?[0-9A-Za-z\$\-_\+!\*\',]+|' + delimiters_regex + '|\(|\)|\||\{)'),
|
12
12
|
Regexp.new(delimiters_regex + '|[0-9A-Za-z\$\-_\+!\*\',]+')
|
13
13
|
)
|
14
14
|
end
|
@@ -40,7 +40,7 @@ class Usher
|
|
40
40
|
parts
|
41
41
|
end
|
42
42
|
|
43
|
-
def split(path, requirements =
|
43
|
+
def split(path, requirements = nil, transformers = nil)
|
44
44
|
parts = Group.new(:all, nil)
|
45
45
|
ss = StringScanner.new(path)
|
46
46
|
current_group = parts
|
@@ -48,8 +48,32 @@ class Usher
|
|
48
48
|
part = ss.scan(@split_regex)
|
49
49
|
case part[0]
|
50
50
|
when ?*, ?:
|
51
|
-
type =
|
52
|
-
current_group << Usher::Route::Variable.new(type, part,
|
51
|
+
type = part.slice!(0).chr.to_sym
|
52
|
+
current_group << Usher::Route::Variable.new(type, part, requirements && requirements[part.to_sym], transformers && transformers[part.to_sym])
|
53
|
+
when ?{
|
54
|
+
pattern = ''
|
55
|
+
count = 1
|
56
|
+
variable = ss.scan(/:([^,]+),/)
|
57
|
+
until count.zero?
|
58
|
+
regex_part = ss.scan(/\{|\}|[^\{\}]+/)
|
59
|
+
case regex_part[0]
|
60
|
+
when ?{
|
61
|
+
count += 1
|
62
|
+
when ?}
|
63
|
+
count -= 1
|
64
|
+
end
|
65
|
+
pattern << regex_part
|
66
|
+
end
|
67
|
+
pattern.slice!(pattern.size - 1)
|
68
|
+
regex = Regexp.new(pattern)
|
69
|
+
if variable
|
70
|
+
variable_type = variable.slice!(0).chr.to_sym
|
71
|
+
variable_name = variable[0, variable.size - 1].to_sym
|
72
|
+
current_group << Usher::Route::Variable.new(variable_type, variable_name, requirements && requirements[variable_name], transformers && transformers[variable_name], regex)
|
73
|
+
else
|
74
|
+
current_group << regex
|
75
|
+
end
|
76
|
+
|
53
77
|
when ?(
|
54
78
|
new_group = Group.new(:any, current_group)
|
55
79
|
current_group << new_group
|
@@ -75,20 +99,16 @@ class Usher
|
|
75
99
|
end unless !path || path.empty?
|
76
100
|
paths = calc_paths(parts)
|
77
101
|
paths.each do |path|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if last_variable
|
86
|
-
last_variable.look_ahead = last_delimiter || @delimiters.first.to_sym
|
102
|
+
path.each_with_index do |part, index|
|
103
|
+
if part.is_a?(Usher::Route::Variable)
|
104
|
+
case part.type
|
105
|
+
when :*
|
106
|
+
part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Symbol) && !p.is_a?(Usher::Route::Variable)} || nil
|
107
|
+
when :':'
|
108
|
+
part.look_ahead = path[index + 1, path.size].find{|p| p.is_a?(Symbol)} || @delimiters.first.to_sym
|
87
109
|
end
|
88
|
-
last_variable = part
|
89
110
|
end
|
90
111
|
end
|
91
|
-
last_variable.look_ahead = last_delimiter || @delimiters.first.to_sym if last_variable
|
92
112
|
end
|
93
113
|
paths
|
94
114
|
end
|
data/lib/usher.rb
CHANGED
@@ -45,9 +45,9 @@ class Usher
|
|
45
45
|
# The +request_methods+ are methods that are called against the request object in order to
|
46
46
|
# enforce the +conditions+ segment of the routes. For HTTP routes (and in fact the default), those
|
47
47
|
# methods are <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]</tt>.
|
48
|
-
def initialize(options =
|
49
|
-
@delimiters = options.delete(:options) || ['/', '.']
|
50
|
-
@request_methods = options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
48
|
+
def initialize(options = nil)
|
49
|
+
@delimiters = options && options.delete(:options) || ['/', '.']
|
50
|
+
@request_methods = options && options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
51
51
|
@splitter = Splitter.for_delimiters(@delimiters)
|
52
52
|
reset!
|
53
53
|
end
|
@@ -56,7 +56,7 @@ class Usher
|
|
56
56
|
#
|
57
57
|
# set = Usher.new
|
58
58
|
# set.add_named_route(:test_route, '/test')
|
59
|
-
def add_named_route(name, path, options =
|
59
|
+
def add_named_route(name, path, options = nil)
|
60
60
|
add_route(path, options).name(name)
|
61
61
|
end
|
62
62
|
|
@@ -113,19 +113,20 @@ class Usher
|
|
113
113
|
# * +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
114
114
|
# * +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.
|
115
115
|
# * Any other key is interpreted as a requirement for the variable of its name.
|
116
|
-
def add_route(path, options =
|
117
|
-
transformers = options.delete(:transformers) || {}
|
118
|
-
conditions = options.delete(:conditions) || {}
|
119
|
-
requirements = options.delete(:requirements) || {}
|
120
|
-
options
|
121
|
-
|
122
|
-
|
123
|
-
|
116
|
+
def add_route(path, options = nil)
|
117
|
+
transformers = options && options.delete(:transformers) || {}
|
118
|
+
conditions = options && options.delete(:conditions) || {}
|
119
|
+
requirements = options && options.delete(:requirements) || {}
|
120
|
+
if options
|
121
|
+
options.delete_if do |k, v|
|
122
|
+
if v.is_a?(Regexp) || v.is_a?(Proc)
|
123
|
+
requirements[k] = v
|
124
|
+
true
|
125
|
+
end
|
124
126
|
end
|
125
127
|
end
|
126
|
-
|
127
128
|
route = Route.new(path, self, {:transformers => transformers, :conditions => conditions, :requirements => requirements})
|
128
|
-
route.to(options)
|
129
|
+
route.to(options) if options && !options.empty?
|
129
130
|
|
130
131
|
@tree.add(route)
|
131
132
|
@routes << route
|
@@ -160,10 +161,10 @@ class Usher
|
|
160
161
|
# set.generate_url(nil, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
161
162
|
# set.generate_url(:test_route, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
162
163
|
# set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
163
|
-
def generate_url(route, params =
|
164
|
-
check_variables = options.key?(:check_variables) ? options.delete(:check_variables) : false
|
165
|
-
delimiter = options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
|
166
|
-
extra_params = options.key?(:extra_params) ? options.delete(:extra_params) : {}
|
164
|
+
def generate_url(route, params = nil, options = nil)
|
165
|
+
check_variables = options && options.key?(:check_variables) ? options.delete(:check_variables) : false
|
166
|
+
delimiter = options && options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
|
167
|
+
extra_params = options && options.key?(:extra_params) ? options.delete(:extra_params) : {}
|
167
168
|
|
168
169
|
path = case route
|
169
170
|
when Symbol
|
@@ -183,6 +184,8 @@ class Usher
|
|
183
184
|
path.dynamic_parts.collect{|k| params_hash.delete(k.name) {|el| raise MissingParameterException.new(k.name)} }
|
184
185
|
when Array
|
185
186
|
path.dynamic_parts.size == params.size ? params : raise(MissingParameterException.new("got #{params.size} arguments, expected #{path.dynamic_parts.size}"))
|
187
|
+
when nil
|
188
|
+
nil
|
186
189
|
else
|
187
190
|
Array(params)
|
188
191
|
end
|
data/spec/recognize_spec.rb
CHANGED
@@ -40,6 +40,50 @@ describe "Usher route recognition" do
|
|
40
40
|
route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'})).params.should == [[:format, ['html', 'json', 'apple']]]
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should recgonize only a glob-style variable" do
|
44
|
+
target_route = route_set.add_route('/*format')
|
45
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'}))
|
46
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
47
|
+
response.path.route.should == target_route
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should recgonize a regex static part" do
|
51
|
+
target_route = route_set.add_route('/test/part/{one|two}')
|
52
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/one'})).path.route.should == target_route
|
53
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/two'})).path.route.should == target_route
|
54
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/three'})).should == nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should recgonize a regex static part containing {}'s" do
|
58
|
+
target_route = route_set.add_route('/test/part/{^o{2,3}$}')
|
59
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oo'})).path.route.should == target_route
|
60
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/ooo'})).path.route.should == target_route
|
61
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oooo'})).should == nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should recgonize a regex static part containing {}'s" do
|
65
|
+
target_route = route_set.add_route('/test/part/{:test,hello|again}')
|
66
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).path.route.should == target_route
|
67
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).params.should == [[:test, 'hello']]
|
68
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).path.route.should == target_route
|
69
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).params.should == [[:test, 'again']]
|
70
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/world'})).should == nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should recgonize two glob-style variables separated by a static part" do
|
74
|
+
target_route = route_set.add_route('/*format/innovate/*onemore')
|
75
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/innovate/apple'}))
|
76
|
+
response.params.should == [[:format, ['sample', 'html']], [:onemore, ['apple']]]
|
77
|
+
response.path.route.should == target_route
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should recgonize only a glob-style variable with a condition" do
|
81
|
+
target_route = route_set.add_route('/*format', :conditions => {:domain => 'test-domain'})
|
82
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple', :domain => 'test-domain'}))
|
83
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
84
|
+
response.path.route.should == target_route
|
85
|
+
end
|
86
|
+
|
43
87
|
it "should recognize a format-style literal" do
|
44
88
|
target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
|
45
89
|
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']])
|
data/spec/split_spec.rb
CHANGED
@@ -6,6 +6,11 @@ describe "Usher route tokenizing" do
|
|
6
6
|
it "should split / delimited routes" do
|
7
7
|
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this/split').should == [[:/, 'test', :/,'this', :/, 'split']]
|
8
8
|
end
|
9
|
+
|
10
|
+
it "should split / delimited routes with a regex in it" do
|
11
|
+
Usher::Splitter.for_delimiters(['/', '.']).
|
12
|
+
split('/test/{this}/split').should == [[:/, 'test', :/, /this/, :/, 'split']]
|
13
|
+
end
|
9
14
|
|
10
15
|
it "should split on ' ' delimited routes as well" do
|
11
16
|
Usher::Splitter.for_delimiters([' ']).split('test this split').should == [['test', :' ', 'this', :' ', 'split']]
|
@@ -50,7 +55,7 @@ describe "Usher route tokenizing" do
|
|
50
55
|
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split(.:format))') == [
|
51
56
|
[:/, "test", :/, "this"],
|
52
57
|
[:/, "test", :/, "this", :/, "split"],
|
53
|
-
[:/, "test", :/, "this", :/, "split", '.', Usher::Route::Variable.new(:':', :format)]
|
58
|
+
[:/, "test", :/, "this", :/, "split", :'.', Usher::Route::Variable.new(:':', :format)]
|
54
59
|
]
|
55
60
|
end
|
56
61
|
|
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.
|
4
|
+
version: 0.4.0
|
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-
|
12
|
+
date: 2009-05-09 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: 0.0.
|
23
|
+
version: 0.0.3
|
24
24
|
version:
|
25
25
|
description: A general purpose routing library
|
26
26
|
email: joshbuddy@gmail.com
|