http_router 0.4.1 → 0.5.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/Rakefile +6 -5
- data/benchmarks/rack_mount.rb +16 -45
- data/benchmarks/rec2.rb +8 -8
- data/http_router.gemspec +5 -4
- data/lib/http_router/interface/sinatra.rb +7 -7
- data/lib/http_router/node.rb +106 -105
- data/lib/http_router/optional_compiler.rb +14 -5
- data/lib/http_router/path.rb +18 -28
- data/lib/http_router/root.rb +17 -29
- data/lib/http_router/route.rb +47 -16
- data/lib/http_router/static.rb +5 -0
- data/lib/http_router/variable.rb +2 -5
- data/lib/http_router/version.rb +1 -1
- data/lib/http_router.rb +38 -65
- data/test/helper.rb +74 -0
- data/test/rack/test_dispatch.rb +120 -0
- data/test/rack/test_route.rb +44 -0
- data/test/rack/test_urlmap.rb +12 -0
- data/{spec → test}/sinatra/recognize_spec.rb +0 -0
- data/test/sinatra/test_recognize.rb +150 -0
- data/test/test_arbitrary.rb +50 -0
- data/test/test_generate.rb +93 -0
- data/test/test_greedy.rb +24 -0
- data/test/test_interstitial.rb +47 -0
- data/test/test_misc.rb +30 -0
- data/test/test_mounting.rb +89 -0
- data/test/test_recognize.rb +56 -0
- data/test/test_request.rb +85 -0
- data/test/test_trailing_slash.rb +28 -0
- data/test/test_variable.rb +108 -0
- metadata +41 -32
- data/lib/http_router/response.rb +0 -46
- data/spec/generate_spec.rb +0 -234
- data/spec/misc_spec.rb +0 -65
- data/spec/mounting_spec.rb +0 -5
- data/spec/rack/dispatch_spec.rb +0 -119
- data/spec/rack/generate_spec.rb +0 -29
- data/spec/rack/middleware_spec.rb +0 -22
- data/spec/rack/route_spec.rb +0 -72
- data/spec/rack/urlmap_spec.rb +0 -13
- data/spec/recognize_spec.rb +0 -497
- data/spec/spec_helper.rb +0 -25
@@ -0,0 +1,150 @@
|
|
1
|
+
require "sinatra"
|
2
|
+
require "http_router/interface/sinatra"
|
3
|
+
|
4
|
+
module CallWithMockRequestMixin
|
5
|
+
def call_with_mock_request(url = "/sample", method = "GET", params = Hash.new)
|
6
|
+
params.merge!(:method => method)
|
7
|
+
request = Rack::MockRequest.new(self)
|
8
|
+
request.request(method, url, params)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestRecognize < MiniTest::Unit::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@app = Sinatra.new { register HttpRouter::Interface::Sinatra::Extension }
|
16
|
+
@app.extend(CallWithMockRequestMixin)
|
17
|
+
@app.reset!
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_basic
|
21
|
+
response = @app.call_with_mock_request('/bar')
|
22
|
+
assert_equal 404, response.status
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_map_index
|
26
|
+
@app.get("/") { "index" }
|
27
|
+
response = @app.call_with_mock_request('/')
|
28
|
+
assert_equal 200, response.status
|
29
|
+
assert_equal "index", response.body
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_trailing_slash
|
33
|
+
@app.get("/foo") { "foo" }
|
34
|
+
response = @app.call_with_mock_request('/foo')
|
35
|
+
assert_equal 200, response.status
|
36
|
+
assert_equal "foo", response.body
|
37
|
+
response = @app.call_with_mock_request('/foo/')
|
38
|
+
assert_equal 200, response.status
|
39
|
+
assert_equal "foo", response.body
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_trailing_slash2
|
43
|
+
@app.get("/foo") { "foo" }
|
44
|
+
@app.get("/foo/bar") { "bar" }
|
45
|
+
response = @app.call_with_mock_request('/foo')
|
46
|
+
assert_equal 200, response.status
|
47
|
+
assert_equal "foo", response.body
|
48
|
+
response = @app.call_with_mock_request('/foo/bar')
|
49
|
+
assert_equal 200, response.status
|
50
|
+
assert_equal "bar", response.body
|
51
|
+
response = @app.call_with_mock_request('/foo/')
|
52
|
+
assert_equal 200, response.status
|
53
|
+
assert_equal "foo", response.body
|
54
|
+
response = @app.call_with_mock_request('/foo/bar/')
|
55
|
+
assert_equal 200, response.status
|
56
|
+
assert_equal "bar", response.body
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_trailing_slash_with_optional_param
|
60
|
+
@app.get("/foo/(:bar)") { params[:bar] }
|
61
|
+
@app.get("/bar(/:foo)") { params[:foo] }
|
62
|
+
response = @app.call_with_mock_request('/foo/bar')
|
63
|
+
assert_equal 200, response.status
|
64
|
+
assert_equal "bar", response.body
|
65
|
+
response = @app.call_with_mock_request('/bar/foo')
|
66
|
+
assert_equal 200, response.status
|
67
|
+
assert_equal "foo", response.body
|
68
|
+
response = @app.call_with_mock_request('/bar')
|
69
|
+
assert_equal 200, response.status
|
70
|
+
assert_equal "", response.body
|
71
|
+
response = @app.call_with_mock_request('/bar/')
|
72
|
+
assert_equal 200, response.status
|
73
|
+
assert_equal "", response.body
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_trailing_question_mark
|
77
|
+
@app.get("/foo/?") { "foo" }
|
78
|
+
response = @app.call_with_mock_request('/foo')
|
79
|
+
assert_equal 200, response.status
|
80
|
+
assert_equal "foo", response.body
|
81
|
+
response = @app.call_with_mock_request('/foo/')
|
82
|
+
assert_equal 200, response.status
|
83
|
+
assert_equal "foo", response.body
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_map_basic
|
87
|
+
@app.get('/hi', :name => :hi) { generate(:hi) }
|
88
|
+
response = @app.call_with_mock_request('/hi')
|
89
|
+
assert_equal 200, response.status
|
90
|
+
assert_equal "/hi", response.body
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_map_basic2
|
94
|
+
@app.get('/hi', :name => :hi) { generate(:hi) }
|
95
|
+
response = @app.call_with_mock_request('/hi/')
|
96
|
+
assert_equal 200, response.status
|
97
|
+
assert_equal "/hi", response.body
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_map_param
|
101
|
+
@app.get('/hi/:id', :name => :hi) { generate(:hi, :id => 18) }
|
102
|
+
response = @app.call_with_mock_request('/hi/1')
|
103
|
+
assert_equal 200, response.status
|
104
|
+
assert_equal "/hi/18", response.body
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_map_param2
|
108
|
+
@app.get('/hi-:id', :name => :hi) { generate(:hi, :id => 18) }
|
109
|
+
response = @app.call_with_mock_request('/hi-1')
|
110
|
+
assert_equal 200, response.status
|
111
|
+
assert_equal "/hi-18", response.body
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_map_complex
|
115
|
+
@app.get('/hi/:foo/:bar/:baz(.:format)') { "/#{params[:foo]}/#{params[:bar]}/#{params[:baz]}/#{params[:format]}" }
|
116
|
+
response = @app.call_with_mock_request('/hi/foo/bar/baz')
|
117
|
+
assert_equal 200, response.status
|
118
|
+
assert_equal "/foo/bar/baz/", response.body
|
119
|
+
response = @app.call_with_mock_request('/hi/foo/bar-bax/baz')
|
120
|
+
assert_equal 200, response.status
|
121
|
+
assert_equal "/foo/bar-bax/baz/", response.body
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_map_regexp
|
125
|
+
@app.get('/numbers/:digits', :matching => { :digits => /\d+/ }) { params[:digits] }
|
126
|
+
response = @app.call_with_mock_request('/numbers/2010')
|
127
|
+
assert_equal 200, response.status
|
128
|
+
assert_equal "2010", response.body
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_not_map_regex
|
132
|
+
@app.get('/numbers/:digits', :matching => { :digits => /\d+/ }) { params[:digits] }
|
133
|
+
response = @app.call_with_mock_request('/numbers/nan')
|
134
|
+
assert_equal 404, response.status
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_404
|
138
|
+
response = @app.call_with_mock_request('/bar')
|
139
|
+
assert_equal 404, response.status
|
140
|
+
assert_match response.body, /Sinatra doesn't know this ditty/
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_405
|
144
|
+
@app.post('/bar') { 'found' }
|
145
|
+
@app.put('/bar') { 'found' }
|
146
|
+
response = @app.call_with_mock_request('/bar')
|
147
|
+
assert_equal 405, response.status
|
148
|
+
assert_equal ['POST', 'PUT'], response.headers['Allow'].split(/\s*,\s*/).sort
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class TestArbitrary < MiniTest::Unit::TestCase
|
2
|
+
def test_match
|
3
|
+
hello, love80, love8080 = router {
|
4
|
+
add('test').arbitrary(Proc.new{|req, params| req.host == 'hellodooly' })
|
5
|
+
add("test").arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 80}
|
6
|
+
add("test").arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 8080}
|
7
|
+
}
|
8
|
+
assert_route love8080, 'http://lovelove:8080/test'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_less_specific_node
|
12
|
+
general, hello, love80, love8080 = router {
|
13
|
+
add("/test")
|
14
|
+
add("/test").arbitrary(Proc.new{|req, params| req.host == 'hellodooly' })
|
15
|
+
add("/test").arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 80}
|
16
|
+
add("/test").arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 8080}
|
17
|
+
}
|
18
|
+
assert_route general, 'http://lovelove:8081/test'
|
19
|
+
assert_route hello, 'http://hellodooly:8081/test'
|
20
|
+
assert_route love80, 'http://lovelove:80/test'
|
21
|
+
assert_route love8080, 'http://lovelove:8080/test'
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_match_request
|
25
|
+
love80, love8080 = router {
|
26
|
+
add("/test").get.arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 80}
|
27
|
+
add("/test").get.arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 8080}
|
28
|
+
}
|
29
|
+
assert_route love80, 'http://lovelove:80/test'
|
30
|
+
assert_route love8080, 'http://lovelove:8080/test'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_less_specific_with_request
|
34
|
+
love80, love8080, general = router {
|
35
|
+
add("test").post.arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 80}
|
36
|
+
add("test").post.arbitrary(Proc.new{|req, params| req.host == 'lovelove' }).arbitrary{|req, params, dest| req.port == 8080}
|
37
|
+
add("test").post
|
38
|
+
}
|
39
|
+
assert_route love8080, Rack::MockRequest.env_for('http://lovelove:8080/test', :method => :post)
|
40
|
+
assert_route love80, Rack::MockRequest.env_for('http://lovelove:80/test', :method => :post)
|
41
|
+
assert_route general, Rack::MockRequest.env_for('/test', :method => :post)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_pass_params
|
45
|
+
r = router {
|
46
|
+
add(":test").get.arbitrary(Proc.new{|req, params, dest| params[:test] == 'test' })
|
47
|
+
}
|
48
|
+
assert_route r, '/test', {:test => 'test'}
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class TestGenerate < MiniTest::Unit::TestCase
|
2
|
+
|
3
|
+
def test_static
|
4
|
+
router {
|
5
|
+
add('/').name(:a)
|
6
|
+
add('/test').name(:b)
|
7
|
+
add('/test/time').name(:c)
|
8
|
+
add('/one/more/what').name(:d)
|
9
|
+
add('/test.html').name(:e)
|
10
|
+
}
|
11
|
+
assert_generate '/', :a
|
12
|
+
assert_generate '/test', :b
|
13
|
+
assert_generate '/test/time', :c
|
14
|
+
assert_generate '/one/more/what', :d
|
15
|
+
assert_generate '/test.html', :e
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_dynamic
|
19
|
+
assert_generate '/test', '/:var', :var => 'test'
|
20
|
+
assert_generate '/test', '/:var', 'test'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_array_with_extras
|
24
|
+
assert_generate '/test?query=string', '/:var', :var => 'test', :query => 'string'
|
25
|
+
assert_generate '/test?query=string', '/:var', 'test', :query => 'string'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_multiple_dynamics
|
29
|
+
assert_generate '/one/two', "/:var/:baz", :var => 'one', :baz => 'two'
|
30
|
+
assert_generate '/one/two', "/:var/:baz", 'one', 'two'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_extension
|
34
|
+
assert_generate '/test.html', "/test.:format", :format => 'html'
|
35
|
+
assert_generate '/test.html', "/test.:format", 'html'
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_optional_extension
|
39
|
+
assert_generate '/test.html', "/test(.:format)", :format => 'html'
|
40
|
+
assert_generate '/test.html', "/test(.:format)", 'html'
|
41
|
+
assert_generate '/test', "/test(.:format)"
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_variable_with_extension
|
45
|
+
assert_generate '/test.html', "/:var.:format", :var => 'test', :format => 'html'
|
46
|
+
assert_generate '/test.html', "/:var.:format", 'test', 'html'
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_variable_with_optional_extension
|
50
|
+
assert_generate '/test.html', "/:var(.:format)", :var => 'test', :format => 'html'
|
51
|
+
assert_generate '/test.html', "/:var(.:format)", 'test', 'html'
|
52
|
+
assert_generate '/test', "/:var(.:format)", :var => 'test'
|
53
|
+
assert_generate '/test', "/:var(.:format)", 'test'
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_optionals
|
57
|
+
assert_generate '/var', "/:var1(/:var2)", 'var'
|
58
|
+
assert_generate '/var/fooz', "/:var1(/:var2)", 'var', 'fooz'
|
59
|
+
assert_generate '/var', "/:var1(/:var2)", :var1 => 'var'
|
60
|
+
assert_generate '/var/fooz', "/:var1(/:var2)", :var1 => 'var', :var2 => 'fooz'
|
61
|
+
assert_raises(HttpRouter::UngeneratableRouteException) { router.url(router.add("/:var1(/:var2)").to(:test), :var2 => 'fooz') }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_optionals_with_format
|
65
|
+
assert_generate '/var', "/:var1(/:var2.:format)", 'var'
|
66
|
+
assert_generate '/var/fooz.html', "/:var1(/:var2.:format)", 'var', 'fooz', 'html'
|
67
|
+
assert_generate '/var', "/:var1(/:var2.:format)", :var1 => 'var'
|
68
|
+
assert_generate '/var/fooz.html', "/:var1(/:var2.:format)", :var1 => 'var', :var2 => 'fooz', :format => 'html'
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_nested_optionals
|
72
|
+
assert_generate '/var', "/:var1(/:var2(/:var3))", 'var'
|
73
|
+
assert_generate '/var/fooz', "/:var1(/:var2(/:var3))", 'var', 'fooz'
|
74
|
+
assert_generate '/var/fooz/baz', "/:var1(/:var2(/:var3))", 'var', 'fooz', 'baz'
|
75
|
+
assert_generate '/var', "/:var1(/:var2(/:var3))", :var1 => 'var'
|
76
|
+
assert_generate '/var/fooz', "/:var1(/:var2(/:var3))", :var1 => 'var', :var2 => 'fooz'
|
77
|
+
assert_generate '/var/fooz/baz', "/:var1(/:var2(/:var3))", :var1 => 'var', :var2 => 'fooz', :var3 => 'baz'
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_default_value
|
81
|
+
assert_generate "/123?page=1", router.add("/:var").default(:page => 1), 123
|
82
|
+
assert_generate "/1/123", router.add("/:page/:entry").default(:page => 1), :entry => '123'
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_nil_values
|
86
|
+
assert_generate '/url', "/url(/:var)", :var => nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_raise
|
90
|
+
r = router { add(':var').matching(:var => /\d+/) }
|
91
|
+
assert_raises(HttpRouter::InvalidRouteException) { router.url(r, 'asd') }
|
92
|
+
end
|
93
|
+
end
|
data/test/test_greedy.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class TestGreedy < MiniTest::Unit::TestCase
|
2
|
+
def test_mix_regex_with_greedy
|
3
|
+
regex, greedy = router {
|
4
|
+
add("/:test/number").matching(:test => /\d+/)
|
5
|
+
add("/:test/anything")
|
6
|
+
}
|
7
|
+
assert_route regex, '/123/number', {:test => '123'}
|
8
|
+
assert_route greedy, '/123/anything', {:test => '123'}
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_trailing_slash
|
12
|
+
assert_route router.add("/:test").matching(:test => /.*/), '/test/', {:test => 'test/'}
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_extension
|
16
|
+
assert_route router.add("/:test").matching(:test => /.*/), '/test.html', {:test => 'test.html'}
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_match_at_beginning
|
20
|
+
r = router { add(':test', :test => /\d+/)}
|
21
|
+
assert_route r, '/123', {:test => '123'}
|
22
|
+
assert_route nil, '/a123'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class TestInterstitial < MiniTest::Unit::TestCase
|
2
|
+
def test_recognize
|
3
|
+
assert_route '/one-:variable-time', '/one-value-time', {:variable => 'value'}
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_regex
|
7
|
+
r = router { add('/one-:variable-time').matching(:variable => /\d+/) }
|
8
|
+
assert_route r, '/one-123-time', {:variable => '123'}
|
9
|
+
assert_route nil, '/one-value-time'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_regex_as_options
|
13
|
+
r = router { add('/one-:variable-time', :variable => /\d+/) }
|
14
|
+
assert_route r, '/one-123-time', {:variable => '123'}
|
15
|
+
assert_route nil, '/one-value-time'
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_extension
|
19
|
+
assert_route 'hey.:greed.html', '/hey.greedybody.html', {:greed => 'greedybody'}
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_multi
|
23
|
+
r1, r2, r3, r4, r5, r6 = router {
|
24
|
+
add('/:var1')
|
25
|
+
add('/:var1-:var2')
|
26
|
+
add('/:var1-:var2-:var3')
|
27
|
+
add('/:var1-:var2-:var3-:var4')
|
28
|
+
add('/:var1-:var2-:var3-:var4-:var5')
|
29
|
+
add('/:var1-:var2-:var3-:var4-:var5-:var6')
|
30
|
+
}
|
31
|
+
assert_route r1, '/one', {:var1 => 'one'}
|
32
|
+
assert_route r2, '/one-value', {:var1 => 'one', :var2 => 'value'}
|
33
|
+
assert_route r3, '/one-value-time', {:var1 => 'one', :var2 => 'value', :var3 => 'time'}
|
34
|
+
assert_route r4, '/one-value-time-one', {:var1 => 'one', :var2 => 'value', :var3 => 'time', :var4 => 'one'}
|
35
|
+
assert_route r5, '/one-value-time-one-variable', {:var1 => 'one', :var2 => 'value', :var3 => 'time', :var4 => 'one', :var5 => 'variable'}
|
36
|
+
assert_route r6, '/one-value-time-one-value-time', {:var1 => 'one', :var2 => 'value', :var3 => 'time', :var4 => 'one', :var5 => 'value', :var6 => 'time'}
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_regex_with_mutliple_variables
|
40
|
+
with_regex, without_regex = router {
|
41
|
+
add("/:common_variable.:matched").matching(:matched => /\d+/)
|
42
|
+
add("/:common_variable.:unmatched")
|
43
|
+
}
|
44
|
+
assert_route with_regex, '/common.123', {:common_variable => 'common', :matched => '123'}
|
45
|
+
assert_route without_regex, '/common.other', {:common_variable => 'common', :unmatched => 'other'}
|
46
|
+
end
|
47
|
+
end
|
data/test/test_misc.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
class TestMisc < MiniTest::Unit::TestCase
|
2
|
+
def test_exceptions
|
3
|
+
assert_raises(HttpRouter::AmbiguousRouteException) {HttpRouter.new.add("/:var1(/:var2)(/:var3)").compile}
|
4
|
+
assert_raises(HttpRouter::AmbiguousVariableException) {HttpRouter.new.add("/:var1(/:var1)(/:var1)").compile}
|
5
|
+
assert_raises(HttpRouter::UnsupportedRequestConditionError) {HttpRouter.new.add("/").condition(:flibberty => 'gibet').compile}
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_cloning
|
9
|
+
r1 = HttpRouter.new {
|
10
|
+
add('/test').name(:test_route).to :test
|
11
|
+
}
|
12
|
+
r2 = r1.clone
|
13
|
+
|
14
|
+
r2.add('/test2').name(:test).to(:test2)
|
15
|
+
assert_equal 2, r2.routes.size
|
16
|
+
|
17
|
+
assert r1.recognize(Rack::MockRequest.env_for('/test2')).nil?
|
18
|
+
assert !r2.recognize(Rack::MockRequest.env_for('/test2')).nil?
|
19
|
+
assert_equal r1.routes.first, r1.named_routes[:test_route]
|
20
|
+
assert_equal r2.routes.first, r2.named_routes[:test_route]
|
21
|
+
|
22
|
+
r1.add('/another').name(:test).to(:test2)
|
23
|
+
|
24
|
+
assert_equal r1.routes.size, r2.routes.size
|
25
|
+
assert_equal '/another', r1.url(:test)
|
26
|
+
assert_equal '/test2', r2.url(:test)
|
27
|
+
assert_equal :test, r1.routes.first.dest
|
28
|
+
assert_equal :test, r2.routes.first.dest
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
class TestMounting < MiniTest::Unit::TestCase
|
2
|
+
def setup
|
3
|
+
@r1 = HttpRouter.new
|
4
|
+
@r2 = HttpRouter.new
|
5
|
+
@r2.add("/bar").name(:test).compile
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_url_mount_for_child_route
|
9
|
+
route = @r1.add("/foo").to(@r2)
|
10
|
+
assert_equal "/foo", @r2.url_mount.url
|
11
|
+
assert_equal "/foo/bar", @r2.url(:test)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_default_values
|
15
|
+
route = @r1.add("/foo/:bar").default(:bar => "baz").to(@r2)
|
16
|
+
assert_equal "/foo/baz/bar", @r2.url(:test)
|
17
|
+
assert_equal "/foo/haha/bar", @r2.url(:test, :bar => "haha")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_multiple_values
|
21
|
+
@r1.add("/foo/:bar/:baz").default(:bar => "bar").to(@r2)
|
22
|
+
assert_equal "/foo/bar/baz/bar", @r2.url(:test, :baz => "baz")
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_bubble_params
|
26
|
+
route = @r1.add("/foo/:bar").default(:bar => "baz").to(@r2)
|
27
|
+
assert_equal "/foo/baz/bar?bang=ers", @r2.url(:test, :bang => "ers")
|
28
|
+
assert_equal "/foo/haha/bar?bang=ers", @r2.url(:test, :bar => "haha", :bang => "ers")
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_path_with_optional
|
32
|
+
@r1.add("/foo(/:bar)").to(@r2)
|
33
|
+
@r2.add("/hey(/:there)").name(:test).compile
|
34
|
+
assert_equal "/foo/hey", @r2.url(:test)
|
35
|
+
assert_equal "/foo/bar/hey", @r2.url(:test, :bar => "bar")
|
36
|
+
assert_equal "/foo/bar/hey/there", @r2.url(:test, :bar => "bar", :there => "there")
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_nest3
|
40
|
+
@r3 = HttpRouter.new
|
41
|
+
@r1.add("/foo(/:bar)").default(:bar => "barry").to(@r2)
|
42
|
+
@r2.add("/hi").name(:hi).compile
|
43
|
+
@r2.add("/mounted").to(@r3)
|
44
|
+
@r3.add("/endpoint").name(:endpoint).compile
|
45
|
+
|
46
|
+
assert_equal "/foo/barry/hi", @r2.url(:hi)
|
47
|
+
assert_equal "/foo/barry/mounted/endpoint", @r3.url(:endpoint)
|
48
|
+
assert_equal "/foo/flower/mounted/endpoint", @r3.url(:endpoint, :bar => "flower")
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_with_default_host
|
52
|
+
@r1.add("/mounted").default(:host => "example.com").to(@r2)
|
53
|
+
assert_equal "http://example.com/mounted/bar", @r2.url(:test)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_with_host
|
57
|
+
@r1.add("/mounted").to(@r2)
|
58
|
+
assert_equal "/mounted/bar", @r2.url(:test)
|
59
|
+
assert_equal "http://example.com/mounted/bar", @r2.url(:test, :host => "example.com")
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_with_scheme
|
63
|
+
@r1.add("/mounted").to(@r2)
|
64
|
+
assert_equal "/mounted/bar", @r2.url(:test)
|
65
|
+
assert_equal "https://example.com/mounted/bar", @r2.url(:test, :scheme => "https", :host => "example.com")
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_clone
|
69
|
+
@r3 = HttpRouter.new
|
70
|
+
@r1.add("/first").to(@r2)
|
71
|
+
@r2.add("/second").to(@r3)
|
72
|
+
r1 = @r1.clone
|
73
|
+
assert @r1.routes.first
|
74
|
+
r2 = r1.routes.first.dest
|
75
|
+
assert r2
|
76
|
+
assert_equal @r1.routes.first.dest.object_id, @r2.object_id
|
77
|
+
assert r2.object_id != @r2.object_id
|
78
|
+
assert_equal 2, r2.routes.size
|
79
|
+
r3 = r2.routes.last.dest
|
80
|
+
assert_instance_of HttpRouter, r3
|
81
|
+
assert r3.object_id != @r3.object_id
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# it "should clone my nested structure" do
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
#end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class TestRecognition < MiniTest::Unit::TestCase
|
2
|
+
def test_simple
|
3
|
+
assert_route router.add(''), '/'
|
4
|
+
assert_route router.add('/'), '/'
|
5
|
+
assert_route router.add('/test'), '/test'
|
6
|
+
assert_route router.add('/test/one'), '/test/one'
|
7
|
+
assert_route router.add('/test/one/two'), '/test/one/two'
|
8
|
+
assert_route router.add('/test.html'), '/test.html'
|
9
|
+
assert_route router.add('/.html'), '/.html'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_optional
|
13
|
+
route = router {
|
14
|
+
add 'one(/two(/three(/four)(/five)))'
|
15
|
+
}
|
16
|
+
assert_route route, '/one'
|
17
|
+
assert_route route, '/one/two'
|
18
|
+
assert_route route, '/one/two/three'
|
19
|
+
assert_route route, '/one/two/three/four'
|
20
|
+
assert_route route, '/one/two/three/five'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_escape_paren
|
24
|
+
assert_route router.add('/test\(:variable\)'), '/test(hello)', {:variable => 'hello'}
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_escape_colon
|
28
|
+
assert_route router.add('/test\:variable'), '/test:variable'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_escape_star
|
32
|
+
assert_route router.add('/test\*variable'), '/test*variable'
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_partial
|
36
|
+
router.add("/test*").to { |env| Rack::Response.new(env['PATH_INFO']).finish }
|
37
|
+
assert_body '/optional', router.call(Rack::MockRequest.env_for('/test/optional'))
|
38
|
+
assert_body '/', router.call(Rack::MockRequest.env_for('/test'))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_partial_root
|
42
|
+
router.add("/*").to { |env| Rack::Response.new(env['PATH_INFO']).finish }
|
43
|
+
assert_body '/optional', router.call(Rack::MockRequest.env_for('/optional'))
|
44
|
+
assert_body '/', router.call(Rack::MockRequest.env_for('/'))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_multiple_partial
|
48
|
+
test, root = router {
|
49
|
+
add("/test").partial.to{|env| [200, {}, ['/test',env['PATH_INFO']]]}
|
50
|
+
add("/").partial.to{|env| [200, {}, ['/',env['PATH_INFO']]]}
|
51
|
+
}
|
52
|
+
assert_body ['/test', '/optional'], router.call(Rack::MockRequest.env_for('/test/optional'))
|
53
|
+
assert_body ['/test', '/optional/'], router.call(Rack::MockRequest.env_for('/test/optional/'))
|
54
|
+
assert_body ['/', '/testing/optional'], router.call(Rack::MockRequest.env_for('/testing/optional'))
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class TestRequest < MiniTest::Unit::TestCase
|
2
|
+
def test_simple_case
|
3
|
+
r = router { add('test').post }
|
4
|
+
assert_route r, Rack::MockRequest.env_for('/test', :method => 'POST')
|
5
|
+
assert_header({'Allow' => 'POST'}, Rack::MockRequest.env_for('/test', :method => 'GET'))
|
6
|
+
assert_status(405, Rack::MockRequest.env_for('/test', :method => 'GET'))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_with_optional_parts_and_405
|
10
|
+
get, post, delete = router {
|
11
|
+
get('test(.:format)')
|
12
|
+
post('test(.:format)')
|
13
|
+
delete('test(.:format)')
|
14
|
+
}
|
15
|
+
assert_route get, Rack::MockRequest.env_for('/test', :method => 'GET')
|
16
|
+
assert_route post, Rack::MockRequest.env_for('/test', :method => 'POST')
|
17
|
+
assert_route delete, Rack::MockRequest.env_for('/test', :method => 'DELETE')
|
18
|
+
assert_route get, Rack::MockRequest.env_for('/test.html', :method => 'GET'), {:format => 'html'}
|
19
|
+
assert_route post, Rack::MockRequest.env_for('/test.html', :method => 'POST'), {:format => 'html'}
|
20
|
+
assert_route delete, Rack::MockRequest.env_for('/test.html', :method => 'DELETE'), {:format => 'html'}
|
21
|
+
put = router.call(Rack::MockRequest.env_for('/test', :method => 'PUT'))
|
22
|
+
assert_status 405, put
|
23
|
+
assert_equal %w{DELETE GET POST}, put[1]['Allow'].split(/\s*,\s*/).sort
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_deeply
|
27
|
+
test_post, test_post_post, test_get, test_post_get, test_post_catchall, test_catchall = router {
|
28
|
+
post("/test")
|
29
|
+
post("/test/post")
|
30
|
+
get("/test")
|
31
|
+
get("/test/post")
|
32
|
+
add("/test/post")
|
33
|
+
add("/test")
|
34
|
+
}
|
35
|
+
assert_route test_post, Rack::MockRequest.env_for('/test', :method => 'POST')
|
36
|
+
assert_route test_get, Rack::MockRequest.env_for('/test', :method => 'GET')
|
37
|
+
assert_route test_catchall, Rack::MockRequest.env_for('/test', :method => 'PUT')
|
38
|
+
assert_route test_post_post, Rack::MockRequest.env_for('/test/post', :method => 'POST')
|
39
|
+
assert_route test_post_get, Rack::MockRequest.env_for('/test/post', :method => 'GET')
|
40
|
+
assert_route test_post_catchall, Rack::MockRequest.env_for('/test/post', :method => 'PUT')
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_move_node
|
44
|
+
general, post = router {
|
45
|
+
add("/test").default_destination
|
46
|
+
post("/test").default_destination
|
47
|
+
}
|
48
|
+
assert_route post, Rack::MockRequest.env_for('/test', :method => 'POST')
|
49
|
+
assert_route general, Rack::MockRequest.env_for('/test', :method => 'PUT')
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_complex_routing
|
53
|
+
host2, post, host2_get, host2_post = router {
|
54
|
+
add("/test").host('host2')
|
55
|
+
add("/test").post
|
56
|
+
add("/test").host('host2').get
|
57
|
+
add("/test").post.host('host2')
|
58
|
+
}
|
59
|
+
assert_route host2, Rack::MockRequest.env_for('http://host2/test', :method => 'PUT')
|
60
|
+
assert_route post, Rack::MockRequest.env_for('http://host1/test', :method => 'POST')
|
61
|
+
assert_route host2_get, Rack::MockRequest.env_for('http://host2/test', :method => 'GET')
|
62
|
+
assert_route host2_post, Rack::MockRequest.env_for('http://host2/test', :method => 'POST')
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_regexp
|
66
|
+
with, without = router {
|
67
|
+
get("/test").host(/host1/)
|
68
|
+
get("/test")
|
69
|
+
}
|
70
|
+
assert_route without, 'http://host2/test'
|
71
|
+
assert_route with, 'http://host2.host1.com/test'
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_all_routes
|
75
|
+
router {
|
76
|
+
post("/test").host('host1')
|
77
|
+
}
|
78
|
+
assert_route router.add("/test").host('host2'), Rack::MockRequest.env_for('http://host2/test', :method => 'POST')
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_match_on_scheme
|
82
|
+
http, https = router { get("/test").scheme('http'); get("/test").scheme('https') }
|
83
|
+
assert_status 405, Rack::MockRequest.env_for('https://example.org/test', :method => 'POST')
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class TestVariable < MiniTest::Unit::TestCase
|
2
|
+
def test_ignore_trailing_slash
|
3
|
+
assert_route router.add('/test'), '/test/'
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_ignore_trailing_slash_disabled
|
7
|
+
assert_route router(:ignore_trailing_slash => false).add('/test/?'), '/test/'
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_ignore_trailing_slash_enabled
|
11
|
+
router(:ignore_trailing_slash => false).add('/test/?')
|
12
|
+
assert_route nil, '/test/'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_capture_with_trailing_slash
|
16
|
+
assert_route router.add('/:test'), '/test/', {:test => 'test'}
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_trailing_slash_confusion
|
20
|
+
more_general, more_specific = router {
|
21
|
+
add('foo')
|
22
|
+
add('foo/:bar/:id')
|
23
|
+
}
|
24
|
+
assert_route more_general, '/foo'
|
25
|
+
assert_route more_general, '/foo/'
|
26
|
+
assert_route more_specific, '/foo/5/10', {:bar => '5', :id => '10'}
|
27
|
+
end
|
28
|
+
end
|