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.
- data/README.rdoc +12 -1
- data/Rakefile +5 -29
- data/VERSION.yml +2 -2
- data/lib/usher.rb +126 -37
- data/lib/usher/grapher.rb +5 -4
- data/lib/usher/interface.rb +12 -5
- data/lib/usher/interface/email_interface.rb +1 -1
- data/lib/usher/interface/rack_interface.rb +31 -13
- data/lib/usher/interface/rails2_2_interface.rb +3 -4
- data/lib/usher/interface/rails2_3_interface.rb +3 -4
- data/lib/usher/interface/rails3_interface.rb +57 -0
- data/lib/usher/node.rb +121 -73
- data/lib/usher/route.rb +45 -11
- data/lib/usher/route/path.rb +50 -11
- data/lib/usher/route/util.rb +65 -0
- data/lib/usher/route/variable.rb +22 -11
- data/lib/usher/splitter.rb +4 -141
- data/lib/usher/util.rb +6 -0
- data/lib/usher/util/generate.rb +129 -0
- data/lib/usher/util/parser.rb +145 -0
- data/spec/private/email/recognize_spec.rb +2 -4
- data/spec/private/generate_spec.rb +86 -32
- data/spec/private/grapher_spec.rb +5 -6
- data/spec/private/parser_spec.rb +75 -0
- data/spec/private/path_spec.rb +35 -4
- data/spec/private/rack/dispatch_spec.rb +100 -15
- data/spec/private/recognize_spec.rb +88 -50
- data/spec/spec_helper.rb +22 -0
- metadata +13 -7
- data/lib/usher/generate.rb +0 -131
- data/spec/private/split_spec.rb +0 -76
| @@ -12,8 +12,7 @@ class Usher | |
| 12 12 | 
             
                  end
         | 
| 13 13 |  | 
| 14 14 | 
             
                  def reset!
         | 
| 15 | 
            -
                    @usher ||= Usher.new
         | 
| 16 | 
            -
                    @url_generator ||= Usher::Generators::URL.new(@usher)
         | 
| 15 | 
            +
                    @usher ||= Usher.new(:generator => Usher::Util::Generators::URL.new)
         | 
| 17 16 | 
             
                    @module ||= Module.new
         | 
| 18 17 | 
             
                    @module.instance_methods.each do |selector|
         | 
| 19 18 | 
             
                      @module.class_eval { remove_method selector }
         | 
| @@ -38,7 +37,7 @@ class Usher | |
| 38 37 |  | 
| 39 38 | 
             
                    path[0, 0] = '/' unless path[0] == ?/
         | 
| 40 39 | 
             
                    route = @usher.add_route(path, options)
         | 
| 41 | 
            -
                    raise "your route must include a controller" unless route.paths.first.dynamic_keys.include?(:controller) || route.destination.include?(:controller)
         | 
| 40 | 
            +
                    raise "your route must include a controller" unless (route.paths.first.dynamic_keys && route.paths.first.dynamic_keys.include?(:controller)) || route.destination.include?(:controller)
         | 
| 42 41 | 
             
                    route
         | 
| 43 42 | 
             
                  end
         | 
| 44 43 |  | 
| @@ -86,7 +85,7 @@ class Usher | |
| 86 85 | 
             
                  end
         | 
| 87 86 |  | 
| 88 87 | 
             
                  def generate_url(route, params)
         | 
| 89 | 
            -
                    @ | 
| 88 | 
            +
                    @usher.generator.generate(route, params)
         | 
| 90 89 | 
             
                  end
         | 
| 91 90 |  | 
| 92 91 | 
             
                  def path_for_options(options)
         | 
| @@ -28,7 +28,7 @@ class Usher | |
| 28 28 | 
             
                    path[0, 0] = '/' unless path[0] == ?/
         | 
| 29 29 | 
             
                    route = @router.add_route(path, options).to(options)
         | 
