Skip to content

Commit

Permalink
The very first time a Whois::Answer method/property question method i…
Browse files Browse the repository at this point in the history
…s invoked, the corresponding method is called instead of the question one.
  • Loading branch information
weppos committed Dec 27, 2010
1 parent 673d144 commit f26d6f0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 27 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rdoc
Expand Up @@ -32,6 +32,9 @@

* FIXED: Fixed a bug which prevents a client to be created with nil timeout.

* FIXED: The very first time a Whois::Answer method/property question method is invoked,
the corresponding method is called instead of the question one.


== Release 1.6.6

Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -90,8 +90,8 @@ Rake::TestTask.new do |t|
t.verbose = true
end

namespace :test do

namespace :test do
RUBIES = %w( 1.8.7-p302 1.9.2-p0 jruby-1.5.6 ree-1.8.7-2010.02 )

desc "Run tests for all rubies"
Expand Down
64 changes: 38 additions & 26 deletions lib/whois/answer.rb
Expand Up @@ -210,40 +210,52 @@ def throttle?
end


protected
private

# @api internal
def self.define_property_method(method)
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
if property_supported?(:#{method})
parser.#{method}(*args, &block)
else
nil
end
end
RUBY
end

# @api internal
def self.define_method_method(method)
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
if parser.respond_to?(:#{method})
parser.#{method}(*args, &block)
end
end
RUBY
end

# @api internal
def self.define_question_method(method)
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}?
!#{method}.nil?
end
RUBY
end

# Delegates all method calls to the internal parser.
def method_missing(method, *args, &block)
if Parser::PROPERTIES.include?(method)
self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
if property_supported?(:#{method})
parser.#{method}(*args, &block)
else
nil
end
end
RUBY
self.class.define_property_method(method)
send(method, *args, &block)

elsif Parser::METHODS.include?(method)
self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args, &block)
if parser.respond_to?(:#{method})
parser.#{method}(*args, &block)
end
end
RUBY
self.class.define_method_method(method)
send(method, *args, &block)

elsif method.to_s =~ /([a-z_]+)\?/ and (Parser::PROPERTIES + Parser::METHODS).include?($1.to_sym)
self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{$1}?
!#{$1}.nil?
end
RUBY
send($1)

self.class.define_question_method($1)
send(method)
else
super
end
Expand Down
54 changes: 54 additions & 0 deletions spec/whois/answer_spec.rb
Expand Up @@ -197,4 +197,58 @@
end
end


describe "method_missing" do
context "when a parser property"
context "when a parser method"

context "when a parser question method/property" do
it "calls the corresponding no-question method" do
answer = klass.new(nil, [])
answer.expects(:status)
answer.status?
end

it "returns true if the property is not nil" do
answer = klass.new(nil, [])
answer.expects(:status).returns("available")
answer.status?.should == true
end

it "returns false if the property is nil" do
answer = klass.new(nil, [])
answer.expects(:status).returns(nil)
answer.status?.should == false
end
end

context "when a simple method" do
it "passes the request to super" do
Object.class_eval do
def happy; "yes"; end
end

answer = klass.new(nil, [])
lambda do
answer.happy.should == "yes"
end.should_not raise_error
lambda do
answer.sad
end.should raise_error(NoMethodError)
end

it "doesn't catch all methods" do
lambda do
klass.new(nil, []).i_am_not_defined
end.should raise_error(NoMethodError)
end

it "doesn't catch all question methods" do
lambda do
klass.new(nil, []).i_am_not_defined?
end.should raise_error(NoMethodError)
end
end
end

end

0 comments on commit f26d6f0

Please sign in to comment.