andyjeffries-journey 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.autotest +8 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +6 -0
  4. data/Gemfile +11 -0
  5. data/Manifest.txt +49 -0
  6. data/README.rdoc +48 -0
  7. data/Rakefile +31 -0
  8. data/journey.gemspec +42 -0
  9. data/lib/journey/backwards.rb +5 -0
  10. data/lib/journey/core-ext/hash.rb +11 -0
  11. data/lib/journey/formatter.rb +129 -0
  12. data/lib/journey/gtg/builder.rb +159 -0
  13. data/lib/journey/gtg/simulator.rb +44 -0
  14. data/lib/journey/gtg/transition_table.rb +152 -0
  15. data/lib/journey/nfa/builder.rb +74 -0
  16. data/lib/journey/nfa/dot.rb +34 -0
  17. data/lib/journey/nfa/simulator.rb +45 -0
  18. data/lib/journey/nfa/transition_table.rb +164 -0
  19. data/lib/journey/nodes/node.rb +104 -0
  20. data/lib/journey/parser.rb +204 -0
  21. data/lib/journey/parser.y +47 -0
  22. data/lib/journey/parser_extras.rb +21 -0
  23. data/lib/journey/path/pattern.rb +190 -0
  24. data/lib/journey/route.rb +92 -0
  25. data/lib/journey/router/strexp.rb +22 -0
  26. data/lib/journey/router/utils.rb +57 -0
  27. data/lib/journey/router.rb +138 -0
  28. data/lib/journey/routes.rb +74 -0
  29. data/lib/journey/scanner.rb +58 -0
  30. data/lib/journey/visitors.rb +186 -0
  31. data/lib/journey/visualizer/d3.min.js +2 -0
  32. data/lib/journey/visualizer/fsm.css +34 -0
  33. data/lib/journey/visualizer/fsm.js +134 -0
  34. data/lib/journey/visualizer/index.html.erb +50 -0
  35. data/lib/journey/visualizer/reset.css +48 -0
  36. data/lib/journey.rb +5 -0
  37. data/test/gtg/test_builder.rb +77 -0
  38. data/test/gtg/test_transition_table.rb +113 -0
  39. data/test/helper.rb +4 -0
  40. data/test/nfa/test_simulator.rb +96 -0
  41. data/test/nfa/test_transition_table.rb +70 -0
  42. data/test/nodes/test_symbol.rb +15 -0
  43. data/test/path/test_pattern.rb +260 -0
  44. data/test/route/definition/test_parser.rb +108 -0
  45. data/test/route/definition/test_scanner.rb +52 -0
  46. data/test/router/test_strexp.rb +30 -0
  47. data/test/router/test_utils.rb +19 -0
  48. data/test/test_route.rb +95 -0
  49. data/test/test_router.rb +464 -0
  50. data/test/test_routes.rb +38 -0
  51. metadata +171 -0
