joshbuddy-usher 0.4.3 → 0.4.5

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.
@@ -1,10 +1,8 @@
1
- require 'set'
2
-
3
1
  class Usher
4
2
  class Route
5
3
  class Path
6
4
 
7
- attr_reader :dynamic_parts, :dynamic_map, :dynamic_indicies, :route, :dynamic_set, :parts
5
+ attr_reader :dynamic_parts, :dynamic_map, :dynamic_indicies, :route, :parts, :dynamic_required_keys, :dynamic_keys
8
6
 
9
7
  def initialize(route, parts)
10
8
  @route = route
@@ -14,9 +12,13 @@ class Usher
14
12
  @dynamic_parts = @parts.values_at(*@dynamic_indicies)
15
13
  @dynamic_map = {}
16
14
  @dynamic_parts.each{|p| @dynamic_map[p.name] = p }
17
- @dynamic_set = Set.new(@dynamic_map.keys)
15
+ @dynamic_keys = @dynamic_map.keys
16
+ @dynamic_required_keys = @dynamic_parts.select{|dp| !dp.default_value}.map{|dp| dp.name}
17
+ end
18
+
19
+ def can_generate_from?(keys)
20
+ (@dynamic_required_keys - keys).size.zero?
18
21
  end
19
-
20
22
  end
21
23
  end
22
24
  end
@@ -2,7 +2,7 @@ class Usher
2
2
  class Route
3
3
  class Variable
4
4
  attr_reader :type, :name, :validator, :regex_matcher
5
- attr_accessor :look_ahead, :globs_capture_separators
5
+ attr_accessor :look_ahead, :globs_capture_separators, :default_value
6
6
 
7
7
  def initialize(type, name, validator = nil, regex_matcher = nil, globs_capture_separators = false)
8
8
  @type = type
@@ -19,14 +19,16 @@ class Usher
19
19
  def valid!(val)
20
20
  case @validator
21
21
  when Proc
22
- @validator.call(val)
22
+ begin
23
+ @validator.call(val)
24
+ rescue Exception => e
25
+ raise ValidationException.new("#{val} does not conform to #{@validator}, root cause #{e.inspect}")
26
+ end
23
27
  else
24
- @validator === val or raise
28
+ @validator === val or raise(ValidationException.new("#{val} does not conform to #{@validator}, root cause #{e.inspect}"))
25
29
  end if @validator
26
- rescue Exception => e
27
- raise ValidationException.new("#{val} does not conform to #{@validator}, root cause #{e.inspect}")
28
30
  end
29
-
31
+
30
32
  def ==(o)
31
33
  o && (o.type == @type && o.name == @name && o.validator == @validator)
32
34
  end
data/lib/usher/route.rb CHANGED
@@ -6,17 +6,27 @@ require 'route/request_method'
6
6
 
7
7
  class Usher
8
8
  class Route
9
- attr_reader :paths, :original_path, :requirements, :conditions, :params, :primary_path
9
+ attr_reader :paths, :original_path, :requirements, :conditions, :destination, :named
10
10
 
11
- def initialize(original_path, router, options = nil) # :nodoc:
11
+ def initialize(original_path, router, conditions, requirements, default_values) # :nodoc:
12
12
  @original_path = original_path
13
13
  @router = router
14
- @requirements = options && options.delete(:requirements)
15
- @conditions = options && options.delete(:conditions)
16
- @paths = @router.splitter.split(@original_path, @requirements).collect {|path| Path.new(self, path)}
17
- @primary_path = @paths.first
18
- #FIXME params is poorly named. this shouldn't be an array
19
- @params = []
14
+ @requirements = requirements
15
+ @conditions = conditions
16
+ @default_values = default_values
17
+ @paths = @router.splitter.split(@original_path, @requirements, @default_values).collect {|path| Path.new(self, path)}
18
+ end
19
+
20
+ def grapher
21
+ unless @grapher
22
+ @grapher = Grapher.new
23
+ @grapher.add_route(self)
24
+ end
25
+ @grapher
26
+ end
27
+
28
+ def find_matching_path(params)
29
+ @paths.size == 1 ? @paths.first : grapher.find_matching_path(params)
20
30
  end
21
31
 
22
32
 
@@ -28,7 +38,7 @@ class Usher
28
38
  # route.to(:controller => 'testing', :action => 'index')
29
39
  # set.recognize(Request.new('/test')).first.params => {:controller => 'testing', :action => 'index'}