| 30 30 |  | 
| 31 | 
            -
                    raise "your route must include a controller" unless (route.paths.first.dynamic_keys.include?(:controller) || route.destination.include?(:controller) | 
| 31 | 
            +
                    raise "your route must include a controller" unless (route.paths.first.dynamic_keys && route.paths.first.dynamic_keys.include?(:controller)) || route.destination.include?(:controller)
         | 
| 32 32 | 
             
                    route
         | 
| 33 33 | 
             
                  end
         | 
| 34 34 |  | 
| @@ -72,8 +72,7 @@ class Usher | |
| 72 72 | 
             
                  end
         | 
| 73 73 |  | 
| 74 74 | 
             
                  def reset!
         | 
| 75 | 
            -
                    @router = Usher.new
         | 
| 76 | 
            -
                    @url_generator = Usher::Generators::URL.new(@router)
         | 
| 75 | 
            +
                    @router = Usher.new(:generator => Usher::Util::Generators::URL.new)
         | 
| 77 76 | 
             
                    @configuration_files = []
         | 
| 78 77 | 
             
                    @module ||= Module.new
         | 
| 79 78 | 
             
                    @controller_route_added = false
         | 
| @@ -123,7 +122,7 @@ class Usher | |
| 123 122 | 
             
                  end
         | 
| 124 123 |  | 
| 125 124 | 
             
                  def generate_url(route, params)
         | 
| 126 | 
            -
                    @ | 
| 125 | 
            +
                    @router.generator.generate(route, params)
         | 
| 127 126 | 
             
                  end
         | 
| 128 127 |  | 
| 129 128 | 
             
                  def path_for_options(options)
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            class Usher
         | 
| 2 | 
            +
              module Interface
         | 
| 3 | 
            +
                class Rails3Interface
         | 
| 4 | 
            +
                
         | 
| 5 | 
            +
                  @@instance = nil
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                  def initialize
         | 
| 8 | 
            +
                    @usher = Usher.new
         | 
| 9 | 
            +
                    @controller_paths = []
         | 
| 10 | 
            +
                    @configurations_files = []
         | 
| 11 | 
            +
                    
         | 
| 12 | 
            +
                    @@instance = self
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                  
         | 
| 15 | 
            +
                  def self.instance
         | 
| 16 | 
            +
                    @@instance
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  
         | 
| 19 | 
            +
                  def draw(&blk)
         | 
| 20 | 
            +
                    @usher.instance_eval(&blk)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  
         | 
| 23 | 
            +
                  attr_accessor :controller_paths
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  def add_configuration_file(file)
         | 
| 26 | 
            +
                    @configurations_files << file
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  def reload!
         | 
| 30 | 
            +
                    @usher.reset!
         | 
| 31 | 
            +
                    @configurations_files.each do |c|
         | 
| 32 | 
            +
                      Kernel.load(c)
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                  
         | 
| 36 | 
            +
                  def call(env)
         | 
| 37 | 
            +
                    request = ActionDispatch::Request.new(env)
         | 
| 38 | 
            +
                    response = @usher.recognize(request, request.path_info)
         | 
| 39 | 
            +
                    request.parameters.merge!(response.path.route.default_values) if response.path.route.default_values
         | 
| 40 | 
            +
                    response.params.each{ |hk| request.parameters[hk.first] = hk.last}
         | 
| 41 | 
            +
                    controller = "#{request.parameters[:controller].to_s.camelize}Controller".constantize
         | 
| 42 | 
            +
                    controller.action(request.parameters[:action] || 'index').call(env)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def recognize(request)
         | 
| 46 | 
            +
                    params = recognize_path(request.path, extract_request_environment(request))
         | 
| 47 | 
            +
                    request.path_parameters = params.with_indifferent_access
         | 
| 48 | 
            +
                    "#{params[:controller].to_s.camelize}Controller".constantize
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  
         | 
| 51 | 
            +
                  def load(app)
         | 
| 52 | 
            +
                    @app = app
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                  
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
    
        data/lib/usher/node.rb
    CHANGED
    
    | @@ -4,15 +4,16 @@ class Usher | |
| 4 4 |  | 
| 5 5 | 
             
              class Node
         | 
| 6 6 |  | 
| 7 | 
            -
                Response = Struct.new(:path, :params)
         | 
| 7 | 
            +
                Response = Struct.new(:path, :params, :remaining_path, :matched_path)
         | 
| 8 8 |  | 
| 9 | 
            -
                attr_reader :lookup
         | 
| 10 | 
            -
                attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods | 
| 9 | 
            +
                attr_reader :lookup, :greedy_lookup
         | 
| 10 | 
            +
                attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods
         | 
| 11 11 |  | 
| 12 12 | 
             
                def initialize(parent, value)
         | 
| 13 13 | 
             
                  @parent = parent
         | 
| 14 14 | 
             
                  @value = value
         | 
| 15 15 | 
             
                  @lookup = Hash.new
         | 
| 16 | 
            +
                  @greedy_lookup = Hash.new
         | 
| 16 17 | 
             
                  @exclusive_type = nil
         | 
| 17 18 | 
             
                end
         | 
| 18 19 |  | 
| @@ -20,14 +21,21 @@ class Usher | |
| 20 21 | 
             
                  @lookup = FuzzyHash.new(@lookup)
         | 
| 21 22 | 
             
                end
         | 
| 22 23 |  | 
| 24 | 
            +
                def upgrade_greedy_lookup
         | 
| 25 | 
            +
                  @greedy_lookup = FuzzyHash.new(@greedy_lookup)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 23 28 | 
             
                def depth
         | 
| 24 | 
            -
                  @depth ||= @parent | 
| 29 | 
            +
                  @depth ||= @parent.is_a?(Node) ? @parent.depth + 1 : 0
         | 
| 25 30 | 
             
                end
         | 
| 26 31 |  | 
| 27 | 
            -
                def  | 
| 32 | 
            +
                def greedy?
         | 
| 33 | 
            +
                  !@greedy_lookup.empty?
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                def self.root(route_set, request_methods)
         | 
| 28 37 | 
             
                  root = self.new(route_set, nil)
         | 
| 29 38 | 
             
                  root.request_methods = request_methods
         | 
| 30 | 
            -
                  root.globs_capture_separators = globs_capture_separators
         | 
| 31 39 | 
             
                  root
         | 
| 32 40 | 
             
                end
         | 
| 33 41 |  | 
| @@ -47,92 +55,132 @@ class Usher | |
| 47 55 |  | 
| 48 56 | 
             
                def add(route)
         | 
| 49 57 | 
             
                  route.paths.each do |path|
         | 
| 50 | 
            -
                     | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
                     | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
                          current_node.exclusive_type = key.type
         | 
| 65 | 
            -
                          current_node.lookup[key.value] ||= Node.new(current_node, key)
         | 
| 66 | 
            -
                        else
         | 
| 67 | 
            -
                          parts.unshift(key)
         | 
| 68 | 
            -
                          current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
         | 
| 69 | 
            -
                        end
         | 
| 70 | 
            -
                      else
         | 
| 71 | 
            -
                        key.globs_capture_separators = globs_capture_separators if key.is_a?(Route::Variable)
         | 
| 72 | 
            -
                        
         | 
| 73 | 
            -
                        if !key.is_a?(Route::Variable)
         | 
| 74 | 
            -
                          current_node.upgrade_lookup if key.is_a?(Regexp)
         | 
| 75 | 
            -
                          current_node.lookup[key] ||= Node.new(current_node, key)
         | 
| 76 | 
            -
                        elsif key.regex_matcher
         | 
| 77 | 
            -
                          current_node.upgrade_lookup
         | 
| 78 | 
            -
                          current_node.lookup[key.regex_matcher] ||= Node.new(current_node, key)
         | 
| 79 | 
            -
                        else
         | 
| 80 | 
            -
                          current_node.lookup[nil] ||= Node.new(current_node, key)
         | 
| 81 | 
            -
                        end  
         | 
| 82 | 
            -
                      end
         | 
| 83 | 
            -
                      current_node = target_node
         | 
| 84 | 
            -
                    end
         | 
| 85 | 
            -
                    current_node.terminates = path
         | 
| 58 | 
            +
                    set_path_with_destination(path)
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
                
         | 
| 62 | 
            +
                def delete(route)
         | 
| 63 | 
            +
                  route.paths.each do |path|
         | 
| 64 | 
            +
                    set_path_with_destination(path, nil)
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
                
         | 
| 68 | 
            +
                def unique_routes(node = self, routes = [])
         | 
| 69 | 
            +
                  routes << node.terminates.route if node.terminates
         | 
| 70 | 
            +
                  node.lookup.values.each do |v|
         | 
| 71 | 
            +
                    unique_routes(v, routes)
         | 
| 86 72 | 
             
                  end
         | 
| 87 | 
            -
                   | 
| 73 | 
            +
                  node.greedy_lookup.values.each do |v|
         | 
| 74 | 
            +
                    unique_routes(v, routes)
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                  routes.uniq!
         | 
| 77 | 
            +
                  routes
         | 
| 88 78 | 
             
                end
         | 
| 89 79 |  | 
| 90 | 
            -
                def find(usher, request, path, params = [])
         | 
| 80 | 
            +
                def find(usher, request, original_path, path, params = [], position = 0)
         | 
| 91 81 | 
             
                  if exclusive_type
         | 
| 92 82 | 
             
                    [lookup[request.send(exclusive_type)], lookup[nil]].each do |n|
         | 
| 93 | 
            -
                      if n && (ret = n.find(usher, request, path.dup, params.dup))
         | 
| 83 | 
            +
                      if n && (ret = n.find(usher, request, original_path, path.dup, params.dup, position))
         | 
| 94 84 | 
             
                        return ret
         | 
| 95 85 | 
             
                      end
         | 
| 96 86 | 
             
                    end
         | 
| 97 | 
            -
                  elsif path.size.zero?  | 
| 98 | 
            -
                     | 
| 87 | 
            +
                  elsif terminates? && (path.size.zero? || terminates.route.partial_match?)
         | 
| 88 | 
            +
                    if terminates.route.partial_match?
         | 
| 89 | 
            +
                      Response.new(terminates, params, original_path[position, original_path.size], original_path[0, position])
         | 
| 90 | 
            +
                    else
         | 
| 91 | 
            +
                      Response.new(terminates, params, nil, original_path)
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                  elsif !path.size.zero? && (greedy? && (match_with_result_output = greedy_lookup.match_with_result(whole_path = original_path[position, original_path.size])))
         | 
| 95 | 
            +
            				next_path, matched_part = match_with_result_output
         | 
| 96 | 
            +
                    position += matched_part.size
         | 
| 97 | 
            +
                    params << [next_path.value.name, whole_path.slice!(0, matched_part.size)]
         | 
| 98 | 
            +
                    next_path.find(usher, request, original_path, whole_path.size.zero? ? whole_path : usher.splitter.url_split(whole_path), params, position)
         | 
| 99 99 | 
             
                  elsif !path.size.zero? && (next_part = lookup[part = path.shift] || lookup[nil])
         | 
| 100 | 
            +
                    position += part.size
         | 
| 100 101 | 
             
                    case next_part.value
         | 
| 101 | 
            -
                    when Route::Variable
         | 
| 102 | 
            -
                       | 
| 103 | 
            -
                       | 
| 104 | 
            -
                         | 
| 105 | 
            -
             | 
| 106 | 
            -
                           | 
| 107 | 
            -
             | 
| 108 | 
            -
                            path.unshift(next_part.parent.value) | 
| 109 | 
            -
                             | 
| 110 | 
            -
                          elsif next_part.value.globs_capture_separators
         | 
| 111 | 
            -
                            params.last.last << part
         | 
| 112 | 
            -
                          elsif !usher.splitter.delimiter_chars.include?(part[0])
         | 
| 113 | 
            -
                            next_part.value.valid!(part)
         | 
| 114 | 
            -
                            params.last.last << part
         | 
| 115 | 
            -
                          end
         | 
| 116 | 
            -
                          if path.size.zero?
         | 
| 117 | 
            -
                            break
         | 
| 118 | 
            -
                          else
         | 
| 119 | 
            -
                            part = path.shift
         | 
| 102 | 
            +
                    when Route::Variable::Glob
         | 
| 103 | 
            +
                      params << [next_part.value.name, []] unless params.last && params.last.first == next_part.value.name
         | 
| 104 | 
            +
                      loop do
         | 
| 105 | 
            +
                        if (next_part.value.look_ahead === part || (!usher.delimiter_chars.include?(part[0]) && next_part.value.regex_matcher && !next_part.value.regex_matcher.match(part)))
         | 
| 106 | 
            +
                          path.unshift(part)
         | 
| 107 | 
            +
                          position -= part.size
         | 
| 108 | 
            +
                          if usher.delimiter_chars.include?(next_part.parent.value[0])
         | 
| 109 | 
            +
                            path.unshift(next_part.parent.value)
         | 
| 110 | 
            +
                            position -= next_part.parent.value.size
         | 
| 120 111 | 
             
                          end
         | 
| 112 | 
            +
                          break
         | 
| 113 | 
            +
                        elsif !usher.delimiter_chars.include?(part[0])
         | 
| 114 | 
            +
                          next_part.value.valid!(part)
         | 
| 115 | 
            +
                          params.last.last << part
         | 
| 121 116 | 
             
                        end
         | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
                         | 
| 125 | 
            -
             | 
| 126 | 
            -
                        until (var.look_ahead === path.first) || path.empty?
         | 
| 127 | 
            -
                          params.last.last << path.shift 
         | 
| 117 | 
            +
                        if path.size.zero?
         | 
| 118 | 
            +
                          break
         | 
| 119 | 
            +
                        else
         | 
| 120 | 
            +
                          part = path.shift
         | 
| 128 121 | 
             
                        end
         | 
| 129 122 | 
             
                      end
         | 
| 123 | 
            +
                    when Route::Variable::Single
         | 
| 124 | 
            +
                      var = next_part.value
         | 
| 125 | 
            +
                      var.valid!(part)
         | 
| 126 | 
            +
                      params << [var.name, part]
         | 
| 127 | 
            +
                      until (var.look_ahead === path.first) || path.empty?
         | 
| 128 | 
            +
                        next_path_part = path.shift
         | 
| 129 | 
            +
                        position += next_path_part.size
         | 
| 130 | 
            +
                        params.last.last << next_path_part
         | 
| 131 | 
            +
                      end
         | 
| 130 132 | 
             
                    end
         | 
| 131 | 
            -
                    next_part.find(usher, request, path, params)
         | 
| 133 | 
            +
                    next_part.find(usher, request, original_path, path, params, position)
         | 
| 132 134 | 
             
                  else
         | 
| 133 135 | 
             
                    nil
         | 
| 134 136 | 
             
                  end
         | 
| 135 137 | 
             
                end
         | 
| 136 138 |  | 
| 139 | 
            +
                private
         | 
| 140 | 
            +
                def set_path_with_destination(path, destination = path)
         | 
| 141 | 
            +
                  parts = path.parts.dup
         | 
| 142 | 
            +
                  request_methods.each do |type|
         | 
| 143 | 
            +
                    parts.push(Route::RequestMethod.new(type, path.route.conditions[type])) if path.route.conditions && path.route.conditions.key?(type)
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
                  
         | 
| 146 | 
            +
                  current_node = self
         | 
| 147 | 
            +
                  until parts.size.zero?
         | 
| 148 | 
            +
                    key = parts.shift
         | 
| 149 | 
            +
                    target_node = case key
         | 
| 150 | 
            +
                    when Route::RequestMethod
         | 
| 151 | 
            +
                      current_node.upgrade_lookup if key.value.is_a?(Regexp)
         | 
| 152 | 
            +
                      if current_node.exclusive_type == key.type
         | 
| 153 | 
            +
                        current_node.lookup[key.value] ||= Node.new(current_node, key)
         | 
| 154 | 
            +
                      elsif current_node.lookup.empty?
         | 
| 155 | 
            +
                        current_node.exclusive_type = key.type
         | 
| 156 | 
            +
                        current_node.lookup[key.value] ||= Node.new(current_node, key)
         | 
| 157 | 
            +
                      else
         | 
| 158 | 
            +
                        parts.unshift(key)
         | 
| 159 | 
            +
                        current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
         | 
| 160 | 
            +
                      end
         | 
| 161 | 
            +
                    when Route::Variable
         | 
| 162 | 
            +
                      upgrade_method, lookup_method = case key
         | 
| 163 | 
            +
                      when Route::Variable::Greedy
         | 
| 164 | 
            +
                        [:upgrade_greedy_lookup, :greedy_lookup]
         | 
| 165 | 
            +
                      else
         | 
| 166 | 
            +
                        [:upgrade_lookup, :lookup]
         | 
| 167 | 
            +
                      end
         | 
| 168 | 
            +
                      
         | 
| 169 | 
            +
                      if key.regex_matcher
         | 
| 170 | 
            +
                        current_node.send(upgrade_method)
         | 
| 171 | 
            +
                        current_node.send(lookup_method)[key.regex_matcher] ||= Node.new(current_node, key)
         | 
| 172 | 
            +
                      else
         | 
| 173 | 
            +
                        current_node.send(lookup_method)[nil] ||= Node.new(current_node, key)
         | 
| 174 | 
            +
                      end  
         | 
| 175 | 
            +
                    else
         | 
| 176 | 
            +
                      current_node.upgrade_lookup if key.is_a?(Regexp)
         | 
| 177 | 
            +
                      current_node.lookup[key] ||= Node.new(current_node, key)
         | 
| 178 | 
            +
                    end
         | 
| 179 | 
            +
                    current_node = target_node
         | 
| 180 | 
            +
                  end
         | 
| 181 | 
            +
                  current_node.terminates = destination
         | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
                
         | 
| 184 | 
            +
                
         | 
| 137 185 | 
             
              end
         | 
| 138 186 | 
             
            end
         | 
    
        data/lib/usher/route.rb
    CHANGED
    
    | @@ -1,20 +1,20 @@ | |
| 1 1 | 
             
            require File.join(File.dirname(__FILE__), 'route', 'path')
         | 
| 2 | 
            +
            require File.join(File.dirname(__FILE__), 'route', 'util')
         | 
| 2 3 | 
             
            require File.join(File.dirname(__FILE__), 'route', 'variable')
         | 
| 3 4 | 
             
            require File.join(File.dirname(__FILE__), 'route', 'request_method')
         | 
| 4 5 |  | 
| 5 6 | 
             
            class Usher
         | 
| 6 7 | 
             
              class Route
         | 
| 7 | 
            -
                attr_reader | 
| 8 | 
            +
                attr_reader   :paths, :requirements, :conditions,
         | 
| 9 | 
            +
                              :destination, :named, :generate_with,
         | 
| 10 | 
            +
                              :default_values, :match_partially
         | 
| 11 | 
            +
                attr_accessor :parent_route
         | 
| 8 12 |  | 
| 9 13 | 
             
                GenerateWith = Struct.new(:scheme, :port, :host)
         | 
| 10 14 |  | 
| 11 | 
            -
                def initialize( | 
| 12 | 
            -
                  @ | 
| 13 | 
            -
                  @router = router
         | 
| 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)}
         | 
