joshbuddy-usher 0.0.2
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/History.txt +3 -0
- data/Manifest.txt +35 -0
- data/README.rdoc +63 -0
- data/Rakefile +27 -0
- data/lib/compat.rb +1 -0
- data/lib/usher.rb +135 -0
- data/lib/usher/exceptions.rb +4 -0
- data/lib/usher/grapher.rb +44 -0
- data/lib/usher/interface.rb +22 -0
- data/lib/usher/interface/merb_interface.rb +63 -0
- data/lib/usher/interface/rack_interface.rb +31 -0
- data/lib/usher/interface/rack_interface/mapper.rb +0 -0
- data/lib/usher/interface/rack_interface/route.rb +9 -0
- data/lib/usher/interface/rails2_interface.rb +133 -0
- data/lib/usher/interface/rails2_interface/mapper.rb +44 -0
- data/lib/usher/node.rb +149 -0
- data/lib/usher/node/lookup.rb +78 -0
- data/lib/usher/route.rb +33 -0
- data/lib/usher/route/http.rb +21 -0
- data/lib/usher/route/path.rb +20 -0
- data/lib/usher/route/separator.rb +21 -0
- data/lib/usher/route/splitter.rb +93 -0
- data/lib/usher/route/variable.rb +22 -0
- data/rails/init.rb +4 -0
- data/spec/generate_spec.rb +61 -0
- data/spec/node/lookup_spec.rb +53 -0
- data/spec/path_spec.rb +42 -0
- data/spec/rack/dispatch_spec.rb +36 -0
- data/spec/rails/generate_spec.rb +28 -0
- data/spec/rails/path_spec.rb +16 -0
- data/spec/rails/recognize_spec.rb +79 -0
- data/spec/recognize_spec.rb +66 -0
- data/spec/spec.opts +7 -0
- data/spec/split_spec.rb +37 -0
- data/usher.gemspec +32 -0
- metadata +98 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
class Usher
|
2
|
+
class Route
|
3
|
+
class Path
|
4
|
+
|
5
|
+
attr_reader :dynamic_parts, :dynamic_map, :dynamic_indicies, :route, :dynamic_set, :parts
|
6
|
+
|
7
|
+
def initialize(route, parts)
|
8
|
+
@route = route
|
9
|
+
@parts = parts
|
10
|
+
@dynamic_indicies = []
|
11
|
+
@parts.each_index{|i| @dynamic_indicies << i if @parts[i].is_a?(Variable)}
|
12
|
+
@dynamic_parts = @parts.values_at(*@dynamic_indicies)
|
13
|
+
@dynamic_map = {}
|
14
|
+
@dynamic_parts.each{|p| @dynamic_map[p.name] = p }
|
15
|
+
@dynamic_set = Set.new(@dynamic_map.keys)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Usher
|
2
|
+
class Route
|
3
|
+
|
4
|
+
class Separator
|
5
|
+
private
|
6
|
+
def initialize(sep)
|
7
|
+
@sep = sep
|
8
|
+
@sep_to_s = "#{sep}"
|
9
|
+
end
|
10
|
+
|
11
|
+
public
|
12
|
+
def to_s
|
13
|
+
@sep_to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
Dot = Separator.new(:'.')
|
17
|
+
Slash = Separator.new(:/)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class Usher
|
2
|
+
class Route
|
3
|
+
class Splitter
|
4
|
+
|
5
|
+
ScanRegex = /([:\*]?[0-9a-z_]+|\/|\.|\(|\))/
|
6
|
+
UrlScanRegex = /\/|\.|\w+/
|
7
|
+
|
8
|
+
attr_reader :paths
|
9
|
+
|
10
|
+
def initialize(path, requirements = {}, transformers = {})
|
11
|
+
@parts = Splitter.split(path, requirements, transformers)
|
12
|
+
@paths = calc_paths(@parts)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.url_split(path)
|
16
|
+
parts = path[0] == ?/ ? [] : [Separator::Slash]
|
17
|
+
ss = StringScanner.new(path)
|
18
|
+
while !ss.eos?
|
19
|
+
part = ss.scan(UrlScanRegex)
|
20
|
+
case part[0]
|
21
|
+
when ?.
|
22
|
+
parts << Separator::Dot
|
23
|
+
when ?/
|
24
|
+
parts << Separator::Slash
|
25
|
+
else
|
26
|
+
parts << part
|
27
|
+
end
|
28
|
+
end if path && !path.empty?
|
29
|
+
parts
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.split(path, requirements = {}, transformers = {})
|
33
|
+
parts = path[0] == ?/ ? [] : [Separator::Slash]
|
34
|
+
ss = StringScanner.new(path)
|
35
|
+
groups = [parts]
|
36
|
+
current_group = parts
|
37
|
+
while !ss.eos?
|
38
|
+
part = ss.scan(ScanRegex)
|
39
|
+
case part[0]
|
40
|
+
when ?*, ?:
|
41
|
+
type = part.slice!(0).chr.to_sym
|
42
|
+
current_group << Variable.new(type, part, :validator => requirements[part.to_sym], :transformer => transformers[part.to_sym])
|
43
|
+
when ?.
|
44
|
+
current_group << Separator::Dot
|
45
|
+
when ?/
|
46
|
+
current_group << Separator::Slash
|
47
|
+
when ?(
|
48
|
+
new_group = []
|
49
|
+
groups << new_group
|
50
|
+
current_group << new_group
|
51
|
+
current_group = new_group
|
52
|
+
when ?)
|
53
|
+
groups.pop
|
54
|
+
current_group = groups.last
|
55
|
+
else
|
56
|
+
current_group << part
|
57
|
+
end
|
58
|
+
end unless !path || path.empty?
|
59
|
+
parts
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def calc_paths(parts)
|
64
|
+
paths = []
|
65
|
+
optional_parts = []
|
66
|
+
parts.each_index {|i| optional_parts << i if parts[i].is_a?(Array)}
|
67
|
+
if optional_parts.size.zero?
|
68
|
+
[parts]
|
69
|
+
else
|
70
|
+
(0...(2 << (optional_parts.size - 1))).each do |i|
|
71
|
+
current_paths = [[]]
|
72
|
+
parts.each_index do |part_index|
|
73
|
+
part = parts[part_index]
|
74
|
+
if optional_parts.include?(part_index) && (2 << (optional_parts.index(part_index)-1) & i != 0)
|
75
|
+
new_sub_parts = calc_paths(part)
|
76
|
+
current_paths_size = current_paths.size
|
77
|
+
(new_sub_parts.size - 1).times {|i| current_paths << current_paths[i % current_paths_size].dup }
|
78
|
+
current_paths.each_index do |current_path_idx|
|
79
|
+
current_paths[current_path_idx].push(*new_sub_parts[current_path_idx % new_sub_parts.size])
|
80
|
+
end
|
81
|
+
elsif !optional_parts.include?(part_index)
|
82
|
+
current_paths.each { |current_path| current_path << part }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
paths.push(*current_paths)
|
86
|
+
end
|
87
|
+
paths
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Usher
|
2
|
+
class Route
|
3
|
+
class Variable
|
4
|
+
attr_reader :type, :name, :validator, :transformer
|
5
|
+
|
6
|
+
def initialize(type, name, opts = {})
|
7
|
+
@type = type
|
8
|
+
@name = :"#{name}"
|
9
|
+
@validator = opts[:validator]
|
10
|
+
@transformer = opts[:transformer]
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"#{type}#{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(o)
|
18
|
+
o && (o.type == @type && o.name == @name && o.validator == @validator)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
route_set = Usher.new
|
4
|
+
|
5
|
+
describe "Usher URL generation" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
route_set.reset!
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should generate a simple URL" do
|
12
|
+
route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'action')
|
13
|
+
route_set.generate_url(:sample, {}).should == '/sample'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate a simple URL with a single variable" do
|
17
|
+
route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
|
18
|
+
route_set.generate_url(:sample, {:action => 'action'}).should == '/sample/action'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should generate a simple URL with a single variable (thats not a string)" do
|
22
|
+
route_set.add_named_route(:sample, '/sample/:action/:id', :controller => 'sample')
|
23
|
+
route_set.generate_url(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should generate a simple URL with a glob variable" do
|
27
|
+
route_set.add_named_route(:sample, '/sample/*action', :controller => 'sample')
|
28
|
+
route_set.generate_url(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should generate a mutliple vairable URL from a hash" do
|
32
|
+
route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
33
|
+
route_set.generate_url(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should generate a mutliple vairable URL from an array" do
|
37
|
+
route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
38
|
+
route_set.generate_url(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should generate append extra hash variables to the end" do
|
42
|
+
route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
43
|
+
route_set.generate_url(:sample, {:first => 'maz', :second => 'zoo', :third => 'zanz'}).should == '/sample/maz/zoo?third=zanz'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should generate append extra hash variables to the end using [] syntax if its an array" do
|
47
|
+
route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
48
|
+
route_set.generate_url(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should generate a mutliple vairable URL from an array" do
|
52
|
+
route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
|
53
|
+
route_set.generate_url(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should generate a simple URL with a format" do
|
57
|
+
route_set.add_named_route(:sample, '/sample/:action.:format', :controller => 'sample')
|
58
|
+
route_set.generate_url(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
|
4
|
+
describe "String/regexp lookup table" do
|
5
|
+
|
6
|
+
it "should accept strings and retrieve based on them" do
|
7
|
+
l = Usher::Node::Lookup.new
|
8
|
+
l['asd'] = 'qwe'
|
9
|
+
l['asd'].should == 'qwe'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should accept regexs too" do
|
13
|
+
l = Usher::Node::Lookup.new
|
14
|
+
l[/asd.*/] = 'qwe'
|
15
|
+
l['asdqweasd'].should == 'qwe'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should prefer string to regex matches" do
|
19
|
+
l = Usher::Node::Lookup.new
|
20
|
+
l['asd'] = 'qwe2'
|
21
|
+
l[/asd.*/] = 'qwe'
|
22
|
+
l['asd'].should == 'qwe2'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow nil keys" do
|
26
|
+
l = Usher::Node::Lookup.new
|
27
|
+
l[nil] = 'qwe2'
|
28
|
+
l['asd'] = 'qwe'
|
29
|
+
l['asd'].should == 'qwe'
|
30
|
+
l[nil].should == 'qwe2'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to delete by value for hash" do
|
34
|
+
l = Usher::Node::Lookup.new
|
35
|
+
l[nil] = 'qwe2'
|
36
|
+
l['asd'] = 'qwe'
|
37
|
+
l['asd'].should == 'qwe'
|
38
|
+
l[nil].should == 'qwe2'
|
39
|
+
l.delete_value('qwe2')
|
40
|
+
l[nil].should == nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to delete by value for hash" do
|
44
|
+
l = Usher::Node::Lookup.new
|
45
|
+
l[/qwe.*/] = 'qwe2'
|
46
|
+
l['asd'] = 'qwe'
|
47
|
+
l['asd'].should == 'qwe'
|
48
|
+
l['qweasd'].should == 'qwe2'
|
49
|
+
l.delete_value('qwe2')
|
50
|
+
l['qweasd'].should == nil
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/spec/path_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
route_set = Usher.new
|
4
|
+
|
5
|
+
S = Usher::Route::Separator::Slash
|
6
|
+
D = Usher::Route::Separator::Dot
|
7
|
+
|
8
|
+
describe "Usher route adding" do
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
route_set.reset!
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be empty after a reset" do
|
15
|
+
route_set.add_route('/sample', :controller => 'sample')
|
16
|
+
route_set.empty?.should == false
|
17
|
+
route_set.reset!
|
18
|
+
route_set.empty?.should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "shouldn't care about routes without a controller" do
|
22
|
+
proc { route_set.add_route('/bad/route') }.should_not raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should add every kind of optional route possible" do
|
26
|
+
route_set.add_route('/a/b(/c)(/d(/e))')
|
27
|
+
route_set.routes.first.paths.collect{|a| a.parts }.should == [
|
28
|
+
[S, "a", S, "b"],
|
29
|
+
[S, "a", S, "b", S, "c"],
|
30
|
+
[S, "a", S, "b", S, "d"],
|
31
|
+
[S, "a", S, "b", S, "d", S, "e"],
|
32
|
+
[S, "a", S, "b", S, "c", S, "d"],
|
33
|
+
[S, "a", S, "b", S, "c", S, "d", S, "e"]
|
34
|
+
]
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow named routes to be added" do
|
39
|
+
route_set.add_named_route(:route, '/bad/route', :controller => 'sample').should == route_set.named_routes[:route]
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'lib/compat'
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rack)
|
5
|
+
|
6
|
+
def build_request_mock(path, method, params)
|
7
|
+
request = mock "Request"
|
8
|
+
request.should_receive(:path).any_number_of_times.and_return(path)
|
9
|
+
request.should_receive(:method).any_number_of_times.and_return(method)
|
10
|
+
params = params.with_indifferent_access
|
11
|
+
request.should_receive(:path_parameters=).any_number_of_times.with(params)
|
12
|
+
request.should_receive(:path_parameters).any_number_of_times.and_return(params)
|
13
|
+
request
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_app_mock(params)
|
17
|
+
request = mock "App"
|
18
|
+
request.should_receive(:call).any_number_of_times.with(params)
|
19
|
+
request
|
20
|
+
end
|
21
|
+
|
22
|
+
SampleController = Object.new
|
23
|
+
|
24
|
+
describe "Usher (for rack) route dispatching" do
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
route_set.reset!
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should dispatch a simple request" do
|
31
|
+
env = {'REQUEST_URI' => '/sample', 'REQUEST_METHOD' => 'get', 'usher.params' => {}}
|
32
|
+
route_set.add('/sample', :controller => 'sample', :action => 'action').to(build_app_mock(env.dup))
|
33
|
+
route_set.call(env)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'lib/compat'
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2)
|
5
|
+
|
6
|
+
describe "Usher (for rails) URL generation" do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
route_set.reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should fill in the controller from recall" do
|
13
|
+
route_set.add_route(':controller/:action/:id')
|
14
|
+
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should skip the action if not provided" do
|
18
|
+
route_set.add_route(':controller/:action/:id')
|
19
|
+
route_set.generate({:controller => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/thingy'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should pick the correct param from optional parts" do
|
23
|
+
route_set.add_route(':controller/:action(.:format)')
|
24
|
+
route_set.generate({:action => 'thingy', :format => 'html'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy.html'
|
25
|
+
route_set.generate({:action => 'thingy'}, {:controller => 'sample', :action => 'index', :id => 123}, :generate).should == '/sample/thingy'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'lib/compat'
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2)
|
5
|
+
|
6
|
+
describe "Usher (for rails) route adding" do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
route_set.reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
it "shouldn't allow routes without a controller to be added" do
|
13
|
+
proc { route_set.add_route('/bad/route') }.should raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'lib/compat'
|
2
|
+
require 'lib/usher'
|
3
|
+
require 'action_controller'
|
4
|
+
|
5
|
+
route_set = Usher::Interface.for(:rails2)
|
6
|
+
|
7
|
+
def build_request_mock(path, method, params)
|
8
|
+
request = mock "Request"
|
9
|
+
request.should_receive(:path).any_number_of_times.and_return(path)
|
10
|
+
request.should_receive(:method).any_number_of_times.and_return(method)
|
11
|
+
params = params.with_indifferent_access
|
12
|
+
request.should_receive(:path_parameters=).any_number_of_times.with(params)
|
13
|
+
request.should_receive(:path_parameters).any_number_of_times.and_return(params)
|
14
|
+
request
|
15
|
+
end
|
16
|
+
|
17
|
+
SampleController = Object.new
|
18
|
+
|
19
|
+
describe "Usher (for rails) route recognition" do
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
route_set.reset!
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should recognize a simple request" do
|
26
|
+
route_set.add_route('/sample', :controller => 'sample', :action => 'action')
|
27
|
+
route_set.recognize(build_request_mock('/sample', 'get', {:controller => 'sample', :action => 'action'})).should == SampleController
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should interpolate action :index" do
|
31
|
+
route_set.add_route('/sample', :controller => 'sample')
|
32
|
+
route_set.recognize(build_request_mock('/sample', 'get', {:controller => 'sample', :action => 'index'})).should == SampleController
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should correctly distinguish between multiple request methods" do
|
36
|
+
route_set.add_route('/sample', :controller => 'not_sample', :conditions => {:method => :get})
|
37
|
+
correct_route = route_set.add_route('/sample', :controller => 'sample', :conditions => {:method => :post})
|
38
|
+
route_set.add_route('/sample', :controller => 'not_sample', :conditions => {:method => :put})
|
39
|
+
route_set.recognize(build_request_mock('/sample', :post, {:controller => 'sample', :action => 'index'})).should == SampleController
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should prefer the static route to the dynamic route" do
|
43
|
+
route_set.add_route('/sample/:action', :controller => 'not_sample')
|
44
|
+
route_set.add_route('/sample/test', :controller => 'sample', :action => 'action')
|
45
|
+
route_set.recognize(build_request_mock('/sample/test', 'get', {:controller => 'sample', :action => 'action'})).should == SampleController
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should raise based upon an invalid param" do
|
49
|
+
route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample', :requirements => {:action => /\d+/})
|
50
|
+
proc { route_set.recognize(build_request_mock('/sample/asdqwe', :post, {})) }.should raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should raise based upon an invalid route" do
|
54
|
+
route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'test')
|
55
|
+
proc { route_set.recognize(build_request_mock('/test/asdqwe', :post, {})) }.should raise_error(ActionController::RoutingError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should add /:controller and /:controller/:action if /:controller/:action/:id is added" do
|
59
|
+
route_set.add_route('/:controller/:action/:id')
|
60
|
+
route_set.route_count.should == 3
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should correctly recognize a format (dynamic path path with . delimiter)" do
|
64
|
+
route_set.add_route('/:controller/:action/:id.:format')
|
65
|
+
route_set.recognize(build_request_mock('/sample/test/123.html', 'get', {:controller => 'sample', :action => 'test', :id => '123', :format => 'html'})).should == SampleController
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should support root nodes" do
|
69
|
+
route_set.add_route('/', :controller => 'sample')
|
70
|
+
route_set.recognize(build_request_mock('/', :get, {:controller => 'sample', :action => 'index'})).should == SampleController
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should default action to 'index' when controller (and not index) is specified" do
|
74
|
+
route_set.add_route('/:controller/:action')
|
75
|
+
route_set.recognize(build_request_mock('/sample', :get, {:controller => 'sample', :action => 'index'})).should == SampleController
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
end
|