Permalink
Browse files

Added ability to check whether a property is supported via answer.sup…

…ported? or parser.supported?
  • Loading branch information...
1 parent 578b5fc commit 4386fd4390f6fddf53ed67d3654f64053787a0ee @weppos committed Sep 28, 2009
View
@@ -1,6 +1,11 @@
= Changelog
+== next mini
+
+* ADDED: ability to check whether a property is supported via answer.supported? or parser.supported?
+
+
== Release 0.8.0
* FIXED: Server definition with :format doesn't use the Formatted adapter (closes #305)
View
@@ -63,7 +63,7 @@ def self.whois(qstring)
def self.available?(qstring)
query(qstring).available?
rescue ParserNotFound => e
- $stderr.puts "This method is not available for this kind of object.\n" +
+ $stderr.puts "This method is not supported for this kind of object.\n" +
"Use Whois.query('#{qstring}') instead."
nil
end
@@ -87,7 +87,7 @@ def self.available?(qstring)
def self.registered?(qstring)
query(qstring).registered?
rescue ParserNotFound => e
- $stderr.puts "This method is not available for this kind of object.\n" +
+ $stderr.puts "This method is not supported for this kind of object.\n" +
"Use Whois.query('#{qstring}') instead."
nil
end
View
@@ -109,6 +109,13 @@ def parser
@parser ||= Parser.new(self)
end
+ # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
+ # is supported by any available parser for this answer.
+ # See also <tt>Whois::Answer::Parser.supported?</tt>.
+ def supported?(property)
+ parser.supported?(property)
+ end
+
protected
@@ -46,10 +46,20 @@ def initialize(answer)
@answer = answer
end
+ # Returns an array with all host-specific parsers initialized for the parts
+ # contained into this parser.
+ # The array is lazy-initialized.
def parsers
@parsers ||= init_parsers
end
+ # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
+ # is supported by any available parser.
+ # See also <tt>Whois::Answer::Parser::Base.supported?</tt>.
+ def supported?(property)
+ parsers.any? { |parser| parser.supported?(property) }
+ end
+
protected
@@ -70,12 +80,21 @@ def method_missing(method, *args, &block)
# Loops through all answer parts, for each parts tries to guess
# the appropriate Whois::Answer::Parser::<parser> if it exists
# and returns the final array of server-specific parsers.
+ #
+ # Parsers are initialized in reverse order for performance reason.
+ # See also <tt>select_parser</tt>.
+ #
+ # parser.parts
+ # # => [whois.foo.com, whois.bar.com]
+ # parser.parsers
+ # # => [parser(whois.bar.com), parser(whois.foo.com)]
+ #
def init_parsers
- answer.parts.map { |part| self.class.parser_for(part) }
+ answer.parts.reverse.map { |part| self.class.parser_for(part) }
end
def select_parser(method)
- parsers.reverse.each do |parser|
+ parsers.each do |parser|
return parser if parser.method_registered?(method)
end
nil
@@ -50,6 +50,43 @@ def initialize(part)
end
end
+ # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
+ # is supported by current parser.
+ #
+ # parser.supported? :disclaimer
+ # # => false
+ #
+ # parser.register_method(:disclaimer) {}
+ # parser.supported? :disclaimer
+ # # => true
+ #
+ # This method is different than <tt>respond_to?</tt>.
+ # While <tt>respond_to?</tt> always returns true for any registrable property,
+ # including those not effectively implemented,
+ # this method only returns <tt>true</tt> if the parser implements <tt>property</tt>.
+ # Also, <tt>supported?</tt> returns <tt>false</tt> if <tt>property</tt> exists as a method
+ # but it's not a property method.
+ #
+ # parser.respond_to?(:disclaimer)
+ # # => true
+ # parser.supported?(:disclaimer)
+ # # => false
+ #
+ # parser.register_method(:disclaimer) {}
+ # parser.respond_to?(:disclaimer)
+ # # => true
+ # parser.supported?(:disclaimer)
+ # # => true
+ #
+ # parser.respond_to?(:contact)
+ # # => true
+ # parser.supported?(:contact)
+ # # => false
+ #
+ def supported?(property)
+ method_registered?(property.to_s.to_sym)
+ end
+
# This is an internal method primaly used as a common access point
# to get the content to be parsed as a string.
@@ -19,9 +19,29 @@ def test_initialize_should_require_part
end
+ def test_supported?
+ klass = Class.new(@klass) do
+ register_method(:disclaimer) {}
+ end
+ assert klass.new(@part).supported?(:disclaimer)
+ assert klass.new(@part).respond_to?(:disclaimer)
+
+ klass = Class.new(@klass) do
+ end
+ assert !klass.new(@part).supported?(:disclaimer)
+ assert klass.new(@part).respond_to?(:disclaimer)
+ end
+
+ def test_supported_should_return_false_unless_registrable_method
+ parser = @klass.new(@part)
+ assert !parser.supported?(:content)
+ assert parser.respond_to?(:content)
+ end
+
+
def test_content
parser = @klass.new(@part)
assert_equal @part.response, parser.content
end
-
+
end
@@ -20,28 +20,61 @@ def test_initialize_should_require_answer
end
- def test_parsers_should_not_create_parser_instance_with_zero_parts
+ def test_parsers_with_zero_parts
answer = Whois::Answer.new(nil, [])
parser = @klass.new(answer)
assert_equal 0, parser.parsers.length
assert_equal [], parser.parsers
end
- def test_parsers_should_create_parser_instance_with_supported_server
+ def test_parsers_with_one_part_supported
answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "whois.nic.it")])
parser = @klass.new(answer)
assert_equal 1, parser.parsers.length
assert_instance_of Whois::Answer::Parser::WhoisNicIt, parser.parsers.first
end
- def test_parsers_should_create_blank_parser_instance_with_not_supported_server
+ def test_parsers_with_one_part_unsupported
answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "invalid.nic.it")])
parser = @klass.new(answer)
assert_equal 1, parser.parsers.length
assert_instance_of Whois::Answer::Parser::Blank, parser.parsers.first
end
-
+ def test_parsers_with_two_parts
+ answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "whois.crsnic.net"), Whois::Answer::Part.new(nil, "whois.nic.it")])
+ parser = @klass.new(answer)
+ assert_equal 2, parser.parsers.length
+ assert_instance_of Whois::Answer::Parser::WhoisNicIt, parser.parsers.first
+ assert_instance_of Whois::Answer::Parser::WhoisCrsnicNet, parser.parsers.last
+ end
+
+
+ def test_supported_with_zero_parts
+ answer = Whois::Answer.new(nil, [])
+ parser = @klass.new(answer)
+ assert !parser.supported?(:disclaimer)
+ end
+
+ def test_supported_with_one_part_supported
+ answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "whois.nic.it")])
+ parser = @klass.new(answer)
+ assert parser.supported?(:disclaimer)
+ end
+
+ def test_supported_with_one_part_unsupported
+ answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "invalid.nic.it")])
+ parser = @klass.new(answer)
+ assert !parser.supported?(:disclaimer)
+ end
+
+ def test_supported_with_two_parts
+ answer = Whois::Answer.new(nil, [Whois::Answer::Part.new(nil, "whois.crsnic.net"), Whois::Answer::Part.new(nil, "whois.nic.it")])
+ parser = @klass.new(answer)
+ assert parser.supported?(:disclaimer)
+ end
+
+
(Whois::Answer::Parser.registrable_methods - [:referral_url, :referral_whois]).each do |method|
define_method "test_should_delegate_#{method}_to_parsers_first_parser_if_supported" do
answer = Whois::Answer.new(nil, [Whois::Answer::Part.new("", "whois.nic.it")])
View
@@ -79,14 +79,19 @@ def test_match?
def test_parser
answer = @klass.new(nil, [Whois::Answer::Part.new("", "whois.nic.it")])
- assert_instance_of Whois::Answer::Parser,
- answer.parser
+ assert_instance_of Whois::Answer::Parser, answer.parser
answer = @klass.new(nil, [])
- assert_instance_of Whois::Answer::Parser,
- answer.parser
+ assert_instance_of Whois::Answer::Parser, answer.parser
end
+ def test_supported?
+ answer = @klass.new(nil, [])
+ answer.parser.expects(:supported?).with(:disclaimer).returns(:value)
+ assert_equal :value, answer.supported?(:disclaimer)
+ end
+
+
Whois::Answer::Parser.registrable_methods.each do |method|
define_method "test_should_delegate_#{method}_to_parser" do
answer = @klass.new(nil, [Whois::Answer::Part.new("", "whois.nic.it")])

0 comments on commit 4386fd4

Please sign in to comment.