http_router 0.7.10 → 0.8.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.md +1 -0
- data/benchmarks/rec2.rb +4 -2
- data/lib/http_router.rb +18 -1
- data/lib/http_router/node.rb +26 -8
- data/lib/http_router/node/arbitrary.rb +14 -10
- data/lib/http_router/node/destination.rb +12 -11
- data/lib/http_router/node/free_regex.rb +11 -9
- data/lib/http_router/node/glob.rb +12 -11
- data/lib/http_router/node/glob_regex.rb +11 -2
- data/lib/http_router/node/lookup.rb +12 -7
- data/lib/http_router/node/regex.rb +12 -15
- data/lib/http_router/node/request.rb +12 -11
- data/lib/http_router/node/spanning_regex.rb +12 -9
- data/lib/http_router/node/variable.rb +9 -8
- data/lib/http_router/request.rb +5 -1
- data/lib/http_router/route.rb +1 -3
- data/lib/http_router/version.rb +1 -1
- data/test/test_recognize.rb +16 -1
- data/test/test_request.rb +6 -0
- data/test/test_variable.rb +1 -0
- metadata +88 -38
data/README.md
CHANGED
data/benchmarks/rec2.rb
CHANGED
@@ -15,6 +15,8 @@ u.add('/dynamic/:variable').to {|env| [200, {'Content-type'=>'text/html'}, []]}
|
|
15
15
|
#u.add('/greedy/:greed').matching(:greed => /.*/).compile.to {|env| [200, {'Content-type'=>'text/html'}, []]}
|
16
16
|
#u.add('/greedy/hey.:greed.html').to {|env| [200, {'Content-type'=>'text/html'}, []]}
|
17
17
|
|
18
|
+
u.compile rescue nil
|
19
|
+
|
18
20
|
puts Benchmark.measure {
|
19
21
|
('aa'..'nn').each do |first|
|
20
22
|
('a'..'n').each do |second|
|
@@ -34,7 +36,7 @@ TIMES = 50_000
|
|
34
36
|
#simple_and_dynamic_env1 = Rack::MockRequest.env_for('/rails/controller/action/id')
|
35
37
|
#simple_and_dynamic_env2 = Rack::MockRequest.env_for('/greedy/controller/action/id')
|
36
38
|
#simple_and_dynamic_env3 = Rack::MockRequest.env_for('/greedy/hey.hello.html')
|
37
|
-
|
39
|
+
5.times {
|
38
40
|
RBench.run(TIMES) do
|
39
41
|
|
40
42
|
report "2 levels, static" do
|
@@ -62,5 +64,5 @@ TIMES = 50_000
|
|
62
64
|
#end
|
63
65
|
|
64
66
|
end
|
65
|
-
|
67
|
+
}
|
66
68
|
puts `ps -o rss= -p #{Process.pid}`.to_i
|
data/lib/http_router.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'rack'
|
3
|
+
require 'uri'
|
4
|
+
require 'cgi'
|
5
|
+
require 'url_mount'
|
3
6
|
require 'http_router/node'
|
4
7
|
require 'http_router/request'
|
5
8
|
require 'http_router/response'
|
@@ -11,7 +14,7 @@ require 'http_router/optional_compiler'
|
|
11
14
|
|
12
15
|
class HttpRouter
|
13
16
|
|
14
|
-
attr_reader :root, :routes, :known_methods, :named_routes
|
17
|
+
attr_reader :root, :routes, :known_methods, :named_routes, :nodes
|
15
18
|
attr_accessor :default_app, :url_mount
|
16
19
|
|
17
20
|
# Raised when a Route is not able to be generated.
|
@@ -36,6 +39,7 @@ class HttpRouter
|
|
36
39
|
@ignore_trailing_slash = options && options.key?(:ignore_trailing_slash) ? options[:ignore_trailing_slash] : true
|
37
40
|
@redirect_trailing_slash = options && options.key?(:redirect_trailing_slash) ? options[:redirect_trailing_slash] : false
|
38
41
|
@known_methods = Set.new(options && options[:known_methods] || [])
|
42
|
+
@nodes = []
|
39
43
|
reset!
|
40
44
|
instance_eval(&blk) if blk
|
41
45
|
end
|
@@ -143,6 +147,15 @@ class HttpRouter
|
|
143
147
|
@default_app = app
|
144
148
|
end
|
145
149
|
|
150
|
+
def register_node(n)
|
151
|
+
@nodes << n
|
152
|
+
@nodes.size - 1
|
153
|
+
end
|
154
|
+
|
155
|
+
def [](pos)
|
156
|
+
@nodes.at(pos)
|
157
|
+
end
|
158
|
+
|
146
159
|
# Generate a URL for a specified route. This will accept a list of variable values plus any other variable names named as a hash.
|
147
160
|
# This first value must be either the Route object or the name of the route.
|
148
161
|
#
|
@@ -191,6 +204,10 @@ class HttpRouter
|
|
191
204
|
cloned_router
|
192
205
|
end
|
193
206
|
|
207
|
+
def compile
|
208
|
+
@root.compile
|
209
|
+
end
|
210
|
+
|
194
211
|
private
|
195
212
|
def no_response(env, perform_call = true)
|
196
213
|
supported_methods = (@known_methods - [env['REQUEST_METHOD']]).select do |m|
|
data/lib/http_router/node.rb
CHANGED
@@ -11,16 +11,12 @@ class HttpRouter
|
|
11
11
|
autoload :Lookup, 'http_router/node/lookup'
|
12
12
|
autoload :Destination, 'http_router/node/destination'
|
13
13
|
|
14
|
-
attr_reader :priority, :router
|
14
|
+
attr_reader :priority, :router, :node_position
|
15
15
|
|
16
16
|
def initialize(router, matchers = [])
|
17
17
|
@router, @matchers = router, matchers
|
18
18
|
end
|
19
19
|
|
20
|
-
def [](request)
|
21
|
-
@matchers.each {|m| m[request] }; nil
|
22
|
-
end
|
23
|
-
|
24
20
|
def add_variable
|
25
21
|
add(Variable.new(@router))
|
26
22
|
end
|
@@ -61,15 +57,37 @@ class HttpRouter
|
|
61
57
|
false
|
62
58
|
end
|
63
59
|
|
60
|
+
def method_missing(m, *args, &blk)
|
61
|
+
if m.to_s == '[]'
|
62
|
+
compile
|
63
|
+
send(:[], *args)
|
64
|
+
else
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def compile
|
70
|
+
instance_eval "def [](r0)\n#{to_code(0)}\nnil\nend", __FILE__, __LINE__
|
71
|
+
end
|
72
|
+
|
64
73
|
private
|
65
74
|
def add(matcher)
|
66
75
|
@matchers << matcher unless matcher.usable?(@matchers.last)
|
67
76
|
@matchers.last
|
68
77
|
end
|
69
78
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
79
|
+
def to_code(pos)
|
80
|
+
@matchers.map{ |m| m.to_code(pos) }.join("\n") << "\n"
|
81
|
+
end
|
82
|
+
|
83
|
+
def indented_code(pos, code)
|
84
|
+
lines = code.
|
85
|
+
strip.
|
86
|
+
split(/\n/).
|
87
|
+
select{|l| !l.strip.size.zero?}
|
88
|
+
indent_size = lines.first[/ */].size
|
89
|
+
lines.map! {|l| "#{' ' * pos.next}#{l[indent_size, l.size]}"}
|
90
|
+
"\n" << lines.join("\n") << "\n"
|
73
91
|
end
|
74
92
|
end
|
75
93
|
end
|
@@ -1,26 +1,30 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class Arbitrary < Node
|
4
|
-
alias_method :node_lookup, :[]
|
5
4
|
attr_reader :allow_partial, :blk, :param_names
|
6
5
|
|
7
6
|
def initialize(router, allow_partial, blk, param_names)
|
8
7
|
@allow_partial, @blk, @param_names = allow_partial, blk, param_names
|
8
|
+
@node_position = router.register_node(blk)
|
9
9
|
super(router)
|
10
10
|
end
|
11
11
|
|
12
|
-
def [](request)
|
13
|
-
if request.path.empty? or (request.path.size == 1 and request.path[0] == '') or @allow_partial
|
14
|
-
request = request.clone
|
15
|
-
request.continue = proc { |state| node_lookup(request) if state }
|
16
|
-
params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
|
17
|
-
@blk.call(request, params)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
12
|
def usuable?(other)
|
22
13
|
other.class == self.class && other.allow_partial == allow_partial && other.blk == blk && other.param_names == param_names
|
23
14
|
end
|
15
|
+
|
16
|
+
def to_code(pos)
|
17
|
+
indented_code pos, "
|
18
|
+
#{"if r#{pos}.path_finished?" unless @allow_partial}
|
19
|
+
r#{pos.next} = r#{pos}.dup
|
20
|
+
r#{pos.next}.continue = proc { |state|
|
21
|
+
if state
|
22
|
+
#{super(pos.next)}
|
23
|
+
end
|
24
|
+
}
|
25
|
+
router.nodes.at(#{node_position})[r#{pos.next}, #{@param_names.nil? || @param_names.empty? ? '{}' : "Hash[#{@param_names.inspect}.zip(r#{pos.next}.params)]"}]
|
26
|
+
#{"end" unless @allow_partial}"
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -1,25 +1,26 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class Destination < Node
|
4
|
+
attr_reader :blk, :allow_partial, :param_names
|
5
|
+
|
4
6
|
def initialize(router, blk, allow_partial)
|
5
7
|
@blk, @allow_partial = blk, allow_partial
|
8
|
+
@node_position = router.register_node(blk)
|
6
9
|
super(router)
|
7
10
|
end
|
8
11
|
|
9
|
-
def [](request)
|
10
|
-
if request.path.empty? or (request.path.size == 1 and request.path[0] == '') or @allow_partial
|
11
|
-
request.passed_with = catch(:pass) do
|
12
|
-
request = request.clone
|
13
|
-
request.continue = proc { |state| destination(request) if state }
|
14
|
-
params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
|
15
|
-
@blk.call(request, params)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
12
|
def usuable?(other)
|
21
13
|
other.class == self.class && other.allow_partial == allow_partial && other.blk == blk
|
22
14
|
end
|
15
|
+
|
16
|
+
def to_code(pos)
|
17
|
+
indented_code pos, "
|
18
|
+
#{"if r#{pos}.path_finished?" unless @allow_partial}
|
19
|
+
r0.passed_with = catch(:pass) do
|
20
|
+
router.nodes.at(#{node_position})[r#{pos}, #{@param_names.nil? || @param_names.empty? ? 'nil' : "Hash[#{@param_names.inspect}.zip(r#{pos.next}.params)]"}]
|
21
|
+
end
|
22
|
+
#{"end" unless @allow_partial}"
|
23
|
+
end
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -7,15 +7,17 @@ class HttpRouter
|
|
7
7
|
super(router)
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
def to_code(pos)
|
11
|
+
indented_code pos, "
|
12
|
+
whole_path = \"/\#{r#{pos}.joined_path}\"
|
13
|
+
if match = #{matcher.inspect}.match(whole_path) and match[0].size == whole_path.size
|
14
|
+
r#{pos.next} = r#{pos}.dup
|
15
|
+
r#{pos.next}.extra_env['router.regex_match'] = match
|
16
|
+
r#{pos.next}.path = ['']
|
17
|
+
" << (//.respond_to?(:names) ?
|
18
|
+
"match.names.size.times{|i| r#{pos.next}.params << match[i + 1]} if match.respond_to?(:names) && match.names" : "") << "
|
19
|
+
#{super(pos.next)}
|
20
|
+
end"
|
19
21
|
end
|
20
22
|
|
21
23
|
def usuable?(other)
|
@@ -1,20 +1,21 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class Glob < Node
|
4
|
-
def [](request)
|
5
|
-
request = request.clone
|
6
|
-
request.params << []
|
7
|
-
remaining_parts = request.path.dup
|
8
|
-
until remaining_parts.empty?
|
9
|
-
request.params[-1] << unescape(remaining_parts.shift)
|
10
|
-
request.path = remaining_parts
|
11
|
-
super(request)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
4
|
def usuable?(other)
|
16
5
|
other.class == self.class
|
17
6
|
end
|
7
|
+
|
8
|
+
def to_code(pos)
|
9
|
+
indented_code pos, "
|
10
|
+
r#{pos.next} = r#{pos}.dup
|
11
|
+
r#{pos.next}.params << []
|
12
|
+
remaining_parts = r#{pos.next}.path.dup
|
13
|
+
until remaining_parts.empty?
|
14
|
+
r#{pos.next}.params[-1] << URI.unescape(remaining_parts.shift)
|
15
|
+
r#{pos.next}.path = remaining_parts
|
16
|
+
#{super(pos.next)}
|
17
|
+
end"
|
18
|
+
end
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -1,8 +1,17 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class GlobRegex < SpanningRegex
|
4
|
-
def
|
5
|
-
|
4
|
+
def to_code(pos)
|
5
|
+
indented_code pos, "
|
6
|
+
whole_path = r#{pos}.joined_path
|
7
|
+
if match = #{@matcher.inspect}.match(whole_path) and match.begin(0).zero?
|
8
|
+
r#{pos.next} = r#{pos}.dup\n" <<
|
9
|
+
@capturing_indicies.map { |c| "r#{pos.next}.params << URI.unescape(match[#{c}].split(/\\//))\n" }.join << "
|
10
|
+
remaining_path = whole_path[match[0].size + (whole_path[match[0].size] == ?/ ? 1 : 0), whole_path.size]
|
11
|
+
r#{pos.next}.path = remaining_path.split('/')
|
12
|
+
#{super(pos.next)}
|
13
|
+
end
|
14
|
+
"
|
6
15
|
end
|
7
16
|
end
|
8
17
|
end
|
@@ -6,13 +6,6 @@ class HttpRouter
|
|
6
6
|
super(router)
|
7
7
|
end
|
8
8
|
|
9
|
-
def [](request)
|
10
|
-
if @map[request.path.first]
|
11
|
-
request = request.clone
|
12
|
-
@map[request.path.shift].each{|m| m[request]}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
9
|
def add(part)
|
17
10
|
Node.new(@router, @map[part] ||= [])
|
18
11
|
end
|
@@ -20,6 +13,18 @@ class HttpRouter
|
|
20
13
|
def usuable?(other)
|
21
14
|
other.class == self.class
|
22
15
|
end
|
16
|
+
|
17
|
+
def to_code(pos)
|
18
|
+
code = "case r#{pos}.path.first\n"
|
19
|
+
@map.keys.each do |k|
|
20
|
+
code << "when #{k.inspect}\n
|
21
|
+
r#{pos.next} = r#{pos}.dup
|
22
|
+
r#{pos.next}.path.shift
|
23
|
+
#{@map[k].map{|n| n.to_code(pos.next)} * "\n"}"
|
24
|
+
end
|
25
|
+
code << "\nend"
|
26
|
+
indented_code pos, code
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class Regex < Node
|
4
|
-
alias_method :
|
4
|
+
alias_method :node_to_code, :to_code
|
5
5
|
attr_reader :matcher, :splitting_indicies, :capturing_indicies
|
6
6
|
|
7
7
|
def initialize(router, matcher, capturing_indicies, splitting_indicies = nil)
|
@@ -9,23 +9,20 @@ class HttpRouter
|
|
9
9
|
super(router)
|
10
10
|
end
|
11
11
|
|
12
|
-
def [](request)
|
13
|
-
if match = @matcher.match(request.path.first) and match.begin(0).zero?
|
14
|
-
request = request.clone
|
15
|
-
request.path.shift
|
16
|
-
add_params(request, match)
|
17
|
-
super(request)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_params(request, match)
|
22
|
-
@splitting_indicies.each { |idx| request.params << unescape(match[idx]).split(/\//) } if @splitting_indicies
|
23
|
-
@capturing_indicies.each { |idx| request.params << unescape(match[idx]) }
|
24
|
-
end
|
25
|
-
|
26
12
|
def usuable?(other)
|
27
13
|
other.class == self.class && other.matcher == matcher && other.splitting_indicies == splitting_indicies && other.capturing_indicies == capturing_indicies
|
28
14
|
end
|
15
|
+
|
16
|
+
def to_code(pos)
|
17
|
+
indented_code pos, "
|
18
|
+
if match = #{@matcher.inspect}.match(r#{pos}.path.first) and match.begin(0).zero?
|
19
|
+
r#{pos.next} = r#{pos}.dup
|
20
|
+
r#{pos.next}.path.shift\n" <<
|
21
|
+
@splitting_indicies.map { |s| "r#{pos.next}.params << URI.unescape(match[#{s}]).split(/\\//)\n" }.join <<
|
22
|
+
@capturing_indicies.map { |c| "r#{pos.next}.params << URI.unescape(match[#{c}])\n" }.join << "
|
23
|
+
#{super(pos.next)}
|
24
|
+
end"
|
25
|
+
end
|
29
26
|
end
|
30
27
|
end
|
31
28
|
end
|
@@ -9,20 +9,21 @@ class HttpRouter
|
|
9
9
|
super(router)
|
10
10
|
end
|
11
11
|
|
12
|
-
def [](request)
|
13
|
-
@opts.each{|k,v|
|
14
|
-
test = request.rack_request.send(k)
|
15
|
-
return unless case v
|
16
|
-
when Array then v.any?{|vv| vv === test}
|
17
|
-
else v === test
|
18
|
-
end
|
19
|
-
}
|
20
|
-
super(request)
|
21
|
-
end
|
22
|
-
|
23
12
|
def usuable?(other)
|
24
13
|
other.class == self.class && other.opts == opts
|
25
14
|
end
|
15
|
+
|
16
|
+
def to_code(pos)
|
17
|
+
code = "if "
|
18
|
+
code << @opts.map do |k,v|
|
19
|
+
case v
|
20
|
+
when Array then "(#{v.map{|vv| "#{vv.inspect} === r#{pos}.rack_request.#{k}"}.join(' or ')})"
|
21
|
+
else "#{v.inspect} === r#{pos}.rack_request.#{k.inspect}"
|
22
|
+
end
|
23
|
+
end * ' and '
|
24
|
+
code << "\n #{super}\nend"
|
25
|
+
indented_code pos, code
|
26
|
+
end
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
@@ -1,15 +1,18 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class SpanningRegex < Regex
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
def to_code(pos)
|
5
|
+
indented_code(pos, "
|
6
|
+
whole_path = r#{pos}.joined_path
|
7
|
+
if match = #{@matcher.inspect}.match(whole_path) and match.begin(0).zero?
|
8
|
+
r#{pos.next} = r#{pos}.dup\n" <<
|
9
|
+
(@splitting_indicies || []).map { |s| "r#{pos.next}.params << URI.unescape(match[#{s}]).split(/\\//)\n" }.join <<
|
10
|
+
@capturing_indicies.map { |c| "r#{pos.next}.params << URI.unescape(match[#{c}])\n" }.join << "
|
11
|
+
remaining_path = whole_path[match[0].size + (whole_path[match[0].size] == ?/ ? 1 : 0), whole_path.size]
|
12
|
+
r#{pos.next}.path = remaining_path.split('/')
|
13
|
+
#{node_to_code(pos.next)}
|
14
|
+
end
|
15
|
+
")
|
13
16
|
end
|
14
17
|
end
|
15
18
|
end
|
@@ -1,17 +1,18 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Node
|
3
3
|
class Variable < Node
|
4
|
-
def [](request)
|
5
|
-
unless request.path.empty?
|
6
|
-
request = request.clone
|
7
|
-
request.params << unescape(request.path.shift)
|
8
|
-
super(request)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
4
|
def usuable?(other)
|
13
5
|
other.class == self.class
|
14
6
|
end
|
7
|
+
|
8
|
+
def to_code(pos)
|
9
|
+
indented_code(pos, "
|
10
|
+
unless r#{pos}.path_finished?
|
11
|
+
r#{pos.next} = r#{pos}.dup
|
12
|
+
r#{pos.next}.params << URI.unescape(r#{pos.next}.path.shift)
|
13
|
+
#{super(pos.next)}
|
14
|
+
end")
|
15
|
+
end
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
data/lib/http_router/request.rb
CHANGED
@@ -27,12 +27,16 @@ class HttpRouter
|
|
27
27
|
"request path, #{path.inspect}"
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def dup
|
31
31
|
dup_obj = super
|
32
32
|
dup_obj.path = path.dup
|
33
33
|
dup_obj.params = params.dup
|
34
34
|
dup_obj.extra_env = extra_env.dup
|
35
35
|
dup_obj
|
36
36
|
end
|
37
|
+
|
38
|
+
def path_finished?
|
39
|
+
@path.size == 0 or @path.size == 1 && @path.first == ''
|
40
|
+
end
|
37
41
|
end
|
38
42
|
end
|
data/lib/http_router/route.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'url_mount'
|
2
|
-
require 'uri'
|
3
1
|
|
4
2
|
class HttpRouter
|
5
3
|
class Route
|
@@ -300,7 +298,7 @@ class HttpRouter
|
|
300
298
|
when Hash
|
301
299
|
value.each{ |k, v| append_querystring_value(uri, "#{key}[#{k}]", v) }
|
302
300
|
else
|
303
|
-
uri << '&' <<
|
301
|
+
uri << '&' << CGI.escape(key.to_s) << '=' << CGI.escape(value.to_s)
|
304
302
|
end
|
305
303
|
end
|
306
304
|
|
data/lib/http_router/version.rb
CHANGED
data/test/test_recognize.rb
CHANGED
@@ -4,12 +4,27 @@ class TestRecognition < MiniTest::Unit::TestCase
|
|
4
4
|
assert_route router.add(''), '/'
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def test_simple1
|
8
8
|
assert_route router.add('/'), '/'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_simple2
|
9
12
|
assert_route router.add('/test'), '/test'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_simple3
|
10
16
|
assert_route router.add('/test/one'), '/test/one'
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_simple4
|
11
20
|
assert_route router.add('/test/one/two'), '/test/one/two'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_simple5
|
12
24
|
assert_route router.add('/test.html'), '/test.html'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_simple6
|
13
28
|
assert_route router.add('/.html'), '/.html'
|
14
29
|
end
|
15
30
|
|
data/test/test_request.rb
CHANGED
@@ -6,6 +6,12 @@ class TestRequest < MiniTest::Unit::TestCase
|
|
6
6
|
assert_status(405, Rack::MockRequest.env_for('/test', :method => 'GET'))
|
7
7
|
end
|
8
8
|
|
9
|
+
def test_simple_case_with_array
|
10
|
+
r = router { add('test', :request => {:request_methods => ['POST', 'GET']}) }
|
11
|
+
assert_route r, Rack::MockRequest.env_for('/test', :method => 'POST')
|
12
|
+
assert_route r, Rack::MockRequest.env_for('/test', :method => 'GET')
|
13
|
+
end
|
14
|
+
|
9
15
|
def test_single_app_with_404
|
10
16
|
r = router { add('test').post.to{|env| [404, {}, []]} }
|
11
17
|
assert_route nil, Rack::MockRequest.env_for('/test', :method => 'POST')
|
data/test/test_variable.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 63
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Joshua Hull
|
@@ -10,108 +15,147 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-06-01 00:00:00 -04:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
17
|
-
|
18
|
-
prerelease: false
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
20
23
|
none: false
|
21
24
|
requirements:
|
22
25
|
- - ">="
|
23
26
|
- !ruby/object:Gem::Version
|
27
|
+
hash: 23
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
24
32
|
version: 1.0.0
|
33
|
+
requirement: *id001
|
34
|
+
prerelease: false
|
25
35
|
type: :runtime
|
26
|
-
|
36
|
+
name: rack
|
27
37
|
- !ruby/object:Gem::Dependency
|
28
|
-
|
29
|
-
prerelease: false
|
30
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
31
39
|
none: false
|
32
40
|
requirements:
|
33
41
|
- - ~>
|
34
42
|
- !ruby/object:Gem::Version
|
43
|
+
hash: 21
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 2
|
47
|
+
- 1
|
35
48
|
version: 0.2.1
|
49
|
+
requirement: *id002
|
50
|
+
prerelease: false
|
36
51
|
type: :runtime
|
37
|
-
|
52
|
+
name: url_mount
|
38
53
|
- !ruby/object:Gem::Dependency
|
39
|
-
|
40
|
-
prerelease: false
|
41
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
42
55
|
none: false
|
43
56
|
requirements:
|
44
57
|
- - ~>
|
45
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 15
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 0
|
63
|
+
- 0
|
46
64
|
version: 2.0.0
|
65
|
+
requirement: *id003
|
66
|
+
prerelease: false
|
47
67
|
type: :development
|
48
|
-
|
68
|
+
name: minitest
|
49
69
|
- !ruby/object:Gem::Dependency
|
50
|
-
|
51
|
-
prerelease: false
|
52
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
53
71
|
none: false
|
54
72
|
requirements:
|
55
73
|
- - ">="
|
56
74
|
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
57
78
|
version: "0"
|
79
|
+
requirement: *id004
|
80
|
+
prerelease: false
|
58
81
|
type: :development
|
59
|
-
|
82
|
+
name: code_stats
|
60
83
|
- !ruby/object:Gem::Dependency
|
61
|
-
|
62
|
-
prerelease: false
|
63
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
64
85
|
none: false
|
65
86
|
requirements:
|
66
87
|
- - ~>
|
67
88
|
- !ruby/object:Gem::Version
|
89
|
+
hash: 49
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
- 8
|
93
|
+
- 7
|
68
94
|
version: 0.8.7
|
95
|
+
requirement: *id005
|
96
|
+
prerelease: false
|
69
97
|
type: :development
|
70
|
-
|
98
|
+
name: rake
|
71
99
|
- !ruby/object:Gem::Dependency
|
72
|
-
|
73
|
-
prerelease: false
|
74
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
100
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
75
101
|
none: false
|
76
102
|
requirements:
|
77
103
|
- - ">="
|
78
104
|
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
106
|
+
segments:
|
107
|
+
- 0
|
79
108
|
version: "0"
|
109
|
+
requirement: *id006
|
110
|
+
prerelease: false
|
80
111
|
type: :development
|
81
|
-
|
112
|
+
name: rbench
|
82
113
|
- !ruby/object:Gem::Dependency
|
83
|
-
|
84
|
-
prerelease: false
|
85
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
114
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
86
115
|
none: false
|
87
116
|
requirements:
|
88
117
|
- - ">="
|
89
118
|
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
90
122
|
version: "0"
|
123
|
+
requirement: *id007
|
124
|
+
prerelease: false
|
91
125
|
type: :development
|
92
|
-
|
126
|
+
name: phocus
|
93
127
|
- !ruby/object:Gem::Dependency
|
94
|
-
|
95
|
-
prerelease: false
|
96
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
128
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
97
129
|
none: false
|
98
130
|
requirements:
|
99
131
|
- - ~>
|
100
132
|
- !ruby/object:Gem::Version
|
133
|
+
hash: 23
|
134
|
+
segments:
|
135
|
+
- 1
|
136
|
+
- 0
|
137
|
+
- 0
|
101
138
|
version: 1.0.0
|
139
|
+
requirement: *id008
|
140
|
+
prerelease: false
|
102
141
|
type: :development
|
103
|
-
|
142
|
+
name: bundler
|
104
143
|
- !ruby/object:Gem::Dependency
|
105
|
-
|
106
|
-
prerelease: false
|
107
|
-
requirement: &id009 !ruby/object:Gem::Requirement
|
144
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
108
145
|
none: false
|
109
146
|
requirements:
|
110
147
|
- - "="
|
111
148
|
- !ruby/object:Gem::Version
|
149
|
+
hash: 15
|
150
|
+
segments:
|
151
|
+
- 1
|
152
|
+
- 2
|
153
|
+
- 8
|
112
154
|
version: 1.2.8
|
155
|
+
requirement: *id009
|
156
|
+
prerelease: false
|
113
157
|
type: :development
|
114
|
-
|
158
|
+
name: thin
|
115
159
|
description: This library allows you to recognize and build URLs in a Rack application.
|
116
160
|
email: joshbuddy@gmail.com
|
117
161
|
executables: []
|
@@ -195,12 +239,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
195
239
|
requirements:
|
196
240
|
- - ">="
|
197
241
|
- !ruby/object:Gem::Version
|
242
|
+
hash: 3
|
243
|
+
segments:
|
244
|
+
- 0
|
198
245
|
version: "0"
|
199
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
247
|
none: false
|
201
248
|
requirements:
|
202
249
|
- - ">="
|
203
250
|
- !ruby/object:Gem::Version
|
251
|
+
hash: 3
|
252
|
+
segments:
|
253
|
+
- 0
|
204
254
|
version: "0"
|
205
255
|
requirements: []
|
206
256
|
|