Skip to content

Commit

Permalink
get cloning support working again
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Hull committed Mar 22, 2011
1 parent bd79060 commit 218995f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 39 deletions.
1 change: 0 additions & 1 deletion README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
* Partial matches.
* Supports interstitial variables (e.g. /my-:variable-brings.all.the.boys/yard) and unnamed variable /one/:/two
* Very fast and small code base (~1,000 loc).
* Sinatra compatibility.

== Usage

Expand Down
4 changes: 2 additions & 2 deletions http_router.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Gem::Specification.new do |s|
s.version = HttpRouter::VERSION
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Joshua Hull"]
s.summary = "A kick-ass HTTP router for use in Rack & Sinatra"
s.description = "This library allows you to recognize and build URLs in a Rack application. As well it contains an interface for use within Sinatra."
s.summary = "A kick-ass HTTP router for use in Rack"
s.description = "This library allows you to recognize and build URLs in a Rack application."
s.email = %q{joshbuddy@gmail.com}
s.extra_rdoc_files = ['README.rdoc']
s.files = `git ls-files`.split("\n")
Expand Down
30 changes: 26 additions & 4 deletions lib/http_router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
class HttpRouter

attr_reader :root, :routes, :known_methods, :named_routes
attr_accessor :default_app
attr_accessor :default_app, :url_mount

UngeneratableRouteException = Class.new(RuntimeError)
InvalidRouteException = Class.new(RuntimeError)
MissingParameterException = Class.new(RuntimeError)

def initialize(opts = nil, &blk)
def initialize(options = nil, &blk)
reset!
@ignore_trailing_slash = opts && opts.key?(:ignore_trailing_slash) ? opts[:ignore_trailing_slash] : true
@options = options
@default_app = default_app || options && options[:default_app] || proc{|env| ::Rack::Response.new("Not Found", 404).finish }
@ignore_trailing_slash = options && options.key?(:ignore_trailing_slash) ? options[:ignore_trailing_slash] : true
instance_eval(&blk) if blk
end

Expand All @@ -30,11 +32,15 @@ def add(path, opts = {}, &app)
else
Route.new(self, path, opts)
end
@routes << route
add_route(route)
route.to(app) if app
route
end

def add_route(route)
@routes << route
end

def add_with_request_method(path, method, opts = {}, &app)
route = add(path, opts).send(method.to_sym)
route.to(app) if app
Expand Down Expand Up @@ -104,4 +110,20 @@ def append_querystring(uri, params)
end
uri
end

# Creates a deep-copy of the router.
def clone(klass = self.class)
cloned_router = klass.new(@options)
@routes.each do |route|
new_route = route.clone(cloned_router)
cloned_router.add_route(new_route)
new_route.name(route.named) if route.named
begin
new_route.to route.dest.clone
rescue
new_route.to route.dest
end
end
cloned_router
end
end
4 changes: 2 additions & 2 deletions lib/http_router/regex_route.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class HttpRouter
class RegexRoute < Route
def initialize(router, path, opts = {})
@router, @path, @opts = router, path, opts
@router, @original_path, @opts = router, path, opts
end

def compile
add_non_path_to_tree(@router.root.add_free_match(path), path, [])
add_non_path_to_tree(@router.root.add_free_match(@original_path), path, [])
@compiled = true
end

Expand Down
8 changes: 6 additions & 2 deletions lib/http_router/route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ def url(*args)
@router.append_querystring(result, extra_params)
end

def clone(new_router)
Route.new(new_router, @original_path.dup, as_options)
end

def url_with_params(*args)
options = args.last.is_a?(Hash) ? args.pop : nil
options = options.nil? ? default_values.dup : default_values.merge(options) if default_values
Expand All @@ -137,8 +141,8 @@ def url_with_params(*args)
end
raise UngeneratableRouteException unless path
result, params = path.url(args, options)
#mount_point = router.url_mount && router.url_mount.url(options)
#mount_point ? [File.join(mount_point, result), params] : [result, params]
mount_point = router.url_mount && router.url_mount.url(options)
mount_point ? [File.join(mount_point, result), params] : [result, params]
[result, params]
end

Expand Down
50 changes: 22 additions & 28 deletions test/test_misc.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
class TestMisc < MiniTest::Unit::TestCase
#def test_exceptions
# assert_raises(HttpRouter::AmbiguousRouteException) {HttpRouter.new.add("/:var1(/:var2)(/:var3)").compile}
# assert_raises(HttpRouter::AmbiguousVariableException) {HttpRouter.new.add("/:var1(/:var1)(/:var1)").compile}
# assert_raises(HttpRouter::UnsupportedRequestConditionError) {HttpRouter.new.add("/").condition(:flibberty => 'gibet').compile}
#end
#
#def test_cloning
# r1 = HttpRouter.new {
# add('/test').name(:test_route).to :test
# }
# r2 = r1.clone
#
# r2.add('/test2').name(:test).to(:test2)
# assert_equal 2, r2.routes.size
#
# assert r1.recognize(Rack::Request.new(Rack::MockRequest.env_for('/test2'))).nil?
# assert !r2.recognize(Rack::Request.new(Rack::MockRequest.env_for('/test2'))).nil?
# assert_equal r1.routes.first, r1.named_routes[:test_route]
# assert_equal r2.routes.first, r2.named_routes[:test_route]
#
# r1.add('/another').name(:test).to(:test2)
#
# assert_equal r1.routes.size, r2.routes.size
# assert_equal '/another', r1.url(:test)
# assert_equal '/test2', r2.url(:test)
# assert_equal :test, r1.routes.first.dest
# assert_equal :test, r2.routes.first.dest
#end
def test_cloning
r1 = HttpRouter.new {
add('/test').name(:test_route).to :test
}
r2 = r1.clone

r2.add('/test2').name(:test).to(:test2)
assert_equal 2, r2.routes.size

assert_equal 404, r1.recognize(Rack::Request.new(Rack::MockRequest.env_for('/test2'))).first
assert r2.recognize(Rack::Request.new(Rack::MockRequest.env_for('/test2')))
assert_equal r1.routes.first, r1.named_routes[:test_route]
assert_equal r2.routes.first, r2.named_routes[:test_route]

r1.add('/another').name(:test).to(:test2)

assert_equal r1.routes.size, r2.routes.size
assert_equal '/another', r1.url(:test)
assert_equal '/test2', r2.url(:test)
assert_equal :test, r1.routes.first.dest
assert_equal :test, r2.routes.first.dest
end
end

0 comments on commit 218995f

Please sign in to comment.