usher 0.4.8 → 0.5.1

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.
@@ -0,0 +1,145 @@
1
+ require 'strscan'
2
+
3
+ class Usher
4
+ module Util
5
+ class Parser
6
+
7
+ def self.for_delimiters(router, valid_regex)
8
+ ParserInstance.new(
9
+ router,
10
+ Regexp.new('((:|\*)?' + valid_regex + '|' + router.delimiters_regex + '|\(|\)|\||\{)')
11
+ )
12
+ end
13
+
14
+ class ParserInstance
15
+
16
+ def initialize(router, split_regex)
17
+ @router = router
18
+ @split_regex = split_regex
19
+ end
20
+
21
+ def generate_route(unprocessed_path, conditions, requirements, default_values, generate_with)
22
+ match_partially = if unprocessed_path.is_a?(String)
23
+ unprocessed_path = parse(unprocessed_path, requirements, default_values)
24
+ if unprocessed_path[-1] == ?*
25
+ unprocessed_path.slice!(-1)
26
+ true
27
+ else
28
+ false
29
+ end
30
+ else
31
+ false
32
+ end
33
+
34
+ unless unprocessed_path.first.is_a?(Route::Util::Group)
35
+ group = Usher::Route::Util::Group.new(:all, nil)
36
+ unprocessed_path.each{|p| group << p}
37
+ unprocessed_path = group
38
+ end
39
+
40
+ paths = Route::Util.expand_path(unprocessed_path)
41
+
42
+ paths.each do |path|
43
+ path.each_with_index do |part, index|
44
+ part.default_value = default_values[part.name] if part.is_a?(Usher::Route::Variable) && default_values && default_values[part.name]
45
+ case part
46
+ when Usher::Route::Variable::Glob
47
+ part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Usher::Route::Variable) && !router.delimiter_chars.include?(p[0])} || nil
48
+ when Usher::Route::Variable
49
+ part.look_ahead = path[index + 1, path.size].find{|p| router.delimiter_chars.include?(p[0])} || router.delimiters.first
50
+ end
51
+ end
52
+ end
53
+
54
+ Route.new(
55
+ paths,
56
+ router,
57
+ conditions,
58
+ requirements,
59
+ default_values,
60
+ generate_with,
61
+ match_partially
62
+ )
63
+
64
+ end
65
+
66
+
67
+ def parse_and_expand(path, requirements = nil, default_values = nil)
68
+ Usher::Route::Util.expand_path(parse(path, requirements, default_values))
69
+ end
70
+
71
+ def parse(path, requirements = nil, default_values = nil)
72
+ parts = Usher::Route::Util::Group.new(:all, nil)
73
+ ss = StringScanner.new(path)
74
+ current_group = parts
75
+ while !ss.eos?
76
+ part = ss.scan(@split_regex)
77
+ case part[0]
78
+ when ?*
79
+ var_name = part[1, part.size - 1].to_sym
80
+ current_group << Usher::Route::Variable::Glob.new(part[1, part.size - 1], nil, requirements && requirements[var_name])
81
+ when ?:
82
+ var_name = part[1, part.size - 1].to_sym
83
+ current_group << Usher::Route::Variable::Single.new(part[1, part.size - 1], nil, requirements && requirements[var_name])
84
+ when ?{
85
+ pattern = ''
86
+ count = 1
87
+ variable = ss.scan(/[!:\*]([^,]+),/)
88
+ until count.zero?
89
+ regex_part = ss.scan(/\{|\}|[^\{\}]+/)
90
+ case regex_part[0]
91
+ when ?{
92
+ count += 1
93
+ when ?}
94
+ count -= 1
95
+ end
96
+ pattern << regex_part
97
+ end
98
+ pattern.slice!(pattern.length - 1)
99
+ regex = Regexp.new(pattern)
100
+ if variable
101
+ variable_type = variable.slice!(0).chr.to_sym
102
+ variable_class = case variable_type
103
+ when :'!' then Usher::Route::Variable::Greedy
104
+ when :* then Usher::Route::Variable::Glob
105
+ when :':' then Usher::Route::Variable::Single
106
+ end
107
+
108
+ variable_name = variable[0, variable.size - 1].to_sym
109
+ current_group << variable_class.new(variable_name, regex, requirements && requirements[variable_name])
110
+ else
111
+ current_group << regex
112
+ end
113
+ when ?(
114
+ new_group = Usher::Route::Util::Group.new(:any, current_group)
115
+ current_group << new_group
116
+ current_group = new_group
117
+ when ?)
118
+ current_group = current_group.parent.group_type == :one ? current_group.parent.parent : current_group.parent
119
+ when ?|
120
+ unless current_group.parent.group_type == :one
121
+ detached_group = current_group.parent.pop
122
+ new_group = Usher::Route::Util::Group.new(:one, detached_group.parent)
123
+ detached_group.parent = new_group
124
+ detached_group.group_type = :all
125
+ new_group << detached_group
126
+ new_group.parent << new_group
127
+ end
128
+ current_group.parent << Usher::Route::Util::Group.new(:all, current_group.parent)
129
+ current_group = current_group.parent.last
130
+ else
131
+ current_group << part
132
+ end
133
+ end unless !path || path.empty?
134
+ parts
135
+ end
136
+
137
+ private
138
+ attr_reader :router
139
+
140
+ end
141
+
142
+
143
+ end
144
+ end
145
+ end
@@ -1,7 +1,5 @@
1
1
  require 'lib/usher'
2
2
 
3
-
4
-
5
3
  def build_email_mock(email)
6
4
  request = mock "Request"
7
5
  request.should_receive(:email).any_number_of_times.and_return(email)
@@ -24,14 +22,14 @@ describe "Usher (for email) route recognition" do
24
22
  it "should recognize a wildcard domain" do
25
23
  receiver = mock('receiver')
26
24
  receiver.should_receive(:action).with({:domain => 'gmail.com'}).exactly(1)
27
- @route_set.for('joshbuddy@*domain') { |params| receiver.action(params) }
25
+ @route_set.for('joshbuddy@{!domain,.*}') { |params| receiver.action(params) }
28
26
  @route_set.act('joshbuddy@gmail.com')
29
27
  end
30
28
 
31
29
  it "should recognize a complex email" do
32
30
  receiver = mock('receiver')
33
31
  receiver.should_receive(:action).with({:subject => 'sub+ect', :id => '123', :sid => '456', :tok => 'sdqwe123ae', :domain => 'mydomain.org'}).exactly(1)
34
- @route_set.for(':subject.{:id,^\d+$}-{:sid,^\d+$}-{:tok,^\w+$}@*domain') { |params| receiver.action(params) }
32
+ @route_set.for(':subject.{!id,\d+}-{!sid,\d+}-{!tok,\w+}@{!domain,.*}') { |params| receiver.action(params) }
35
33
  @route_set.act('sub+ect.123-456-sdqwe123ae@mydomain.org')
36
34
  end
37
35
 
@@ -4,138 +4,192 @@ require 'rack'
4
4
  describe "Usher URL generation" do
5
5
 
6
6
  before(:each) do
7
- @route_set = Usher.new
7
+ @route_set = Usher.new(:generator => Usher::Util::Generators::URL.new)
8
8
  @route_set.reset!
9
- @url_generator = Usher::Generators::URL.new(@route_set)
10
9
  end
11
10
 
12
11
  it "should generate a simple URL" do
13
12
  @route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'action')
