andyjeffries-journey 1.0.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/.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
|