30
40
  def to(options = nil, &block)
31
- @params << (block_given? ? block : options)
41
+ @destination = (block_given? ? block : options)
32
42
  self
33
43
  end
34
44
 
@@ -38,7 +48,9 @@ class Usher
38
48
  # route = set.add_route('/test').name(:route)
39
49
  # set.generate_url(:route) => '/test'
40
50
  def name(name)
51
+ @named = name
41
52
  @router.name(name, self)
53
+ self
42
54
  end
43
55
 
44
56
  end
@@ -8,7 +8,7 @@ class Usher
8
8
  SplitterInstance.new(
9
9
  delimiters,
10
10
  Regexp.new('((:|\*)?' + valid_regex + '|' + delimiters_regex + '|\(|\)|\||\{)'),
11
- Regexp.new(delimiters_regex + '|' + valid_regex)
11
+ Regexp.new("[#{delimiters.collect{|d| Regexp.quote(d)}}]|[^#{delimiters.collect{|d| Regexp.quote(d)}}]+")
12
12
  )
13
13
  end
14
14
 
@@ -16,21 +16,20 @@ class Usher
16
16
 
17
17
  class SplitterInstance
18
18
 
19
+ attr_reader :delimiter_chars
20
+
19
21
  def initialize(delimiters, split_regex, url_split_regex)
20
22
  @delimiters = delimiters
21
23
  @delimiter_chars = delimiters.collect{|d| d[0]}
22
- @delimiter_chars_map = Hash[*@delimiter_chars.map{|c| [c, c.chr.to_sym]}.flatten]
23
24
  @split_regex = split_regex
24
25
  @url_split_regex = url_split_regex
25
26
  end
26
27
 
27
28
  def url_split(path)
28
- parts = path.scan(@url_split_regex)
29
- parts.map!{ |part| @delimiter_chars_map[part[0]] || part}
30
- parts
29
+ path.scan(@url_split_regex)
31
30
  end
32
31
 
33
- def split(path, requirements = nil)
32
+ def split(path, requirements = nil, default_values = nil)
34
33
  parts = Group.new(:all, nil)
35
34
  ss = StringScanner.new(path)
36
35
  current_group = parts
@@ -80,8 +79,6 @@ class Usher
80
79
  end
81
80
  current_group.parent << Group.new(:all, current_group.parent)
82
81
  current_group = current_group.parent.last
83
- when *@delimiter_chars
84
- current_group << part.to_sym
85
82
  else
86
83
  current_group << part
87
84
  end
@@ -90,11 +87,13 @@ class Usher
90
87
  paths.each do |path|
91
88
  path.each_with_index do |part, index|
92
89
  if part.is_a?(Usher::Route::Variable)
90
+ part.default_value = default_values[part.name] if default_values
91
+
93
92
  case part.type
94
93
  when :*
95
- part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Symbol) && !p.is_a?(Usher::Route::Variable)} || nil
94
+ part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Usher::Route::Variable) && !@delimiter_chars.include?(p[0])} || nil
96
95
  when :':'
97
- part.look_ahead = path[index + 1, path.size].find{|p| p.is_a?(Symbol)} || @delimiters.first.to_sym
96
+ part.look_ahead = path[index + 1, path.size].find{|p| @delimiter_chars.include?(p[0])} || @delimiters.first
98
97
  end
99
98
  end
100
99
  end
data/lib/usher.rb CHANGED
@@ -8,9 +8,10 @@ require 'usher/grapher'
8
8
  require 'usher/interface'
9
9
  require 'usher/splitter'
10
10
  require 'usher/exceptions'
11
+ require 'usher/generate'
11
12
 
12
13
  class Usher
13
- attr_reader :tree, :named_routes, :route_count, :routes, :splitter
14
+ attr_reader :tree, :named_routes, :route_count, :routes, :splitter, :delimiters
14
15
 
15
16
  SymbolArraySorter = proc {|a,b| a.hash <=> b.hash} #:nodoc:
16
17
 
@@ -75,7 +76,8 @@ class Usher
75
76
  # route = set.add_route('/test')
76
77
  # set.name(:test, route)
77
78
  def name(name, route)
78
- @named_routes[name] = route.primary_path
79
+ @named_routes[name] = route
80
+ route
79
81
  end
80
82
 
81
83
  # Creates a route from +path+ and +options+