14
- @url_generator.generate(:sample, {}).should == '/sample'
13
+ @route_set.generator.generate(:sample, {}).should == '/sample'
15
14
  end
16
15
 
17
16
  it "should generate a simple URL with a single variable" do
18
17
  @route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
19
- @url_generator.generate(:sample, {:action => 'action'}).should == '/sample/action'
18
+ @route_set.generator.generate(:sample, {:action => 'action'}).should == '/sample/action'
20
19
  end
21
20
 
22
21
  it "should generate a simple URL with a single variable (and escape)" do
23
22
  @route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
24
- @url_generator.generate(:sample, {:action => 'action time'}).should == '/sample/action%20time'
23
+ @route_set.generator.generate(:sample, {:action => 'action time'}).should == '/sample/action%20time'
25
24
  end
26
25
 
27
26
  it "should generate a simple URL with a single variable (thats not a string)" do
28
27
  @route_set.add_named_route(:sample, '/sample/:action/:id', :controller => 'sample')
29
- @url_generator.generate(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
28
+ @route_set.generator.generate(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
30
29
  end
31
30
 
32
31
  it "should generate a simple URL with a glob variable" do
33
32
  @route_set.add_named_route(:sample, '/sample/*action', :controller => 'sample')
34
- @url_generator.generate(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
33
+ @route_set.generator.generate(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
35
34
  end
36
35
 
37
36
  it "should generate a mutliple vairable URL from a hash" do
38
37
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
39
- @url_generator.generate(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
38
+ @route_set.generator.generate(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
40
39
  end
41
40
 
42
41
  it "should generate a mutliple vairable URL from an array" do
43
42
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
44
- @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
43
+ @route_set.generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
45
44
  end
46
45
 
47
46
  it "should generate append extra hash variables to the end" do
48
47
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
49
- @url_generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => 'zanz'}).should == '/sample/maz/zoo?third=zanz'
48
+ @route_set.generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => 'zanz'}).should == '/sample/maz/zoo?third=zanz'
50
49
  end
51
50
 
52
51
  it "should generate append extra hash variables to the end (when the first parts are an array)" do
53
52
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
54
- ['/sample/maz/zoo?four=jane&third=zanz', '/sample/maz/zoo?third=zanz&four=jane'].include?(@url_generator.generate(:sample, ['maz', 'zoo', {:third => 'zanz', :four => 'jane'}])).should == true
53
+ ['/sample/maz/zoo?four=jane&third=zanz', '/sample/maz/zoo?third=zanz&four=jane'].include?(@route_set.generator.generate(:sample, ['maz', 'zoo', {:third => 'zanz', :four => 'jane'}])).should == true
55
54
  end
56
55
 
57
56
  it "should generate append extra hash variables to the end using [] syntax if its an array" do
58
57
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
59
- @url_generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
58
+ @route_set.generator.generate(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
60
59
  end
61
60
 
62
61
  it "should generate a mutliple vairable URL from an array" do
63
62
  @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
64
- @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
63
+ @route_set.generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
65
64
  end
66
65
 
67
66
  it "should generate a simple URL with a format" do
68
67
  @route_set.add_named_route(:sample, '/sample/:action.:format', :controller => 'sample')
69
- @url_generator.generate(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
68
+ @route_set.generator.generate(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
70
69
  end
71
70
 
72
71
  it "should generate from parameters" do
73
72
  caf = @route_set.add_route('/:controller/:action.:format')
74
73
  ca = @route_set.add_route('/:controller/:action')
75
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
76
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action', :format => 'html'}).should == '/controller/action.html'
74
+ @route_set.generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
75
+ @route_set.generator.generate(nil, {:controller => 'controller', :action => 'action', :format => 'html'}).should == '/controller/action.html'
77
76
  end
78
77
 
79
78
  it "should use the first route when generating a URL from two ambiguous routes" do
80
79
  @route_set.add_route('/:controller/:action')
81
80
  @route_set.add_route('/:action/:controller')
82
- @url_generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
81
+ @route_set.generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
83
82
  end
84
83
 
85
84
  it "should accept an array of parameters" do
86
85
  caf = @route_set.add_named_route(:name, '/:controller/:action.:format')
87
- @url_generator.generate(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
86
+ @route_set.generator.generate(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
88
87
  end
89
88
 
90
89
  it "should generate a route with a specific host" do
91
90
  caf = @route_set.add_named_route(:name, '/:controller/:action.:format', :generate_with => {:host => 'www.slashdot.org', :port => 80})
92
- @url_generator.generate_full(:name, Rack::Request.new(Rack::MockRequest.env_for("http://localhost:8080")), ['controller', 'action', 'html']).should == 'http://www.slashdot.org/controller/action.html'
91
+ @route_set.generator.generate_full(:name, Rack::Request.new(Rack::MockRequest.env_for("http://localhost:8080")), ['controller', 'action', 'html']).should == 'http://www.slashdot.org/controller/action.html'
93
92
  end
94
93
 
95
94
  it "should require all the parameters (hash) to generate a route" do
96
- proc {@url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
95
+ proc{@route_set.generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller'})}.should raise_error(Usher::MissingParameterException)
97
96
  end
98
97
 
99
98
  it "should generate from a route" do
100
- @url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
99
+ @route_set.generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
101
100
  end
102
101
 
103
102
  it "should require all the parameters (array) to generate a route" do
104
103
  @route_set.add_named_route(:name, '/:controller/:action.:format')
105
- proc {@url_generator.generate(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
104
+ proc {@route_set.generator.generate(:name, ['controller', 'action'])}.should raise_error(Usher::MissingParameterException)
106
105
  end
107
106
 
108
107
  it "should generate a route when only one parameter is given" do
109
108
  @route_set.add_named_route(:name, '/:controller')
110
- @url_generator.generate(:name, 'controller').should == '/controller'
109
+ @route_set.generator.generate(:name, 'controller').should == '/controller'
111
110
  end
112
111
 
113
112
  it "should generate the correct route from a route containing optional parts" do
114
113
  @route_set.add_named_route(:name, '/:controller(/:action(/:id))')
115
- @url_generator.generate(:name, {:controller => 'controller'}).should == '/controller'
116
- @url_generator.generate(:name, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
117
- @url_generator.generate(:name, {:controller => 'controller', :action => 'action', :id => 'id'}).should == '/controller/action/id'
114
+ @route_set.generator.generate(:name, {:controller => 'controller'}).should == '/controller'
115
+ @route_set.generator.generate(:name, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
116
+ @route_set.generator.generate(:name, {:controller => 'controller', :action => 'action', :id => 'id'}).should == '/controller/action/id'
118
117
  end
119
118
 
120
119
  it "should generate a route using defaults for everything but the first parameter" do
121
120
  @route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
122
- @url_generator.generate(:name, {:one => "1"}).should == '/1/two/three'
121
+ @route_set.generator.generate(:name, {:one => "1"}).should == '/1/two/three'
123
122
  end
124
123
 
125
124
  it "should generate a route using defaults for everything" do
126
125
  @route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
127
- @url_generator.generate(:name).should == '/one/two/three'
126
+ @route_set.generator.generate(:name).should == '/one/two/three'
128
127
  end
129
128
 
130
129
  it "should generate a route using defaults and optionals using the last parameter" do
131
130
  @route_set.add_named_route(:opts_with_defaults, '/:one(/:two(/:three))', {:default_values => {:one => '1', :two => '2', :three => '3'}})
132
- @url_generator.generate(:opts_with_defaults, {:three => 'three'}).should == '/1/2/three'
131
+ @route_set.generator.generate(:opts_with_defaults, {:three => 'three'}).should == '/1/2/three'
133
132
  end
134
133
 
135
134
  it "should generate a route with optional segments given two nested optional parameters" do
136
135
  @route_set.add_named_route(:optionals, '/:controller(/:action(/:id))(.:format)')
137
- @url_generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
136
+ @route_set.generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
137
+ end
138
+
139
+ describe "nested generation" do
140
+ before do
141
+ @route_set2 = Usher.new(:generator => Usher::Util::Generators::URL.new)
142
+ @route_set3 = Usher.new(:generator => Usher::Util::Generators::URL.new)
143
+ @route_set4 = Usher.new(:generator => Usher::Util::Generators::URL.new)
144
+
145
+ @route_set.add_named_route(:simple, "/mount_point").match_partially!.to(@route_set2)
146
+ @route_set.add_route("/third/:foo", :default_values => {:foo => "foo"}).match_partially!.to(@route_set3)
147
+ @route_set.add_route("/fourth/:bar").match_partially!.to(@route_set4)
148
+
149
+ @route_set2.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
150
+ @route_set2.add_named_route(:nested_complex, "/another_nested(/:complex)", :controller => "nested", :action => "complex")
151
+
152
+ @route_set3.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
153
+ @route_set3.add_named_route(:nested_complex, "/another_nested(/:complex)", :controller => "nested", :action => "complex")
154
+
155
+ @route_set4.add_named_route(:nested_simple, "/nested/simple", :controller => "nested", :action => "simple")
156
+ end
157
+
158
+ it "should generate a route for the simple nested route" do
159
+ @route_set2.generator.generate(:nested_simple).should == "/mount_point/nested/simple"
160
+ end
161
+
162
+ it "should generate a simple route without optional segments" do
163
+ @route_set2.generator.generate(:nested_complex).should == "/mount_point/another_nested"
164
+ end
165
+
166
+ it "should generate a route with optional segements" do
167
+ @route_set2.generator.generate(:nested_complex, :complex => "foo").should == "/mount_point/another_nested/foo"
168
+ end
169
+
170
+ it "should genearte a route with the specified value for the parent route" do
171
+ @route_set3.generator.generate(:nested_simple, :foo => "bar").should == "/third/bar/nested/simple"
172
+ end
173
+
174
+ it "should generate a route with the default value from the parent route" do
175
+ @route_set3.generator.generate(:nested_simple).should == "/third/foo/nested/simple"
176
+ end
177
+
178
+ it "should generate a route with an optional segement in the parent and child" do
179
+ @route_set3.generator.generate(:nested_complex, :complex => "complex").should == "/third/foo/another_nested/complex"
180
+ end
181
+
182
+ it "should generate a route without the optional value from the child" do
183
+ @route_set3.generator.generate(:nested_complex).should == "/third/foo/another_nested"
184
+ end
185
+
186
+ it "should raise an exception when trying to generate a route where the parent variable is not defined and does not have a default value" do
187
+ lambda do
188
+ @route_set4.generator.generate(:nested_simple)
189
+ end.should raise_error(Usher::MissingParameterException)
190
+ end
191
+
192
+
193
+
138
194
  end
139
-
140
-
141
195
  end
@@ -4,31 +4,30 @@ require 'lib/usher'
4
4
  describe "Usher grapher" do
5
5
 
6
6
  before(:each) do
7
- @route_set = Usher.new
7
+ @route_set = Usher.new(:generator => Usher::Util::Generators::URL.new)
8
8
  @route_set.reset!
9
- @url_generator = Usher::Generators::URL.new(@route_set)
10
9
  end
11
10
 
12
11
  it "should find a simple path" do
13
12
  @route_set.add_route('/:a/:b/:c')
14
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
13
+ @route_set.generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
15
14
  end
16
15
 
17
16
  it "should pick a more specific route" do
18
17
  @route_set.add_route('/:a/:b')
19
18
  @route_set.add_route('/:a/:b/:c')
20
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
19
+ @route_set.generator.generate(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
21
20
  end
22
21
 
23
22
  it "should fail to generate a route when none matches" do
24
23
  @route_set.add_route('/:a/:b')
25
- proc {@url_generator.generate(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
24
+ proc {@route_set.generator.generate(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
26
25
  end
27
26
 
28
27
  it "should find the most specific route and append extra parts on as a query string" do
29
28
  @route_set.add_route('/:a/:b/:c')
30
29
  @route_set.add_route('/:a/:b')
31
- @url_generator.generate(nil, {:a => 'A', :b => 'B', :d => 'C'}).should == '/A/B?d=C'
30
+ @route_set.generator.generate(nil, {:a => 'A', :b => 'B', :d => 'C'}).should == '/A/B?d=C'
32
31
  end
33
32
 
34
33
  # FIXME
@@ -0,0 +1,75 @@
1
+ require 'lib/usher'
2
+
3
+ describe "Usher route tokenizing" do
4
+
5
+
6
+ it "should split / delimited routes" do
7
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this/split').should == [['/', 'test', '/','this', '/', 'split']]
8
+ end
9
+
10
+ it "should split / delimited routes with a regex in it" do
11
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/{this}/split').should == [['/', 'test', '/', /this/, '/', 'split']]
12
+ end
13
+
14
+ it "should split on ' ' delimited routes as well" do
15
+ Usher.new(:delimiters => [' '], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('test this split').should == [['test', ' ', 'this', ' ', 'split']]
16
+ end
17
+
18
+ it "should split on email delimiters as well" do
19
+ Usher.new(:delimiters => ['@', '+', '-', '.'], :valid_regex => '[a-zA-Z0-9]+').parser.parse_and_expand('one+more.12345-09876-alphanum3ric5@domain.com').should == [["one", '+', "more", ".", "12345", '-', "09876", '-', "alphanum3ric5", "@", "domain", ".", "com"]]
20
+ end
21
+
22
+ it "should split on ' ' delimited routes for more complex routes as well" do
23
+ Usher.new(:delimiters => [' '], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('(test|this) split').should == [['test', ' ', 'split'], ['this', ' ', 'split']]
24
+ end
25
+
26
+ it "should group optional parts with brackets" do
27
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this(/split)').should == [
28
+ ['/', 'test', '/', 'this'],
29
+ ['/', 'test', '/', 'this', '/', 'split']
30
+ ]
31
+ end
32
+
33
+ it "should group exclusive optional parts with brackets and pipes" do
34
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this(/split|/split2)').should == [
35
+ ['/', 'test', '/', 'this','/', 'split'],
36
+ ['/', 'test', '/', 'this','/', 'split2']
37
+ ]
38
+ end
39
+
40
+ it "should group exclusive optional-optional parts with brackets and pipes" do
41
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this((/split|/split2))').should == [
42
+ ['/', 'test','/', 'this'],
43
+ ['/', 'test','/', 'this', '/', 'split'],
44
+ ['/', 'test','/', 'this', '/', 'split2']
45
+ ]
46
+ end
47
+
48
+ it "should group optional parts with brackets (for non overlapping groups)" do
49
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this(/split)(/split2)') == [
50
+ ['/', "test", '/', "this"],
51
+ ['/', "test", '/', "this", '/', "split"],
52
+ ['/', "test", '/', "this", '/', "split2"],
53
+ ['/', "test", '/', "this", '/', "split", '/', "split2"]
54
+ ]
55
+ end
56
+
57
+ it "should group nested-optional parts with brackets" do
58
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/test/this(/split(.:format))') == [
59
+ ['/', "test", '/', "this"],
60
+ ['/', "test", '/', "this", '/', "split"],
61
+ ['/', "test", '/', "this", '/', "split", '.', Usher::Route::Variable::Single.new(:format)]
62
+ ]
63
+ end
64
+
65
+ it "should to_s all different variable types" do
66
+ Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/:split/*splitter').first.collect{|v| v.to_s} ==
67
+ [ ':split', '*splitter' ]
68
+ end
69
+
70
+ it "should == variable types" do
71
+ parts = Usher.new(:delimiters => ['/', '.'], :valid_regex => '[0-9A-Za-z\$\-_\+!\*\',]+').parser.parse_and_expand('/:split/:split').first
72
+ parts[1].should == parts[3]
73
+ end
74
+
75
+ end