diff --git a/lib/http/cookie_jar.rb b/lib/http/cookie_jar.rb
index 9e0851f..4e0864e 100644
--- a/lib/http/cookie_jar.rb
+++ b/lib/http/cookie_jar.rb
@@ -29,16 +29,38 @@ class HTTP::CookieJar
attr_reader :store
+ def get_impl(base, value, *args)
+ case value
+ when base
+ value
+ when Symbol
+ begin
+ base.implementation(value).new(*args)
+ rescue IndexError => e
+ raise ArgumentError, e.message
+ end
+ when Class
+ if base >= value
+ value.new(*args)
+ else
+ raise TypeError, 'not a subclass of %s: %s' % [base, value]
+ end
+ else
+ raise TypeError, 'invalid object: %s' % value.inspect
+ end
+ end
+ private :get_impl
+
# Generates a new cookie jar.
#
# Available option keywords are as below:
#
# :store
# : The store class that backs this jar. (default: `:hash`)
- # A symbol or an instance of a store class is accepted. Symbols are
- # mapped to store classes, like `:hash` to
- # HTTP::CookieJar::HashStore and `:mozilla` to
- # HTTP::CookieJar::MozillaStore.
+ # A symbol addressing a store class, a store class, or an instance
+ # of a store class is accepted. Symbols are mapped to store
+ # classes, like `:hash` to HTTP::CookieJar::HashStore and `:mozilla`
+ # to HTTP::CookieJar::MozillaStore.
#
# Any options given are passed through to the initializer of the
# specified store class. For example, the `:mozilla`
@@ -49,14 +71,7 @@ class HTTP::CookieJar
:store => :hash,
}
opthash.update(options) if options
- case store = opthash[:store]
- when Symbol
- @store = AbstractStore.implementation(store).new(opthash)
- when AbstractStore
- @store = store
- else
- raise TypeError, 'wrong object given as cookie store: %s' % store.inspect
- end
+ @store = get_impl(AbstractStore, opthash[:store], opthash)
end
# The copy constructor. Not all backend store classes support cloning.
@@ -191,6 +206,10 @@ class HTTP::CookieJar
#
# * `:format`
#
+ # Specifies the format for saving. A saver class, a symbol
+ # addressing a saver class, or a pre-generated instance of a
+ # saver class is accepted.
+ #
#
# - :yaml
# - YAML structure (default)
@@ -221,20 +240,20 @@ class HTTP::CookieJar
when Symbol
opthash[:format] = options
else
- opthash.update(options) if options
+ if hash = Hash.try_convert(options)
+ opthash.update(hash)
+ end
end
when 2
opthash[:format], options = options
- opthash.update(options) if options
+ if hash = Hash.try_convert(options)
+ opthash.update(hash)
+ end
else
raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
end
- begin
- saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
- rescue IndexError => e
- raise ArgumentError, e.message
- end
+ saver = get_impl(AbstractSaver, opthash[:format], opthash)
if writable.respond_to?(:write)
saver.save(writable, self)
@@ -259,6 +278,10 @@ class HTTP::CookieJar
#
# * `:format`
#
+ # Specifies the format for loading. A saver class, a symbol
+ # addressing a saver class, or a pre-generated instance of a
+ # saver class is accepted.
+ #
#
# - :yaml
# - YAML structure (default)
@@ -280,20 +303,20 @@ class HTTP::CookieJar
when Symbol
opthash[:format] = options
else
- opthash.update(options) if options
+ if hash = Hash.try_convert(options)
+ opthash.update(hash)
+ end
end
when 2
opthash[:format], options = options
- opthash.update(options) if options
+ if hash = Hash.try_convert(options)
+ opthash.update(hash)
+ end
else
raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
end
- begin
- saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
- rescue IndexError => e
- raise ArgumentError, e.message
- end
+ saver = get_impl(AbstractSaver, opthash[:format], opthash)
if readable.respond_to?(:write)
saver.load(readable, self)
diff --git a/test/test_http_cookie_jar.rb b/test/test_http_cookie_jar.rb
index 9ef6f02..e7539a8 100644
--- a/test/test_http_cookie_jar.rb
+++ b/test/test_http_cookie_jar.rb
@@ -355,14 +355,6 @@ module TestHTTPCookieJar
assert_equal(0, @jar.cookies(url).length)
end
- def test_save_nonexistent_saver
- Dir.mktmpdir { |dir|
- assert_raises(ArgumentError) {
- @jar.save(File.join(dir, "file"), :nonexistent)
- }
- }
- end
-
def test_save_cookies_yaml
url = URI 'http://rubyforge.org/'
@@ -403,12 +395,18 @@ module TestHTTPCookieJar
@jar.save(filename, :format => :cookiestxt)
@jar.save(filename, :cookiestxt, :session => true)
@jar.save(filename, :cookiestxt)
+ @jar.save(filename, HTTP::CookieJar::CookiestxtSaver)
+ @jar.save(filename, HTTP::CookieJar::CookiestxtSaver.new)
@jar.save(filename, :session => true)
@jar.save(filename)
+
assert_raises(ArgumentError) {
@jar.save()
}
assert_raises(ArgumentError) {
+ @jar.save(filename, :nonexistent)
+ }
+ assert_raises(TypeError) {
@jar.save(filename, { :format => :cookiestxt }, { :session => true })
}
assert_raises(ArgumentError) {
@@ -418,6 +416,8 @@ module TestHTTPCookieJar
@jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
@jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
@jar.load(filename, :format => :cookiestxt)
+ @jar.load(filename, HTTP::CookieJar::CookiestxtSaver)
+ @jar.load(filename, HTTP::CookieJar::CookiestxtSaver.new)
@jar.load(filename, :cookiestxt, :linefeed => "\n")
@jar.load(filename, :cookiestxt)
@jar.load(filename, :linefeed => "\n")
@@ -426,6 +426,9 @@ module TestHTTPCookieJar
@jar.load()
}
assert_raises(ArgumentError) {
+ @jar.load(filename, :nonexistent)
+ }
+ assert_raises(TypeError) {
@jar.load(filename, { :format => :cookiestxt }, { :linefeed => "\n" })
}
assert_raises(ArgumentError) {
@@ -850,16 +853,14 @@ module TestHTTPCookieJar
jar = HTTP::CookieJar.new(:store => :hash)
assert_instance_of HTTP::CookieJar::HashStore, jar.store
- assert_raises(IndexError) {
+ assert_raises(ArgumentError) {
jar = HTTP::CookieJar.new(:store => :nonexistent)
}
jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore.new)
assert_instance_of HTTP::CookieJar::HashStore, jar.store
- assert_raises(TypeError) {
- jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
- }
+ jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
end
def test_clone