| 15 | 
            +
                def initialize(parsed_paths, router, conditions, requirements, default_values, generate_with, match_partially)            
         | 
| 16 | 
            +
                  @paths = parsed_paths.collect {|path| Path.new(self, path)}
         | 
| 17 | 
            +
                  @router, @requirements, @conditions, @default_values, @match_partially = router, requirements, conditions, default_values, match_partially
         | 
| 18 18 | 
             
                  @generate_with = GenerateWith.new(generate_with[:scheme], generate_with[:port], generate_with[:host]) if generate_with
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| @@ -26,11 +26,27 @@ class Usher | |
| 26 26 | 
             
                  @grapher
         | 
| 27 27 | 
             
                end
         | 
| 28 28 |  | 
| 29 | 
            +
                def dup
         | 
| 30 | 
            +
                  result = super
         | 
| 31 | 
            +
                  result.grapher = nil
         | 
| 32 | 
            +
                  result
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 29 35 | 
             
                def find_matching_path(params)
         | 
| 30 | 
            -
                   | 
| 36 | 
            +
                  if params.nil? || params.empty?
         | 
| 37 | 
            +
                    matching_path = @paths.first
         | 
| 38 | 
            +
                  else
         | 
| 39 | 
            +
                    matching_path = @paths.size == 1 ? @paths.first : grapher.find_matching_path(params)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  
         | 
