usher 0.4.8
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 +126 -0
- data/Rakefile +72 -0
- data/VERSION.yml +4 -0
- data/lib/usher/exceptions.rb +5 -0
- data/lib/usher/generate.rb +131 -0
- data/lib/usher/grapher.rb +65 -0
- data/lib/usher/interface/email_interface.rb +27 -0
- data/lib/usher/interface/merb_interface.rb +61 -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/rack_interface.rb +37 -0
- data/lib/usher/interface/rails2_2_interface/mapper.rb +44 -0
- data/lib/usher/interface/rails2_2_interface.rb +135 -0
- data/lib/usher/interface/rails2_3_interface.rb +135 -0
- data/lib/usher/interface.rb +27 -0
- data/lib/usher/node.rb +138 -0
- data/lib/usher/route/path.rb +24 -0
- data/lib/usher/route/request_method.rb +22 -0
- data/lib/usher/route/variable.rb +37 -0
- data/lib/usher/route.rb +58 -0
- data/lib/usher/splitter.rb +159 -0
- data/lib/usher.rb +184 -0
- data/rails/init.rb +8 -0
- data/spec/private/email/recognize_spec.rb +38 -0
- data/spec/private/generate_spec.rb +141 -0
- data/spec/private/grapher_spec.rb +41 -0
- data/spec/private/path_spec.rb +68 -0
- data/spec/private/rack/dispatch_spec.rb +29 -0
- data/spec/private/rails2_2/compat.rb +1 -0
- data/spec/private/rails2_2/generate_spec.rb +28 -0
- data/spec/private/rails2_2/path_spec.rb +16 -0
- data/spec/private/rails2_2/recognize_spec.rb +79 -0
- data/spec/private/rails2_3/compat.rb +1 -0
- data/spec/private/rails2_3/generate_spec.rb +28 -0
- data/spec/private/rails2_3/path_spec.rb +16 -0
- data/spec/private/rails2_3/recognize_spec.rb +79 -0
- data/spec/private/recognize_spec.rb +178 -0
- data/spec/private/request_method_spec.rb +15 -0
- data/spec/private/split_spec.rb +76 -0
- data/spec/spec.opts +7 -0
- metadata +120 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2_2)
|
5
|
+
|
6
|
+
describe "Usher (for rails 2.2) 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 File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2_2)
|
5
|
+
|
6
|
+
describe "Usher (for rails 2.2) 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 File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
require 'action_controller'
|
4
|
+
|
5
|
+
route_set = Usher::Interface.for(:rails2_2)
|
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 2.2) 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
|
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
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'activesupport'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2_3)
|
5
|
+
|
6
|
+
describe "Usher (for rails 2.3) 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 File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
|
4
|
+
route_set = Usher::Interface.for(:rails2_3)
|
5
|
+
|
6
|
+
describe "Usher (for rails 2.3) 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 File.join(File.dirname(__FILE__), 'compat')
|
2
|
+
require 'lib/usher'
|
3
|
+
require 'action_controller'
|
4
|
+
|
5
|
+
route_set = Usher::Interface.for(:rails2_3)
|
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 2.3) 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
|
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
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
route_set = Usher.new
|
4
|
+
|
5
|
+
def build_request(opts)
|
6
|
+
request = mock "Request"
|
7
|
+
opts.each do |k,v|
|
8
|
+
request.should_receive(k).any_number_of_times.and_return(v)
|
9
|
+
end
|
10
|
+
request
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "Usher route recognition" do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
route_set.reset!
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should recognize a specific domain name" do
|
20
|
+
target_route = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:protocol => 'http'})
|
21
|
+
route_set.add_route('/sample', :controller => 'sample', :action => 'action2', :conditions => {:protocol => 'https'})
|
22
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'http'})).path.route.should == target_route
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should recognize a regex domain name" do
|
26
|
+
target_route = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:domain => /^admin.*$/})
|
27
|
+
route_set.add_route('/sample', :controller => 'sample', :action => 'action2', :conditions => {:domain => 'www.host.com'})
|
28
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :domain => 'admin.host.com'})).path.route.should == target_route
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should recognize a format-style variable" do
|
32
|
+
target_route = route_set.add_route('/sample.:format', :controller => 'sample', :action => 'action')
|
33
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:format , 'html']])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should recognize a glob-style variable" do
|
37
|
+
target_route = route_set.add_route('/sample/*format', :controller => 'sample', :action => 'action')
|
38
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'})).params.should == [[:format, ['html', 'json', 'apple']]]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should recgonize only a glob-style variable" do
|
42
|
+
target_route = route_set.add_route('/*format')
|
43
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'}))
|
44
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
45
|
+
response.path.route.should == target_route
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should recgonize a regex static part" do
|
49
|
+
target_route = route_set.add_route('/test/part/{one|two}')
|
50
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/one'})).path.route.should == target_route
|
51
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/two'})).path.route.should == target_route
|
52
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/three'})).should == nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "shouldn't accept a nil variable" do
|
56
|
+
target_route = route_set.add_route('/:one')
|
57
|
+
route_set.recognize(build_request({:method => 'get', :path => '/one'})).path.route.should == target_route
|
58
|
+
route_set.recognize(build_request({:method => 'get', :path => '/'})).should == nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should recgonize a regex static part containing {}'s" do
|
62
|
+
target_route = route_set.add_route('/test/part/{^o{2,3}$}')
|
63
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oo'})).path.route.should == target_route
|
64
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/ooo'})).path.route.should == target_route
|
65
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oooo'})).should == nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should recgonize a regex single variable" do
|
69
|
+
target_route = route_set.add_route('/test/part/{:test,hello|again}')
|
70
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).path.route.should == target_route
|
71
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).params.should == [[:test, 'hello']]
|
72
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).path.route.should == target_route
|
73
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).params.should == [[:test, 'again']]
|
74
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/world'})).should == nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should recgonize a regex glob variable" do
|
78
|
+
target_route = route_set.add_route('/test/part/{*test,^(hello|again|\d+)$}')
|
79
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again'})).path.route.should == target_route
|
80
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again'})).params.should == [[:test, ['hello', 'again', '123', 'hello', 'again']]]
|
81
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/agaim/123/hello/again'})).should == nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should recgonize a regex glob variable terminated by a static part" do
|
85
|
+
target_route = route_set.add_route('/test/part/{*test,^(hello|again|\d+)$}/onemore')
|
86
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again/onemore'})).path.route.should == target_route
|
87
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again/onemore'})).params.should == [[:test, ['hello', 'again', '123', 'hello', 'again']]]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should recgonize a regex glob variable terminated by a single regex variable" do
|
91
|
+
target_route = route_set.add_route('/test/part/{*test,^(hello|again|\d+)$}/{:party,onemore}')
|
92
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again/onemore'})).path.route.should == target_route
|
93
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello/again/123/hello/again/onemore'})).params.should == [[:test, ['hello', 'again', '123', 'hello', 'again']], [:party, 'onemore']]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should recgonize two glob-style variables separated by a static part" do
|
97
|
+
target_route = route_set.add_route('/*format/innovate/*onemore')
|
98
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/innovate/apple'}))
|
99
|
+
response.params.should == [[:format, ['sample', 'html']], [:onemore, ['apple']]]
|
100
|
+
response.path.route.should == target_route
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should recgonize only a glob-style variable with a condition" do
|
104
|
+
target_route = route_set.add_route('/*format', :conditions => {:domain => 'test-domain'})
|
105
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple', :domain => 'test-domain'}))
|
106
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
107
|
+
response.path.route.should == target_route
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should recognize a format-style literal" do
|
111
|
+
target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
|
112
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:action , 'sample']])
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should recognize a format-style variable along side another variable" do
|
116
|
+
target_route = route_set.add_route('/:action.:format', :controller => 'sample', :action => 'action')
|
117
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:action , 'sample'], [:format, 'html']])
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should recognize a specific route when several http-style restrictions are used" do
|
121
|
+
target_route_http_admin = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:protocol => 'http', :domain => 'admin.spec.com'})
|
122
|
+
target_route_http_www = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:protocol => 'http', :domain => 'www.spec.com'})
|
123
|
+
target_route_https_msie = route_set.add_route('/sample', :controller => 'sample', :action => 'action2', :conditions => {:protocol => 'https', :user_agent => 'MSIE 6.0'})
|
124
|
+
target_route_https_admin = route_set.add_route('/sample', :controller => 'sample', :action => 'action2', :conditions => {:protocol => 'https', :domain => 'admin.spec.com'})
|
125
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'http', :domain => 'admin.spec.com', :user_agent => nil})).path.route.should == target_route_http_admin
|
126
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'http', :domain => 'www.spec.com', :user_agent => nil})).path.route.should == target_route_http_www
|
127
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'https', :domain => 'admin.spec.com', :user_agent => 'MSIE 6.0'})).path.route.should == target_route_https_msie
|
128
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample', :protocol => 'https', :domain => 'admin.spec.com', :user_agent => nil})).path.route.should == target_route_https_admin
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should correctly fix that tree if conditionals are used later" do
|
132
|
+
noop_route = route_set.add_route('/noop', :controller => 'products', :action => 'noop')
|
133
|
+
product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:method => 'get'})
|
134
|
+
route_set.recognize(build_request({:method => 'get', :path => '/noop', :domain => 'admin.host.com'})).path.route.should == noop_route
|
135
|
+
route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'})).path.route.should == product_show_route
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should use conditionals that are boolean" do
|
139
|
+
# hijacking user_agent
|
140
|
+
insecure_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:user_agent => false, :method => 'get'})
|
141
|
+
secure_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:user_agent => true, :method => 'get'})
|
142
|
+
|
143
|
+
secure_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com', :user_agent => true})).path.route
|
144
|
+
insecure_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com', :user_agent => false})).path.route
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should use conditionals that are arrays" do
|
148
|
+
# hijacking user_agent
|
149
|
+
www_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['www'], :method => 'get'})
|
150
|
+
admin_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['admin'], :method => 'get'})
|
151
|
+
|
152
|
+
admin_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['admin'], :user_agent => true})).path.route
|
153
|
+
www_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['www'], :user_agent => false})).path.route
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should use a requirement (proc) on incoming variables" do
|
157
|
+
route_set.add_route('/:controller/:action/:id', :id => proc{|v| Integer(v)})
|
158
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'}))}.should_not raise_error Usher::ValidationException
|
159
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'}))}.should raise_error Usher::ValidationException
|
160
|
+
end
|
161
|
+
|
162
|
+
it "shouldn't care about mildly weird characters in the URL" do
|
163
|
+
route = route_set.add_route('/!asd,qwe/hjk$qwe/:id')
|
164
|
+
route_set.recognize(build_request({:method => 'get', :path => '/!asd,qwe/hjk$qwe/09AZaz$-_+!*\'', :domain => 'admin.host.com'})).params.rassoc('09AZaz$-_+!*\'').first.should == :id
|
165
|
+
end
|
166
|
+
|
167
|
+
it "shouldn't care about non-primary delimiters in the path" do
|
168
|
+
route = route_set.add_route('/testing/:id/testing2/:id2/:id3')
|
169
|
+
route_set.recognize(build_request({:method => 'get', :path => '/testing/asd.qwe/testing2/poi.zxc/oiu.asd'})).params.should == [[:id, 'asd.qwe'], [:id2, 'poi.zxc'], [:id3, 'oiu.asd']]
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should should raise if malformed variables are used" do
|
173
|
+
route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:method => 'get'})
|
174
|
+
proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/qweasd', :domain => 'admin.host.com'}))}.should raise_error
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
describe "Usher request method" do
|
4
|
+
|
5
|
+
it "support eql? and ==" do
|
6
|
+
Usher::Route::RequestMethod.new(:method, 'blah').should == Usher::Route::RequestMethod.new(:method, 'blah')
|
7
|
+
Usher::Route::RequestMethod.new(:method, 'blah').should.eql?(Usher::Route::RequestMethod.new(:method, 'blah'))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "support hash" do
|
11
|
+
Usher::Route::RequestMethod.new(:method, 'blah').hash.should == (Usher::Route::RequestMethod.new(:method, 'blah')).hash
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
describe "Usher route tokenizing" do
|
4
|
+
|
5
|
+
|
6
|
+
it "should split / delimited routes" do
|
7
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this/split').should == [['/', 'test', '/','this', '/', 'split']]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should split / delimited routes with a regex in it" do
|
11
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').
|
12
|
+
split('/test/{this}/split').should == [['/', 'test', '/', /this/, '/', 'split']]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should split on ' ' delimited routes as well" do
|
16
|
+
Usher::Splitter.for_delimiters([' '], '[0-9A-Za-z\$\-_\+!\*\',]+').split('test this split').should == [['test', ' ', 'this', ' ', 'split']]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should split on email delimiters as well" do
|
20
|
+
Usher::Splitter.for_delimiters(['@', '+', '-', '.'], '[a-zA-Z0-9]+').split('one+more.12345-09876-alphanum3ric5@domain.com').should == [["one", '+', "more", ".", "12345", '-', "09876", '-', "alphanum3ric5", "@", "domain", ".", "com"]]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should split on ' ' delimited routes for more complex routes as well" do
|
24
|
+
Usher::Splitter.for_delimiters([' '], '[0-9A-Za-z\$\-_\+!\*\',]+').split('(test|this) split').should == [['test', ' ', 'split'], ['this', ' ', 'split']]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should group optional parts with brackets" do
|
28
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)').should == [
|
29
|
+
['/', 'test', '/', 'this'],
|
30
|
+
['/', 'test', '/', 'this', '/', 'split']
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should group exclusive optional parts with brackets and pipes" do
|
35
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split|/split2)').should == [
|
36
|
+
['/', 'test', '/', 'this','/', 'split'],
|
37
|
+
['/', 'test', '/', 'this','/', 'split2']
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should group exclusive optional-optional parts with brackets and pipes" do
|
42
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this((/split|/split2))').should == [
|
43
|
+
['/', 'test','/', 'this'],
|
44
|
+
['/', 'test','/', 'this', '/', 'split'],
|
45
|
+
['/', 'test','/', 'this', '/', 'split2']
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should group optional parts with brackets (for non overlapping groups)" do
|
50
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)(/split2)') == [
|
51
|
+
['/', "test", '/', "this"],
|
52
|
+
['/', "test", '/', "this", '/', "split"],
|
53
|
+
['/', "test", '/', "this", '/', "split2"],
|
54
|
+
['/', "test", '/', "this", '/', "split", '/', "split2"]
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should group nested-optional parts with brackets" do
|
59
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split(.:format))') == [
|
60
|
+
['/', "test", '/', "this"],
|
61
|
+
['/', "test", '/', "this", '/', "split"],
|
62
|
+
['/', "test", '/', "this", '/', "split", '.', Usher::Route::Variable.new(:':', :format)]
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should to_s all different variable types" do
|
67
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/*splitter').first.collect{|v| v.to_s} ==
|
68
|
+
[ ':split', '*splitter' ]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should == variable types" do
|
72
|
+
parts = Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/:split').first
|
73
|
+
parts[1].should == parts[3]
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|