andyjeffries-journey 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +8 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +6 -0
- data/Gemfile +11 -0
- data/Manifest.txt +49 -0
- data/README.rdoc +48 -0
- data/Rakefile +31 -0
- data/journey.gemspec +42 -0
- data/lib/journey/backwards.rb +5 -0
- data/lib/journey/core-ext/hash.rb +11 -0
- data/lib/journey/formatter.rb +129 -0
- data/lib/journey/gtg/builder.rb +159 -0
- data/lib/journey/gtg/simulator.rb +44 -0
- data/lib/journey/gtg/transition_table.rb +152 -0
- data/lib/journey/nfa/builder.rb +74 -0
- data/lib/journey/nfa/dot.rb +34 -0
- data/lib/journey/nfa/simulator.rb +45 -0
- data/lib/journey/nfa/transition_table.rb +164 -0
- data/lib/journey/nodes/node.rb +104 -0
- data/lib/journey/parser.rb +204 -0
- data/lib/journey/parser.y +47 -0
- data/lib/journey/parser_extras.rb +21 -0
- data/lib/journey/path/pattern.rb +190 -0
- data/lib/journey/route.rb +92 -0
- data/lib/journey/router/strexp.rb +22 -0
- data/lib/journey/router/utils.rb +57 -0
- data/lib/journey/router.rb +138 -0
- data/lib/journey/routes.rb +74 -0
- data/lib/journey/scanner.rb +58 -0
- data/lib/journey/visitors.rb +186 -0
- data/lib/journey/visualizer/d3.min.js +2 -0
- data/lib/journey/visualizer/fsm.css +34 -0
- data/lib/journey/visualizer/fsm.js +134 -0
- data/lib/journey/visualizer/index.html.erb +50 -0
- data/lib/journey/visualizer/reset.css +48 -0
- data/lib/journey.rb +5 -0
- data/test/gtg/test_builder.rb +77 -0
- data/test/gtg/test_transition_table.rb +113 -0
- data/test/helper.rb +4 -0
- data/test/nfa/test_simulator.rb +96 -0
- data/test/nfa/test_transition_table.rb +70 -0
- data/test/nodes/test_symbol.rb +15 -0
- data/test/path/test_pattern.rb +260 -0
- data/test/route/definition/test_parser.rb +108 -0
- data/test/route/definition/test_scanner.rb +52 -0
- data/test/router/test_strexp.rb +30 -0
- data/test/router/test_utils.rb +19 -0
- data/test/test_route.rb +95 -0
- data/test/test_router.rb +464 -0
- data/test/test_routes.rb +38 -0
- metadata +171 -0
@@ -0,0 +1,260 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
module Path
|
5
|
+
class TestPattern < MiniTest::Unit::TestCase
|
6
|
+
x = /.+/
|
7
|
+
{
|
8
|
+
'/:controller(/:action)' => %r{\A/(#{x}?)(?:/([^/.?]+))?\Z},
|
9
|
+
'/:controller/foo' => %r{\A/(#{x}?)/foo\Z},
|
10
|
+
'/:controller/:action' => %r{\A/(#{x}?)/([^/.?]+)\Z},
|
11
|
+
'/:controller' => %r{\A/(#{x}?)\Z},
|
12
|
+
'/:controller(/:action(/:id))' => %r{\A/(#{x}?)(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z},
|
13
|
+
'/:controller/:action.xml' => %r{\A/(#{x}?)/([^/.?]+)\.xml\Z},
|
14
|
+
'/:controller.:format' => %r{\A/(#{x}?)\.([^/.?]+)\Z},
|
15
|
+
'/:controller(.:format)' => %r{\A/(#{x}?)(?:\.([^/.?]+))?\Z},
|
16
|
+
'/:controller/*foo' => %r{\A/(#{x}?)/(.+)\Z},
|
17
|
+
'/:controller/*foo/bar' => %r{\A/(#{x}?)/(.+)/bar\Z},
|
18
|
+
}.each do |path, expected|
|
19
|
+
define_method(:"test_to_regexp_#{path}") do
|
20
|
+
strexp = Router::Strexp.new(
|
21
|
+
path,
|
22
|
+
{ :controller => /.+/ },
|
23
|
+
["/", ".", "?"]
|
24
|
+
)
|
25
|
+
path = Pattern.new strexp
|
26
|
+
assert_equal(expected, path.send(:to_regexp))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
{
|
31
|
+
'/:controller(/:action)' => %r{\A/(#{x}?)(?:/([^/.?]+))?},
|
32
|
+
'/:controller/foo' => %r{\A/(#{x}?)/foo},
|
33
|
+
'/:controller/:action' => %r{\A/(#{x}?)/([^/.?]+)},
|
34
|
+
'/:controller' => %r{\A/(#{x}?)},
|
35
|
+
'/:controller(/:action(/:id))' => %r{\A/(#{x}?)(?:/([^/.?]+)(?:/([^/.?]+))?)?},
|
36
|
+
'/:controller/:action.xml' => %r{\A/(#{x}?)/([^/.?]+)\.xml},
|
37
|
+
'/:controller.:format' => %r{\A/(#{x}?)\.([^/.?]+)},
|
38
|
+
'/:controller(.:format)' => %r{\A/(#{x}?)(?:\.([^/.?]+))?},
|
39
|
+
'/:controller/*foo' => %r{\A/(#{x}?)/(.+)},
|
40
|
+
'/:controller/*foo/bar' => %r{\A/(#{x}?)/(.+)/bar},
|
41
|
+
}.each do |path, expected|
|
42
|
+
define_method(:"test_to_non_anchored_regexp_#{path}") do
|
43
|
+
strexp = Router::Strexp.new(
|
44
|
+
path,
|
45
|
+
{ :controller => /.+/ },
|
46
|
+
["/", ".", "?"],
|
47
|
+
false
|
48
|
+
)
|
49
|
+
path = Pattern.new strexp
|
50
|
+
assert_equal(expected, path.send(:to_regexp))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
{
|
55
|
+
'/:controller(/:action)' => %w{ controller action },
|
56
|
+
'/:controller/foo' => %w{ controller },
|
57
|
+
'/:controller/:action' => %w{ controller action },
|
58
|
+
'/:controller' => %w{ controller },
|
59
|
+
'/:controller(/:action(/:id))' => %w{ controller action id },
|
60
|
+
'/:controller/:action.xml' => %w{ controller action },
|
61
|
+
'/:controller.:format' => %w{ controller format },
|
62
|
+
'/:controller(.:format)' => %w{ controller format },
|
63
|
+
'/:controller/*foo' => %w{ controller foo },
|
64
|
+
'/:controller/*foo/bar' => %w{ controller foo },
|
65
|
+
}.each do |path, expected|
|
66
|
+
define_method(:"test_names_#{path}") do
|
67
|
+
strexp = Router::Strexp.new(
|
68
|
+
path,
|
69
|
+
{ :controller => /.+/ },
|
70
|
+
["/", ".", "?"]
|
71
|
+
)
|
72
|
+
path = Pattern.new strexp
|
73
|
+
assert_equal(expected, path.names)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_to_regexp_with_extended_group
|
78
|
+
strexp = Router::Strexp.new(
|
79
|
+
'/page/:name',
|
80
|
+
{ :name => /
|
81
|
+
#ROFL
|
82
|
+
(tender|love
|
83
|
+
#MAO
|
84
|
+
)/x },
|
85
|
+
["/", ".", "?"]
|
86
|
+
)
|
87
|
+
path = Pattern.new strexp
|
88
|
+
assert_match('/page/tender', path)
|
89
|
+
assert_match('/page/love', path)
|
90
|
+
refute_match('/page/loving', path)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_optional_names
|
94
|
+
[
|
95
|
+
['/:foo(/:bar(/:baz))', %w{ bar baz }],
|
96
|
+
['/:foo(/:bar)', %w{ bar }],
|
97
|
+
['/:foo(/:bar)/:lol(/:baz)', %w{ bar baz }],
|
98
|
+
].each do |pattern, list|
|
99
|
+
path = Pattern.new pattern
|
100
|
+
assert_equal list.sort, path.optional_names.sort
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_to_regexp_with_group
|
105
|
+
strexp = Router::Strexp.new(
|
106
|
+
'/page/:name',
|
107
|
+
{ :name => /(tender|love)/ },
|
108
|
+
["/", ".", "?"]
|
109
|
+
)
|
110
|
+
path = Pattern.new strexp
|
111
|
+
assert_match('/page/tender', path)
|
112
|
+
assert_match('/page/love', path)
|
113
|
+
refute_match('/page/loving', path)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_ast_sets_regular_expressions
|
117
|
+
requirements = { :name => /(tender|love)/, :value => /./ }
|
118
|
+
strexp = Router::Strexp.new(
|
119
|
+
'/page/:name/:value',
|
120
|
+
requirements,
|
121
|
+
["/", ".", "?"]
|
122
|
+
)
|
123
|
+
|
124
|
+
assert_equal requirements, strexp.requirements
|
125
|
+
|
126
|
+
path = Pattern.new strexp
|
127
|
+
nodes = path.ast.grep(Nodes::Symbol)
|
128
|
+
assert_equal 2, nodes.length
|
129
|
+
nodes.each do |node|
|
130
|
+
assert_equal requirements[node.to_sym], node.regexp
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_match_data_with_group
|
135
|
+
strexp = Router::Strexp.new(
|
136
|
+
'/page/:name',
|
137
|
+
{ :name => /(tender|love)/ },
|
138
|
+
["/", ".", "?"]
|
139
|
+
)
|
140
|
+
path = Pattern.new strexp
|
141
|
+
match = path.match '/page/tender'
|
142
|
+
assert_equal 'tender', match[1]
|
143
|
+
assert_equal 2, match.length
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_match_data_with_multi_group
|
147
|
+
strexp = Router::Strexp.new(
|
148
|
+
'/page/:name/:id',
|
149
|
+
{ :name => /t(((ender|love)))()/ },
|
150
|
+
["/", ".", "?"]
|
151
|
+
)
|
152
|
+
path = Pattern.new strexp
|
153
|
+
match = path.match '/page/tender/10'
|
154
|
+
assert_equal 'tender', match[1]
|
155
|
+
assert_equal '10', match[2]
|
156
|
+
assert_equal 3, match.length
|
157
|
+
assert_equal %w{ tender 10 }, match.captures
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_insensitive_regexp_with_group
|
161
|
+
strexp = Router::Strexp.new(
|
162
|
+
'/page/:name/aaron',
|
163
|
+
{ :name => /(tender|love)/i },
|
164
|
+
["/", ".", "?"]
|
165
|
+
)
|
166
|
+
path = Pattern.new strexp
|
167
|
+
assert_match('/page/TENDER/aaron', path)
|
168
|
+
assert_match('/page/loVE/aaron', path)
|
169
|
+
refute_match('/page/loVE/AAron', path)
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_to_regexp_with_strexp
|
173
|
+
strexp = Router::Strexp.new('/:controller', { }, ["/", ".", "?"])
|
174
|
+
path = Pattern.new strexp
|
175
|
+
x = %r{\A/([^/.?]+)\Z}
|
176
|
+
|
177
|
+
assert_equal(x.source, path.source)
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_to_regexp_defaults
|
181
|
+
path = Pattern.new '/:controller(/:action(/:id))'
|
182
|
+
expected = %r{\A/([^/.?]+)(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z}
|
183
|
+
assert_equal expected, path.send(:to_regexp)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_failed_match
|
187
|
+
path = Pattern.new '/:controller(/:action(/:id(.:format)))'
|
188
|
+
uri = 'content'
|
189
|
+
|
190
|
+
refute path =~ uri
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_match_controller
|
194
|
+
path = Pattern.new '/:controller(/:action(/:id(.:format)))'
|
195
|
+
uri = '/content'
|
196
|
+
|
197
|
+
match = path =~ uri
|
198
|
+
assert_equal %w{ controller action id format }, match.names
|
199
|
+
assert_equal 'content', match[1]
|
200
|
+
assert_nil match[2]
|
201
|
+
assert_nil match[3]
|
202
|
+
assert_nil match[4]
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_match_controller_action
|
206
|
+
path = Pattern.new '/:controller(/:action(/:id(.:format)))'
|
207
|
+
uri = '/content/list'
|
208
|
+
|
209
|
+
match = path =~ uri
|
210
|
+
assert_equal %w{ controller action id format }, match.names
|
211
|
+
assert_equal 'content', match[1]
|
212
|
+
assert_equal 'list', match[2]
|
213
|
+
assert_nil match[3]
|
214
|
+
assert_nil match[4]
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_match_controller_action_id
|
218
|
+
path = Pattern.new '/:controller(/:action(/:id(.:format)))'
|
219
|
+
uri = '/content/list/10'
|
220
|
+
|
221
|
+
match = path =~ uri
|
222
|
+
assert_equal %w{ controller action id format }, match.names
|
223
|
+
assert_equal 'content', match[1]
|
224
|
+
assert_equal 'list', match[2]
|
225
|
+
assert_equal '10', match[3]
|
226
|
+
assert_nil match[4]
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_match_literal
|
230
|
+
path = Path::Pattern.new "/books(/:action(.:format))"
|
231
|
+
|
232
|
+
uri = '/books'
|
233
|
+
match = path =~ uri
|
234
|
+
assert_equal %w{ action format }, match.names
|
235
|
+
assert_nil match[1]
|
236
|
+
assert_nil match[2]
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_match_literal_with_action
|
240
|
+
path = Path::Pattern.new "/books(/:action(.:format))"
|
241
|
+
|
242
|
+
uri = '/books/list'
|
243
|
+
match = path =~ uri
|
244
|
+
assert_equal %w{ action format }, match.names
|
245
|
+
assert_equal 'list', match[1]
|
246
|
+
assert_nil match[2]
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_match_literal_with_action_and_format
|
250
|
+
path = Path::Pattern.new "/books(/:action(.:format))"
|
251
|
+
|
252
|
+
uri = '/books/list.rss'
|
253
|
+
match = path =~ uri
|
254
|
+
assert_equal %w{ action format }, match.names
|
255
|
+
assert_equal 'list', match[1]
|
256
|
+
assert_equal 'rss', match[2]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
module Definition
|
5
|
+
class TestParser < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@parser = Parser.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_slash
|
11
|
+
assert_equal :SLASH, @parser.parse('/').type
|
12
|
+
assert_round_trip '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_segment
|
16
|
+
assert_round_trip '/foo'
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_segments
|
20
|
+
assert_round_trip '/foo/bar'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_segment_symbol
|
24
|
+
assert_round_trip '/foo/:id'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_symbol
|
28
|
+
assert_round_trip '/:foo'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_group
|
32
|
+
assert_round_trip '(/:foo)'
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_groups
|
36
|
+
assert_round_trip '(/:foo)(/:bar)'
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_nested_groups
|
40
|
+
assert_round_trip '(/:foo(/:bar))'
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_dot_symbol
|
44
|
+
assert_round_trip('.:format')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_dot_literal
|
48
|
+
assert_round_trip('.xml')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_segment_dot
|
52
|
+
assert_round_trip('/foo.:bar')
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_segment_group_dot
|
56
|
+
assert_round_trip('/foo(.:bar)')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_segment_group
|
60
|
+
assert_round_trip('/foo(/:action)')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_segment_groups
|
64
|
+
assert_round_trip('/foo(/:action)(/:bar)')
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_segment_nested_groups
|
68
|
+
assert_round_trip('/foo(/:action(/:bar))')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_group_followed_by_path
|
72
|
+
assert_round_trip('/foo(/:action)/:bar')
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_star
|
76
|
+
assert_round_trip('*foo')
|
77
|
+
assert_round_trip('/*foo')
|
78
|
+
assert_round_trip('/bar/*foo')
|
79
|
+
assert_round_trip('/bar/(*foo)')
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_or
|
83
|
+
assert_round_trip('a|b')
|
84
|
+
assert_round_trip('a|b|c')
|
85
|
+
assert_round_trip('(a|b)|c')
|
86
|
+
assert_round_trip('a|(b|c)')
|
87
|
+
assert_round_trip('*a|(b|c)')
|
88
|
+
assert_round_trip('*a|:b|c')
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_arbitrary
|
92
|
+
assert_round_trip('/bar/*foo#')
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_literal_dot_paren
|
96
|
+
assert_round_trip "/sprockets.js(.:format)"
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_groups_with_dot
|
100
|
+
assert_round_trip "/(:locale)(.:format)"
|
101
|
+
end
|
102
|
+
|
103
|
+
def assert_round_trip str
|
104
|
+
assert_equal str, @parser.parse(str).to_s
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
module Definition
|
5
|
+
class TestScanner < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@scanner = Scanner.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# /page/:id(/:action)(.:format)
|
11
|
+
def test_tokens
|
12
|
+
[
|
13
|
+
['/', [[:SLASH, '/']]],
|
14
|
+
['*omg', [[:STAR, '*'], [:LITERAL, 'omg']]],
|
15
|
+
['/page', [[:SLASH, '/'], [:LITERAL, 'page']]],
|
16
|
+
['/:page', [[:SLASH, '/'], [:SYMBOL, ':page']]],
|
17
|
+
['/(:page)', [
|
18
|
+
[:SLASH, '/'],
|
19
|
+
[:LPAREN, '('],
|
20
|
+
[:SYMBOL, ':page'],
|
21
|
+
[:RPAREN, ')'],
|
22
|
+
]],
|
23
|
+
['(/:action)', [
|
24
|
+
[:LPAREN, '('],
|
25
|
+
[:SLASH, '/'],
|
26
|
+
[:SYMBOL, ':action'],
|
27
|
+
[:RPAREN, ')'],
|
28
|
+
]],
|
29
|
+
['(())', [[:LPAREN, '('],
|
30
|
+
[:LPAREN, '('], [:RPAREN, ')'], [:RPAREN, ')']]],
|
31
|
+
['(.:format)', [
|
32
|
+
[:LPAREN, '('],
|
33
|
+
[:DOT, '.'],
|
34
|
+
[:SYMBOL, ':format'],
|
35
|
+
[:RPAREN, ')'],
|
36
|
+
]],
|
37
|
+
].each do |str, expected|
|
38
|
+
@scanner.scan_setup str
|
39
|
+
assert_tokens expected, @scanner
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def assert_tokens tokens, scanner
|
44
|
+
toks = []
|
45
|
+
while tok = scanner.next_token
|
46
|
+
toks << tok
|
47
|
+
end
|
48
|
+
assert_equal tokens, toks
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
class Router
|
5
|
+
class TestStrexp < MiniTest::Unit::TestCase
|
6
|
+
def test_many_names
|
7
|
+
exp = Strexp.new(
|
8
|
+
"/:controller(/:action(/:id(.:format)))",
|
9
|
+
{:controller=>/.+?/},
|
10
|
+
["/", ".", "?"],
|
11
|
+
true)
|
12
|
+
|
13
|
+
assert_equal ["controller", "action", "id", "format"], exp.names
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_names
|
17
|
+
{
|
18
|
+
"/bar(.:format)" => %w{ format },
|
19
|
+
":format" => %w{ format },
|
20
|
+
":format-" => %w{ format },
|
21
|
+
":format0" => %w{ format0 },
|
22
|
+
":format1,:format2" => %w{ format1 format2 },
|
23
|
+
}.each do |string, expected|
|
24
|
+
exp = Strexp.new(string, {}, ["/", ".", "?"])
|
25
|
+
assert_equal expected, exp.names
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
class Router
|
5
|
+
class TestUtils < MiniTest::Unit::TestCase
|
6
|
+
def test_path_escape
|
7
|
+
assert_equal "a/b%20c+d", Utils.escape_path("a/b c+d")
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_fragment_escape
|
11
|
+
assert_equal "a/b%20c+d?e", Utils.escape_fragment("a/b c+d?e")
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_uri_unescape
|
15
|
+
assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/test/test_route.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Journey
|
4
|
+
class TestRoute < MiniTest::Unit::TestCase
|
5
|
+
def test_initialize
|
6
|
+
app = Object.new
|
7
|
+
path = Path::Pattern.new '/:controller(/:action(/:id(.:format)))'
|
8
|
+
defaults = Object.new
|
9
|
+
route = Route.new("name", app, path, {}, defaults)
|
10
|
+
|
11
|
+
assert_equal app, route.app
|
12
|
+
assert_equal path, route.path
|
13
|
+
assert_equal defaults, route.defaults
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_route_adds_itself_as_memo
|
17
|
+
app = Object.new
|
18
|
+
path = Path::Pattern.new '/:controller(/:action(/:id(.:format)))'
|
19
|
+
defaults = Object.new
|
20
|
+
route = Route.new("name", app, path, {}, defaults)
|
21
|
+
|
22
|
+
route.ast.grep(Nodes::Terminal).each do |node|
|
23
|
+
assert_equal route, node.memo
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_ip_address
|
28
|
+
path = Path::Pattern.new '/messages/:id(.:format)'
|
29
|
+
route = Route.new("name", nil, path, {:ip => '192.168.1.1'},
|
30
|
+
{ :controller => 'foo', :action => 'bar' })
|
31
|
+
assert_equal '192.168.1.1', route.ip
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_default_ip
|
35
|
+
path = Path::Pattern.new '/messages/:id(.:format)'
|
36
|
+
route = Route.new("name", nil, path, {},
|
37
|
+
{ :controller => 'foo', :action => 'bar' })
|
38
|
+
assert_equal(//, route.ip)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_format_empty
|
42
|
+
path = Path::Pattern.new '/messages/:id(.:format)'
|
43
|
+
route = Route.new("name", nil, path, {},
|
44
|
+
{ :controller => 'foo', :action => 'bar' })
|
45
|
+
|
46
|
+
assert_equal '/messages', route.format({})
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_format_with_star
|
50
|
+
path = Path::Pattern.new '/:controller/*extra'
|
51
|
+
route = Route.new("name", nil, path, {},
|
52
|
+
{ :controller => 'foo', :action => 'bar' })
|
53
|
+
assert_equal '/foo/himom', route.format({
|
54
|
+
:controller => 'foo',
|
55
|
+
:extra => 'himom',
|
56
|
+
})
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_connects_all_match
|
60
|
+
path = Path::Pattern.new '/:controller(/:action(/:id(.:format)))'
|
61
|
+
route = Route.new("name", nil, path, {:action => 'bar'}, { :controller => 'foo' })
|
62
|
+
|
63
|
+
assert_equal '/foo/bar/10', route.format({
|
64
|
+
:controller => 'foo',
|
65
|
+
:action => 'bar',
|
66
|
+
:id => 10
|
67
|
+
})
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_extras_are_not_included_if_optional
|
71
|
+
path = Path::Pattern.new '/page/:id(/:action)'
|
72
|
+
route = Route.new("name", nil, path, { }, { :action => 'show' })
|
73
|
+
|
74
|
+
assert_equal '/page/10', route.format({ :id => 10 })
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_score
|
78
|
+
path = Path::Pattern.new "/page/:id(/:action)(.:format)"
|
79
|
+
specific = Route.new "name", nil, path, {}, {:controller=>"pages", :action=>"show"}
|
80
|
+
|
81
|
+
path = Path::Pattern.new "/:controller(/:action(/:id))(.:format)"
|
82
|
+
generic = Route.new "name", nil, path, {}
|
83
|
+
|
84
|
+
knowledge = {:id=>20, :controller=>"pages", :action=>"show"}
|
85
|
+
|
86
|
+
routes = [specific, generic]
|
87
|
+
|
88
|
+
refute_equal specific.score(knowledge), generic.score(knowledge)
|
89
|
+
|
90
|
+
found = routes.sort_by { |r| r.score(knowledge) }.last
|
91
|
+
|
92
|
+
assert_equal specific, found
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|