| 42 | 
            +
                  if parent_route
         | 
| 43 | 
            +
                    matching_path = parent_route.find_matching_path(params).merge(matching_path)
         | 
| 44 | 
            +
                    matching_path.route = self
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                  
         | 
| 47 | 
            +
                  matching_path
         | 
| 31 48 | 
             
                end
         | 
| 32 49 |  | 
| 33 | 
            -
                
         | 
| 34 50 | 
             
                # Sets +options+ on a route. Returns +self+.
         | 
| 35 51 | 
             
                #   
         | 
| 36 52 | 
             
                #   Request = Struct.new(:path)
         | 
| @@ -39,7 +55,13 @@ class Usher | |
| 39 55 | 
             
                #   route.to(:controller => 'testing', :action => 'index')
         | 
| 40 56 | 
             
                #   set.recognize(Request.new('/test')).first.params => {:controller => 'testing', :action => 'index'}
         | 
| 41 57 | 
             
                def to(options = nil, &block)
         | 
| 42 | 
            -
                   | 
| 58 | 
            +
                  raise "cannot set destintaion as block and argument" if block_given? && options
         | 
| 59 | 
            +
                  @destination = if block_given?
         | 
| 60 | 
            +
                    block
         | 
| 61 | 
            +
                  else
         | 
| 62 | 
            +
                    options.parent_route = self if options.respond_to?(:parent_route=)
         | 
| 63 | 
            +
                    options
         | 
| 64 | 
            +
                  end
         | 
| 43 65 | 
             
                  self
         | 
| 44 66 | 
             
                end
         | 
| 45 67 |  | 
| @@ -53,6 +75,18 @@ class Usher | |
| 53 75 | 
             
                  @router.name(name, self)
         | 
| 54 76 | 
             
                  self
         | 
| 55 77 | 
             
                end
         | 
| 78 | 
            +
                
         | 
| 79 | 
            +
                def match_partially!
         | 
| 80 | 
            +
                  @match_partially = true
         | 
| 81 | 
            +
                  self
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
                
         | 
| 84 | 
            +
                def partial_match?
         | 
| 85 | 
            +
                  @match_partially
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
                
         | 
| 88 | 
            +
                private
         | 
| 89 | 
            +
                attr_writer :grapher
         | 
| 56 90 |  | 
| 57 91 | 
             
              end
         | 
| 58 92 | 
             
            end
         |