From 40aba546188184d7a916b9a7c0f7a4402764ae14 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Sun, 21 Apr 2013 20:35:17 +0900 Subject: [PATCH] Accept a class object where a symbol addressing a class is accepted. Convert IndexError to ArgumentError, and ArgumentError to TypeError as appropriate. --- lib/http/cookie_jar.rb | 75 +++++++++++++++++++++++------------- test/test_http_cookie_jar.rb | 25 ++++++------ 2 files changed, 62 insertions(+), 38 deletions(-) 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