@@ -0,0 +1,464 @@
1
+ require 'helper'
2
+
3
+ module Journey
4
+ class TestRouter < MiniTest::Unit::TestCase
5
+ attr_reader :routes
6
+
7
+ def setup
8
+ @routes = Routes.new
9
+ @router = Router.new(@routes, {})
10
+ @formatter = Formatter.new(@routes)
11
+ end
12
+
13
+ def test_request_class_reader
14
+ klass = Object.new
15
+ router = Router.new(routes, :request_class => klass)
16
+ assert_equal klass, router.request_class
17
+ end
18
+
19
+ class FakeRequestFeeler < Struct.new(:env, :called)
20
+ def new env
21
+ self.env = env
22
+ self
23
+ end
24
+
25
+ def hello
26
+ self.called = true
27
+ 'world'
28
+ end
29
+ end
30
+
31
+ def test_dashes
32
+ klass = FakeRequestFeeler.new nil
33
+ router = Router.new(routes, {})
34
+
35
+ exp = Router::Strexp.new '/foo-bar-baz', {}, ['/.?']
36
+ path = Path::Pattern.new exp
37
+
38
+ routes.add_route nil, path, {}, {:id => nil}, {}
39
+
40
+ env = rails_env 'PATH_INFO' => '/foo-bar-baz'
41
+ called = false
42
+ router.recognize(env) do |r, _, params|
43
+ called = true
44
+ end
45
+ assert called
46
+ end
47
+
48
+ def test_request_class_and_requirements_success
49
+ klass = FakeRequestFeeler.new nil
50
+ router = Router.new(routes, {:request_class => klass })
51
+
52
+ requirements = { :hello => /world/ }
53
+
54
+ exp = Router::Strexp.new '/foo(/:id)', {}, ['/.?']
55
+ path = Path::Pattern.new exp
56
+
57
+ routes.add_route nil, path, requirements, {:id => nil}, {}
58
+
59
+ env = rails_env 'PATH_INFO' => '/foo/10'
60
+ router.recognize(env) do |r, _, params|
61
+ assert_equal({:id => '10'}, params)
62
+ end
63
+
64
+ assert klass.called, 'hello should have been called'
65
+ assert_equal env.env, klass.env
66
+ end
67
+
68
+ def test_request_class_and_requirements_fail
69
+ klass = FakeRequestFeeler.new nil
70
+ router = Router.new(routes, {:request_class => klass })
71
+
72
+ requirements = { :hello => /mom/ }
73
+
74
+ exp = Router::Strexp.new '/foo(/:id)', {}, ['/.?']
75
+ path = Path::Pattern.new exp
76
+
77
+ router.routes.add_route nil, path, requirements, {:id => nil}, {}
78
+
79
+ env = rails_env 'PATH_INFO' => '/foo/10'
80
+ router.recognize(env) do |r, _, params|
81
+ flunk 'route should not be found'
82
+ end
83
+
84
+ assert klass.called, 'hello should have been called'
85
+ assert_equal env.env, klass.env
86
+ end
87
+
88
+ def test_required_parts_verified_are_anchored
89
+ add_routes @router, [
90
+ Router::Strexp.new("/foo/:id", { :id => /\d/ }, ['/', '.', '?'], false)
91
+ ]
92
+
93
+ assert_raises(Router::RoutingError) do
94
+ @formatter.generate(:path_info, nil, { :id => '10' }, { })
95
+ end
96
+ end
97
+
98
+ def test_required_parts_are_verified_when_building
99
+ add_routes @router, [
100
+ Router::Strexp.new("/foo/:id", { :id => /\d+/ }, ['/', '.', '?'], false)
101
+ ]
102
+
103
+ path, _ = @formatter.generate(:path_info, nil, { :id => '10' }, { })
104
+ assert_equal '/foo/10', path
105
+
106
+ assert_raises(Router::RoutingError) do
107
+ @formatter.generate(:path_info, nil, { :id => 'aa' }, { })
108
+ end
109
+ end
110
+
111
+ def test_only_required_parts_are_verified
112
+ add_routes @router, [
113
+ Router::Strexp.new("/foo(/:id)", {:id => /\d/}, ['/', '.', '?'], false)
114
+ ]
115
+
116
+ path, _ = @formatter.generate(:path_info, nil, { :id => '10' }, { })
117
+ assert_equal '/foo/10', path
118
+
119
+ path, _ = @formatter.generate(:path_info, nil, { }, { })
120
+ assert_equal '/foo', path
121
+
122
+ path, _ = @formatter.generate(:path_info, nil, { :id => 'aa' }, { })
123
+ assert_equal '/foo/aa', path
124
+ end
125
+
126
+ def test_X_Cascade
127
+ add_routes @router, [ "/messages(.:format)" ]
128
+ resp = @router.call({ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/lol' })
129
+ assert_equal ['Not Found'], resp.last
130
+ assert_equal 'pass', resp[1]['X-Cascade']
131
+ assert_equal 404, resp.first
132
+ end
133
+
134
+ def test_defaults_merge_correctly
135
+ path = Path::Pattern.new '/foo(/:id)'
136
+ @router.routes.add_route nil, path, {}, {:id => nil}, {}
137
+
138
+ env = rails_env 'PATH_INFO' => '/foo/10'
139
+ @router.recognize(env) do |r, _, params|
140
+ assert_equal({:id => '10'}, params)
141
+ end
142
+
143
+ env = rails_env 'PATH_INFO' => '/foo'
144
+ @router.recognize(env) do |r, _, params|
145
+ assert_equal({:id => nil}, params)
146
+ end
147
+ end
148
+
149
+ def test_recognize_with_unbound_regexp
150
+ add_routes @router, [
151
+ Router::Strexp.new("/foo", { }, ['/', '.', '?'], false)
152
+ ]
153
+
154
+ env = rails_env 'PATH_INFO' => '/foo/bar'
155
+
156
+ @router.recognize(env) { |*_| }
157
+
158
+ assert_equal '/foo', env.env['SCRIPT_NAME']
159
+ assert_equal '/bar', env.env['PATH_INFO']
160
+ end
161
+
162
+ def test_bound_regexp_keeps_path_info
163
+ add_routes @router, [
164
+ Router::Strexp.new("/foo", { }, ['/', '.', '?'], true)
165
+ ]
166
+
167
+ env = rails_env 'PATH_INFO' => '/foo'
168
+
169
+ before = env.env['SCRIPT_NAME']
170
+
171
+ @router.recognize(env) { |*_| }
172
+
173
+ assert_equal before, env.env['SCRIPT_NAME']
174
+ assert_equal '/foo', env.env['PATH_INFO']
175
+ end
176
+
177
+ def test_path_not_found
178
+ add_routes @router, [
179
+ "/messages(.:format)",
180
+ "/messages/new(.:format)",
181
+ "/messages/:id/edit(.:format)",
182
+ "/messages/:id(.:format)"
183
+ ]
184
+ env = rails_env 'PATH_INFO' => '/messages/1.1.1'
185
+ yielded = false
186
+
187
+ @router.recognize(env) do |*whatever|
188
+ yielded = false
189
+ end
190
+ refute yielded
191
+ end
192
+
193
+ def test_required_part_in_recall
194
+ add_routes @router, [ "/messages/:a/:b" ]
195
+
196
+ path, _ = @formatter.generate(:path_info, nil, { :a => 'a' }, { :b => 'b' })
197
+ assert_equal "/messages/a/b", path
198
+ end
199
+
200
+ def test_splat_in_recall
201
+ add_routes @router, [ "/*path" ]
202
+
203
+ path, _ = @formatter.generate(:path_info, nil, { }, { :path => 'b' })
204
+ assert_equal "/b", path
205
+ end
206
+
207
+ def test_recall_should_be_used_when_scoring
208
+ add_routes @router, [
209
+ "/messages/:action(/:id(.:format))",
210
+ "/messages/:id(.:format)"
211
+ ]
212
+
213
+ path, _ = @formatter.generate(:path_info, nil, { :id => 10 }, { :action => 'index' })
214
+ assert_equal "/messages/index/10", path
215
+ end
216
+
217
+ def add_routes router, paths
218
+ paths.each do |path|
219
+ path = Path::Pattern.new path
220
+ router.routes.add_route nil, path, {}, {}, {}
221
+ end
222
+ end
223
+
224
+ def test_nil_path_parts_are_ignored
225
+ path = Path::Pattern.new "/:controller(/:action(.:format))"
226
+ @router.routes.add_route nil, path, {}, {}, {}
227
+
228
+ params = { :controller => "tasks", :format => nil }
229
+ extras = { :action => 'lol' }
230
+
231
+ path, _ = @formatter.generate(:path_info, nil, params, extras)
232
+ assert_equal '/tasks', path
233
+ end
234
+
235
+ def test_generate_slash
236
+ path = Path::Pattern.new '/'
237
+ @router.routes.add_route nil, path, {}, {}, {}
238
+
239
+ params = [ [:controller, "tasks"],
240
+ [:action, "show"] ]
241
+
242
+ path, _ = @formatter.generate(:path_info, nil, Hash[params], {})
243
+ assert_equal '/', path
244
+ end
245
+
246
+ def test_generate_calls_param_proc
247
+ path = Path::Pattern.new '/:controller(/:action)'
248
+ @router.routes.add_route nil, path, {}, {}, {}
249
+
250
+ parameterized = []
251
+ params = [ [:controller, "tasks"],
252
+ [:action, "show"] ]
253
+
254
+ @formatter.generate(
255
+ :path_info,
256
+ nil,
257
+ Hash[params],
258
+ {},
259
+ lambda { |k,v| parameterized << [k,v]; v })
260
+
261
+ assert_equal params.map(&:to_s).sort, parameterized.map(&:to_s).sort
262
+ end
263
+
264
+ def test_generate_id
265
+ path = Path::Pattern.new '/:controller(/:action)'
266
+ @router.routes.add_route nil, path, {}, {}, {}
267
+
268
+ path, params = @formatter.generate(
269
+ :path_info, nil, {:id=>1, :controller=>"tasks", :action=>"show"}, {})
270
+ assert_equal '/tasks/show', path
271
+ assert_equal({:id => 1}, params)
272
+ end
273
+
274
+ def test_generate_escapes
275
+ path = Path::Pattern.new '/:controller(/:action)'
276
+ @router.routes.add_route nil, path, {}, {}, {}
277
+
278
+ path, _ = @formatter.generate(:path_info,
279
+ nil, { :controller => "tasks",
280
+ :action => "a/b c+d",
281
+ }, {})
282
+ assert_equal '/tasks/a/b%20c+d', path
283
+ end
284
+
285
+ def test_generate_extra_params
286
+ path = Path::Pattern.new '/:controller(/:action)'
287
+ @router.routes.add_route nil, path, {}, {}, {}
288
+
289
+ path, params = @formatter.generate(:path_info,
290
+ nil, { :id => 1,
291
+ :controller => "tasks",
292
+ :action => "show",
293
+ :relative_url_root => nil
294
+ }, {})
295
+ assert_equal '/tasks/show', path
296
+ assert_equal({:id => 1, :relative_url_root => nil}, params)
297
+ end
298
+
299
+ def test_generate_uses_recall_if_needed
300
+ path = Path::Pattern.new '/:controller(/:action(/:id))'
301
+ @router.routes.add_route nil, path, {}, {}, {}
302
+
303
+ path, params = @formatter.generate(:path_info,
304
+ nil,
305
+ {:controller =>"tasks", :id => 10},
306
+ {:action =>"index"})
307
+ assert_equal '/tasks/index/10', path
308
+ assert_equal({}, params)
309
+ end
310
+
311
+ def test_generate_with_name
312
+ path = Path::Pattern.new '/:controller(/:action)'
313
+ @router.routes.add_route nil, path, {}, {}, {}
314
+
315
+ path, params = @formatter.generate(:path_info,
316
+ "tasks",
317
+ {:controller=>"tasks"},
318
+ {:controller=>"tasks", :action=>"index"})
319
+ assert_equal '/tasks', path
320
+ assert_equal({}, params)
321
+ end
322
+
323
+ {
324
+ '/content' => { :controller => 'content' },
325
+ '/content/list' => { :controller => 'content', :action => 'list' },
326
+ '/content/show/10' => { :controller => 'content', :action => 'show', :id => "10" },
327
+ }.each do |request_path, expected|
328
+ define_method("test_recognize_#{expected.keys.map(&:to_s).join('_')}") do
329
+ path = Path::Pattern.new "/:controller(/:action(/:id))"
330
+ app = Object.new
331
+ route = @router.routes.add_route(app, path, {}, {}, {})
332
+
333
+ env = rails_env 'PATH_INFO' => request_path
334
+ called = false
335
+
336
+ @router.recognize(env) do |r, _, params|
337
+ assert_equal route, r
338
+ assert_equal(expected, params)
339
+ called = true
340
+ end
341
+
342
+ assert called
343
+ end
344
+ end
345
+
346
+ {
347
+ :segment => ['/a%2Fb%20c+d/splat', { :segment => 'a/b c+d', :splat => 'splat' }],
348
+ :splat => ['/segment/a/b%20c+d', { :segment => 'segment', :splat => 'a/b c+d' }]
349
+ }.each do |name, (request_path, expected)|
350
+ define_method("test_recognize_#{name}") do
351
+ path = Path::Pattern.new '/:segment/*splat'
352
+ app = Object.new
353
+ route = @router.routes.add_route(app, path, {}, {}, {})
354
+
355
+ env = rails_env 'PATH_INFO' => request_path
356
+ called = false
357
+
358
+ @router.recognize(env) do |r, _, params|
359
+ assert_equal route, r
360
+ assert_equal(expected, params)
361
+ called = true
362
+ end
363
+
364
+ assert called
365
+ end
366
+ end
367
+
368
+ def test_namespaced_controller
369
+ strexp = Router::Strexp.new(
370
+ "/:controller(/:action(/:id))",
371
+ { :controller => /.+?/ },
372
+ ["/", ".", "?"]
373
+ )
374
+ path = Path::Pattern.new strexp
375
+ app = Object.new
376
+ route = @router.routes.add_route(app, path, {}, {}, {})
377
+
378
+ env = rails_env 'PATH_INFO' => '/admin/users/show/10'
379
+ called = false
380
+ expected = {
381
+ :controller => 'admin/users',
382
+ :action => 'show',
383
+ :id => '10'
384
+ }
385
+
386
+ @router.recognize(env) do |r, _, params|
387
+ assert_equal route, r
388
+ assert_equal(expected, params)
389
+ called = true
390
+ end
391
+ assert called
392
+ end
393
+
394
+ def test_recognize_literal
395
+ path = Path::Pattern.new "/books(/:action(.:format))"
396
+ app = Object.new
397
+ route = @router.routes.add_route(app, path, {}, {:controller => 'books'})
398
+
399
+ env = rails_env 'PATH_INFO' => '/books/list.rss'
400
+ expected = { :controller => 'books', :action => 'list', :format => 'rss' }
401
+ called = false
402
+ @router.recognize(env) do |r, _, params|
403
+ assert_equal route, r
404
+ assert_equal(expected, params)
405
+ called = true
406
+ end
407
+
408
+ assert called
409
+ end
410
+
411
+ def test_recognize_cares_about_verbs
412
+ path = Path::Pattern.new "/books(/:action(.:format))"
413
+ app = Object.new
414
+ conditions = {
415
+ :request_method => 'GET'
416
+ }
417
+ @router.routes.add_route(app, path, conditions, {})
418
+
419
+ conditions = conditions.dup
420
+ conditions[:request_method] = 'POST'
421
+
422
+ post = @router.routes.add_route(app, path, conditions, {})
423
+
424
+ env = rails_env 'PATH_INFO' => '/books/list.rss',
425
+ "REQUEST_METHOD" => "POST"
426
+
427
+ called = false
428
+ @router.recognize(env) do |r, _, params|
429
+ assert_equal post, r
430
+ called = true
431
+ end
432
+
433
+ assert called
434
+ end
435
+
436
+ private
437
+
438
+ RailsEnv = Struct.new(:env)
439
+
440
+ def rails_env env
441
+ RailsEnv.new rack_env env
442
+ end
443
+
444
+ def rack_env env
445
+ {
446
+ "rack.version" => [1, 1],
447
+ "rack.input" => StringIO.new,
448
+ "rack.errors" => StringIO.new,
449
+ "rack.multithread" => true,
450
+ "rack.multiprocess" => true,
451
+ "rack.run_once" => false,
452
+ "REQUEST_METHOD" => "GET",
453
+ "SERVER_NAME" => "example.org",
454
+ "SERVER_PORT" => "80",
455
+ "QUERY_STRING" => "",
456
+ "PATH_INFO" => "/content",
457
+ "rack.url_scheme" => "http",
458
+ "HTTPS" => "off",
459
+ "SCRIPT_NAME" => "",
460
+ "CONTENT_LENGTH" => "0"
461
+ }.merge env
462
+ end
463
+ end
464
+ end
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+
3
+ module Journey
4
+ class TestRoutes < MiniTest::Unit::TestCase
5
+ def test_clear
6
+ routes = Routes.new
7
+ exp = Router::Strexp.new '/foo(/:id)', {}, ['/.?']
8
+ path = Path::Pattern.new exp
9
+ requirements = { :hello => /world/ }
10
+
11
+ routes.add_route nil, path, requirements, {:id => nil}, {}
12
+ assert_equal 1, routes.length
13
+
14
+ routes.clear
15
+ assert_equal 0, routes.length
16
+ end
17
+
18
+ def test_ast
19
+ routes = Routes.new
20
+ path = Path::Pattern.new '/hello'
21
+
22
+ routes.add_route nil, path, {}, {}, {}
23
+ ast = routes.ast
24
+ routes.add_route nil, path, {}, {}, {}
25
+ refute_equal ast, routes.ast
26
+ end
27
+
28
+ def test_simulator_changes
29
+ routes = Routes.new
30
+ path = Path::Pattern.new '/hello'
31
+
32
+ routes.add_route nil, path, {}, {}, {}
33
+ sim = routes.simulator
34
+ routes.add_route nil, path, {}, {}, {}
35
+ refute_equal sim, routes.simulator
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: andyjeffries-journey
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aaron Patterson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-23 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &70141541897200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70141541897200
25
+ - !ruby/object:Gem::Dependency
26
+ name: racc
27
+ requirement: &70141541896340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.6
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70141541896340
36
+ - !ruby/object:Gem::Dependency
37
+ name: json
38
+ requirement: &70141541895820 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70141541895820
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &70141541895120 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.10'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70141541895120
58
+ - !ruby/object:Gem::Dependency
59
+ name: hoe
60
+ requirement: &70141541894340 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '2.12'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70141541894340
69
+ description: Journey is a router. It routes requests.
70
+ email:
71
+ - aaron@tenderlovemaking.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files:
75
+ - Manifest.txt
76
+ - CHANGELOG.rdoc
77
+ - README.rdoc
78
+ files:
79
+ - .autotest
80
+ - CHANGELOG.rdoc
81
+ - Gemfile
82
+ - Manifest.txt
83
+ - README.rdoc
84
+ - Rakefile
85
+ - journey.gemspec
86
+ - lib/journey.rb
87
+ - lib/journey/backwards.rb
88
+ - lib/journey/core-ext/hash.rb
89
+ - lib/journey/formatter.rb
90
+ - lib/journey/gtg/builder.rb
91
+ - lib/journey/gtg/simulator.rb
92
+ - lib/journey/gtg/transition_table.rb
93
+ - lib/journey/nfa/builder.rb
94
+ - lib/journey/nfa/dot.rb
95
+ - lib/journey/nfa/simulator.rb
96
+ - lib/journey/nfa/transition_table.rb
97
+ - lib/journey/nodes/node.rb
98
+ - lib/journey/parser.rb
99
+ - lib/journey/parser.y
100
+ - lib/journey/parser_extras.rb
101
+ - lib/journey/path/pattern.rb
102
+ - lib/journey/route.rb
103
+ - lib/journey/router.rb
104
+ - lib/journey/router/strexp.rb
105
+ - lib/journey/router/utils.rb
106
+ - lib/journey/routes.rb
107
+ - lib/journey/scanner.rb
108
+ - lib/journey/visitors.rb
109
+ - lib/journey/visualizer/d3.min.js
110
+ - lib/journey/visualizer/fsm.css
111
+ - lib/journey/visualizer/fsm.js
112
+ - lib/journey/visualizer/index.html.erb
113
+ - lib/journey/visualizer/reset.css
114
+ - test/gtg/test_builder.rb
115
+ - test/gtg/test_transition_table.rb
116
+ - test/helper.rb
117
+ - test/nfa/test_simulator.rb
118
+ - test/nfa/test_transition_table.rb
119
+ - test/nodes/test_symbol.rb
120
+ - test/path/test_pattern.rb
121
+ - test/route/definition/test_parser.rb
122
+ - test/route/definition/test_scanner.rb
123
+ - test/router/test_strexp.rb
124
+ - test/router/test_utils.rb
125
+ - test/test_route.rb
126
+ - test/test_router.rb
127
+ - test/test_routes.rb
128
+ - .gemtest
129
+ homepage: http://github.com/tenderlove/journey
130
+ licenses: []
131
+ post_install_message:
132
+ rdoc_options:
133
+ - --main
134
+ - README.rdoc
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ segments:
144
+ - 0
145
+ hash: 3858943851392941251
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project: andyjeffries-journey
154
+ rubygems_version: 1.8.10
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Journey is a router
158
+ test_files:
159
+ - test/gtg/test_builder.rb
160
+ - test/gtg/test_transition_table.rb
161
+ - test/nfa/test_simulator.rb
162
+ - test/nfa/test_transition_table.rb
163
+ - test/nodes/test_symbol.rb
164
+ - test/path/test_pattern.rb
165
+ - test/route/definition/test_parser.rb
166
+ - test/route/definition/test_scanner.rb
167
+ - test/router/test_strexp.rb
168
+ - test/router/test_utils.rb
169
+ - test/test_route.rb
170
+ - test/test_router.rb
171
+ - test/test_routes.rb