@@ -142,6 +144,7 @@ class Usher
142
144
  def add_route(path, options = nil)
143
145
  conditions = options && options.delete(:conditions) || {}
144
146
  requirements = options && options.delete(:requirements) || {}
147
+ default_values = options && options.delete(:default_values) || {}
145
148
  if options
146
149
  options.delete_if do |k, v|
147
150
  if v.is_a?(Regexp) || v.is_a?(Proc)
@@ -150,7 +153,7 @@ class Usher
150
153
  end
151
154
  end
152
155
  end
153
- route = Route.new(path, self, {:conditions => conditions, :requirements => requirements})
156
+ route = Route.new(path, self, conditions, requirements, default_values)
154
157
  route.to(options) if options && !options.empty?
155
158
 
156
159
  @tree.add(route)
@@ -167,87 +170,16 @@ class Usher
167
170
  # route = set.add_route('/test')
168
171
  # set.recognize(Request.new('/test')).path.route == route => true
169
172
  def recognize(request, path = request.path)
170
- @tree.find(request, @splitter.url_split(path))
173
+ @tree.find(self, request, @splitter.url_split(path))
171
174
  end
172
175
 
173
176
  # Recognizes a set of +parameters+ and gets the closest matching Usher::Route::Path or +nil+ if no route exists.
174
177
  #
175
178
  # set = Usher.new
176
179
  # route = set.add_route('/:controller/:action')
177
- # set.route_for_options({:controller => 'test', :action => 'action'}) == path.route => true
178
- def route_for_options(options)
180
+ # set.path_for_options({:controller => 'test', :action => 'action'}) == path.route => true
181
+ def path_for_options(options)
179
182
  @grapher.find_matching_path(options)
180
183
  end
181
184
 
182
- # Generates a completed URL based on a +route+ or set of optional +params+
183
- #
184
- # set = Usher.new
185
- # route = set.add_named_route(:test_route, '/:controller/:action')
186
- # set.generate_url(nil, {:controller => 'c', :action => 'a'}) == '/c/a' => true
187
- # set.generate_url(:test_route, {:controller => 'c', :action => 'a'}) == '/c/a' => true
188
- # set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
189
- def generate_url(route, params = nil, options = nil)
190
- check_variables = options && options.key?(:check_variables) ? options.delete(:check_variables) : false
191
- delimiter = options && options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
192
- extra_params = options && options.key?(:extra_params) ? options.delete(:extra_params) : {}
193
-
194
- path = case route
195
- when Symbol
196
- @named_routes[route]
197
- when nil
198
- route_for_options(params)
199
- when Route
200
- route.paths.first
201
- else
202
- route
203
- end
204
- raise UnrecognizedException.new unless path
205
- params_hash = extra_params
206
- param_list = case params
207
- when Hash
208
- params_hash.merge!(params)
209
- path.dynamic_parts.collect{|k| params_hash.delete(k.name) {|el| raise MissingParameterException.new(k.name)} }
210
- when Array
211
- path.dynamic_parts.size == params.size ? params : raise(MissingParameterException.new("got #{params.size} arguments, expected #{path.dynamic_parts.size}"))
212
- when nil
213
- nil
214
- else
215
- Array(params)
216
- end
217
-
218
- generated_path = ''
219
-
220
- path.parts.each do |p|
221
- case p
222
- when Route::Variable
223
- case p.type
224
- when :*
225
- param_list.first.each {|dp| p.valid!(dp.to_s) } if check_variables
226
- generated_path << param_list.shift.collect{|dp| URI.escape(dp.to_s)} * delimiter
227
- else
228
- p.valid!(param_list.first.to_s) if check_variables
229
- if dp = param_list.shift
230
- generated_path << URI.escape(dp.to_s)
231
- end
232
- end
233
- else
234
- generated_path << p.to_s
235
- end
236
- end
237
-
238
- unless params_hash.empty?
239
- has_query = generated_path[??]
240
- params_hash.each do |k,v|
241
- case v
242
- when Array
243
- v.each do |v_part|
244
- generated_path << (has_query ? '&' : has_query = true && '?') << CGI.escape("#{k.to_s}[]") << '=' << CGI.escape(v_part.to_s)
245
- end
246
- else
247
- generated_path << (has_query ? '&' : has_query = true && '?') << CGI.escape(k.to_s) << '=' << CGI.escape(v.to_s)
248
- end
249
- end
250
- end
251
- generated_path
252
- end
253
185
  end
data/rails/init.rb CHANGED
@@ -1,4 +1,8 @@
1
- class Usher::Interface::Rails2Interface::Mapper
2
- include ActionController::Resources
1
+ if Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR == 3
2
+ ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails2_3)"
3
+ elsif Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR >= 2
4
+ class Usher::Interface::Rails2_2Interface::Mapper
5
+ include ActionController::Resources
6
+ end
7
+ ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails2_2)"
3
8
  end
4
- ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails2);"
@@ -1,107 +1,136 @@
1
1
  require 'lib/usher'
2
2
 
3
- route_set = Usher.new
4
3
 
5
4
  describe "Usher URL generation" do
6
5
 
7
6
  before(:each) do
8
- route_set.reset!
7
+ @route_set = Usher.new
8
+ @route_set.reset!
9
+ @url_generator = Usher::Generators::URL.new(@route_set)
9
10
  end
10
11
 
11
12
  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'
13
+ @route_set.add_named_route(:sample, '/sample', :controller => 'sample', :action => 'action')
14
+ @url_generator.generate(:sample, {}).should == '/sample'
14
15
  end
15
16
 
16
17
  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'
18
+ @route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
19
+ @url_generator.generate(:sample, {:action => 'action'}).should == '/sample/action'
19
20
  end
20
21
 
21
22
  it "should generate a simple URL with a single variable (and escape)" do
22
- route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
23
- route_set.generate_url(:sample, {:action => 'action time'}).should == '/sample/action%20time'
23
+ @route_set.add_named_route(:sample, '/sample/:action', :controller => 'sample')
24
+ @url_generator.generate(:sample, {:action => 'action time'}).should == '/sample/action%20time'
24
25
  end
25
26
 
26
27
  it "should generate a simple URL with a single variable (thats not a string)" do
27
- route_set.add_named_route(:sample, '/sample/:action/:id', :controller => 'sample')
28
- route_set.generate_url(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
28
+ @route_set.add_named_route(:sample, '/sample/:action/:id', :controller => 'sample')
29
+ @url_generator.generate(:sample, {:action => 'action', :id => 123}).should == '/sample/action/123'
29
30
  end
30
31
 
31
32
  it "should generate a simple URL with a glob variable" do
32
- route_set.add_named_route(:sample, '/sample/*action', :controller => 'sample')
33
- route_set.generate_url(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
33
+ @route_set.add_named_route(:sample, '/sample/*action', :controller => 'sample')
34
+ @url_generator.generate(:sample, {:action => ['foo', 'baz']}).should == '/sample/foo/baz'
34
35
  end
35
36
 
36
37
  it "should generate a mutliple vairable URL from a hash" do
37
- route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
38
- route_set.generate_url(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
38
+ @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
39
+ @url_generator.generate(:sample, {:first => 'zoo', :second => 'maz'}).should == '/sample/zoo/maz'
39
40
  end
40
41
 
41
42
  it "should generate a mutliple vairable URL from an array" do
42
- route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
43
- route_set.generate_url(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
43
+ @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
44
+ @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
44
45
  end
45
46
 
46
47
  it "should generate append extra hash variables to the end" 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'}).should == '/sample/maz/zoo?third=zanz'
48
+ @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'
49
50
  end
50
51
 
51
52
  it "should generate append extra hash variables to the end (when the first parts are an array)" do
52
- route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
53
- ['/sample/maz/zoo?four=jane&third=zanz', '/sample/maz/zoo?third=zanz&four=jane'].include?(route_set.generate_url(:sample, ['maz', 'zoo'], :extra_params => {:third => 'zanz', :four => 'jane'})).should == true
53
+ @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
54
55
  end
55
56
 
56
57
  it "should generate append extra hash variables to the end using [] syntax if its an array" do
57
- route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
58
- route_set.generate_url(:sample, {:first => 'maz', :second => 'zoo', :third => ['zanz', 'susie']}).should == '/sample/maz/zoo?third%5B%5D=zanz&third%5B%5D=susie'
58
+ @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'
59
60
  end
60
61
 
61
62
  it "should generate a mutliple vairable URL from an array" do
62
- route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
63
- route_set.generate_url(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
63
+ @route_set.add_named_route(:sample, '/sample/:first/:second', :controller => 'sample')
64
+ @url_generator.generate(:sample, ['maz', 'zoo']).should == '/sample/maz/zoo'
64
65
  end
65
66
 
66
67
  it "should generate a simple URL with a format" do
67
- route_set.add_named_route(:sample, '/sample/:action.:format', :controller => 'sample')
68
- route_set.generate_url(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
68
+ @route_set.add_named_route(:sample, '/sample/:action.:format', :controller => 'sample')
69
+ @url_generator.generate(:sample, {:action => 'action', :format => 'html'}).should == '/sample/action.html'
69
70
  end
70
71
 
71
72
  it "should generate from parameters" do
72
- caf = route_set.add_route('/:controller/:action.:format')
73
- ca = route_set.add_route('/:controller/:action')
74
- route_set.generate_url(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
75
- route_set.generate_url(nil, {:controller => 'controller', :action => 'action', :format => 'html'}).should == '/controller/action.html'
73
+ caf = @route_set.add_route('/:controller/:action.:format')
74
+ 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'
76
77
  end
77
78
 
78
79
  it "should use the first route when generating a URL from two ambiguous routes" do
79
- route_set.add_route('/:controller/:action')
80
- route_set.add_route('/:action/:controller')
81
- route_set.generate_url(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
80
+ @route_set.add_route('/:controller/:action')
81
+ @route_set.add_route('/:action/:controller')
82
+ @url_generator.generate(nil, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
82
83
  end
83
84
 
84
85
  it "should accept an array of parameters" do
85
- caf = route_set.add_named_route(:name, '/:controller/:action.:format')
86
- route_set.generate_url(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
86
+ caf = @route_set.add_named_route(:name, '/:controller/:action.:format')
87
+ @url_generator.generate(:name, ['controller', 'action', 'html']).should == '/controller/action.html'
87
88
  end
88
89
 
89
90
  it "should require all the parameters (hash) to generate a route" do
90
- proc {route_set.generate_url(route_set.add_route('/:controller/:action').primary_path, {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
91
+ proc {@url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
91
92
  end
92
93
 
93
94
  it "should generate from a route" do
94
- route_set.generate_url(route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
95
+ @url_generator.generate(@route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
95
96
  end
96
97
 
97
98
  it "should require all the parameters (array) to generate a route" do
98
- route_set.add_named_route(:name, '/:controller/:action.:format')
99
- proc {route_set.generate_url(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
99
+ @route_set.add_named_route(:name, '/:controller/:action.:format')
100
+ proc {@url_generator.generate(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
100
101
  end
101
102
 
102
103
  it "should generate a route when only one parameter is given" do
103
- route_set.add_named_route(:name, '/:controller')
104
- route_set.generate_url(:name, 'controller').should == '/controller'
104
+ @route_set.add_named_route(:name, '/:controller')
105
+ @url_generator.generate(:name, 'controller').should == '/controller'
105
106
  end
106
107
 
108
+ it "should generate the correct route from a route containing optional parts" do
109
+ @route_set.add_named_route(:name, '/:controller(/:action(/:id))')
110
+ @url_generator.generate(:name, {:controller => 'controller'}).should == '/controller'
111
+ @url_generator.generate(:name, {:controller => 'controller', :action => 'action'}).should == '/controller/action'
112
+ @url_generator.generate(:name, {:controller => 'controller', :action => 'action', :id => 'id'}).should == '/controller/action/id'
113
+ end
114
+
115
+ it "should generate a route using defaults for everything but the first parameter" do
116
+ @route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
117
+ @url_generator.generate(:name, {:one => "1"}).should == '/1/two/three'
118
+ end
119
+
120
+ it "should generate a route using defaults for everything" do
121
+ @route_set.add_named_route(:name, '/:one/:two/:three', {:default_values => {:one => 'one', :two => 'two', :three => 'three'}})
122
+ @url_generator.generate(:name).should == '/one/two/three'
123
+ end
124
+
125
+ it "should generate a route using defaults and optionals using the last parameter" do
126
+ @route_set.add_named_route(:opts_with_defaults, '/:one(/:two(/:three))', {:default_values => {:one => '1', :two => '2', :three => '3'}})
127
+ @url_generator.generate(:opts_with_defaults, {:three => 'three'}).should == '/1/2/three'
128
+ end
129
+
130
+ it "should generate a route with optional segments given two nested optional parameters" do
131
+ @route_set.add_named_route(:optionals, '/:controller(/:action(/:id))(.:format)')
132
+ @url_generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
133
+ end
134
+
135
+
107
136
  end