Skip to content
This repository
Browse code

Converted #changed? and #unchanged? properties to methods and normali…

…zed their behavior.
  • Loading branch information...
commit 7ba3de955f642b275ebb7f5554c51f76b030f9e9 1 parent 387ebe4
Simone Carletti authored

Showing 28 changed files with 499 additions and 496 deletions. Show diff stats Hide diff stats

  1. +5 1 CHANGELOG.rdoc
  2. +68 56 lib/whois/answer.rb
  3. +64 4 lib/whois/answer/parser.rb
  4. +69 26 lib/whois/answer/parser/base.rb
  5. +0 24 lib/whois/answer/parser/example.rb
  6. +0 12 lib/whois/answer/parser/whois.co.pl.rb
  7. +0 12 lib/whois/answer/parser/whois.coza.net.za.rb
  8. +0 12 lib/whois/answer/parser/whois.nic.ac.rb
  9. +0 12 lib/whois/answer/parser/whois.nic.io.rb
  10. +0 10 lib/whois/answer/parser/whois.nic.it.rb
  11. +0 12 lib/whois/answer/parser/whois.nic.sh.rb
  12. +0 12 lib/whois/answer/parser/whois.nic.sn.rb
  13. +0 12 lib/whois/answer/parser/whois.nic.tm.rb
  14. +0 12 lib/whois/answer/parser/whois.org.za.rb
  15. +0 11 lib/whois/answer/parser/whois.publicinterestregistry.net.rb
  16. +0 12 lib/whois/answer/parser/whois.tonic.to.rb
  17. +10 0 spec/spec_helper.rb
  18. +156 0 spec/whois/answer/parser/base_spec.rb
  19. +65 0 spec/whois/answer/parser_spec.rb
  20. +62 0 spec/whois/answer_spec.rb
  21. +0 84 test/whois/answer/parser/base_test.rb
  22. +0 31 test/whois/answer/parser/whois.nic.ac_test.rb
  23. +0 31 test/whois/answer/parser/whois.nic.io_test.rb
  24. +0 21 test/whois/answer/parser/whois.nic.it_test.rb
  25. +0 31 test/whois/answer/parser/whois.nic.sh_test.rb
  26. +0 21 test/whois/answer/parser/whois.nic.sn_test.rb
  27. +0 31 test/whois/answer/parser/whois.nic.tm_test.rb
  28. +0 6 test/whois/answer_test.rb
6 CHANGELOG.rdoc
Source Rendered
@@ -13,12 +13,16 @@
13 13
14 14 * FIXED: whois.dns.pt must support :reserved status.
15 15
  16 +* FIXED: Converted #changed? and #unchanged? properties to methods
  17 + and normalized their behavior.
  18 +
16 19
17 20 == Release 1.6.4
18 21
19 22 * FIXED: With some .pl domains, whois.dns.pl parser returns invalid values for nameservers.
20 23
21   -* FIXED: The whois.pnina.ps server injects a NODNS.NS string when a nameserver is not set. The parser should ignore it.
  24 +* FIXED: The whois.pnina.ps server injects a NODNS.NS string when a nameserver is not set.
  25 + The parser should ignore it.
22 26
23 27 * FIXED: whois.nic.ve must support :suspended status.
24 28
124 lib/whois/answer.rb
@@ -60,104 +60,116 @@ def ==(other)
60 60 (other.is_a?(Answer) && other.to_s == self.to_s)
61 61 end
62 62
63   - # Delegates to ==.
64   - def eql?(other)
65   - self == other
66   - end
  63 + alias_method :eql?, :==
67 64
68 65
69   - # This method joins and returns all answer parts into a single string
  66 + # Joins and returns all answer parts into a single string
70 67 # and separates each response with a newline character.
71 68 #
  69 + # @example Answer with one part
72 70 # answer = Whois::Answer.new([Whois::Answer::Part.new("First answer.")])
73 71 # answer.content
74 72 # # => "First answer."
75 73 #
  74 + # @example Answer with multiple parts
76 75 # answer = Whois::Answer.new([Whois::Answer::Part.new("First answer."), Whois::Answer::Part.new("Second answer.")])
77 76 # answer.content
78 77 # # => "First answer.\nSecond answer."
79 78 #
80   - # ==== Returns
81   - #
82   - # String:: The content of this answer.
  79 + # @return [String] The content of this answer.
83 80 #
84 81 def content
85 82 @content ||= parts.map(&:body).join("\n")
86 83 end
87 84
  85 + # Lazy-loads and returns the parser proxy for current answer.
  86 + #
  87 + # @return [Whois::Answer::Parser]
  88 + def parser
  89 + @parser ||= Parser.new(self)
  90 + end
  91 +
88 92
89   - # Returns whether this answer changed compared to <tt>other</tt>.
  93 + # Returns a Hash containing all supported properties for this answer
  94 + # along with corresponding values.
90 95 #
91   - # Comparing the Answer contents is not always as trivial as it seems.
92   - # Whois servers sometimes inject dynamic method into the whois answer such as
93   - # the timestamp the request was generated.
94   - # This causes two answers to be different even if they actually should be considered equal
95   - # because the registry data didn't change.
  96 + # @return [Hash]
  97 + def properties
  98 + hash = {}
  99 + Parser::PROPERTIES.each { |property| hash[property] = send(property) }
  100 + hash
  101 + end
  102 +
  103 + # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
  104 + # is supported by any available parser for this answer.
  105 + # See also <tt>Whois::Answer::Parser.supported?</tt>.
96 106 #
97   - # This method should provide a bulletproof way to detect whether this answer
98   - # changed if compared with <tt>other</tt>.
  107 + # @param [Symbol] property - The name of the property to check.
  108 + # @return [Boolean]
99 109 #
100   - # ==== Parameters
  110 + # @see Whois::Answer::Parser#property_supported?
101 111 #
102   - # other:: The Whois::Answer to compare.
  112 + def property_supported?(property)
  113 + parser.property_supported?(property)
  114 + end
  115 +
  116 +
  117 + # Checks whether this Answer is different than +other+.
  118 + #
  119 + # Comparing the Answer content is not as trivial as you may think.
  120 + # WHOIS servers can inject into the WHOIS response strings that changes at every request,
  121 + # such as the timestamp the request was generated or the number of requests left
  122 + # for your current IP.
103 123 #
104   - # ==== Returns
  124 + # These strings causes a simple equal comparison to fail even if
  125 + # the registry data is the same.
  126 + #
  127 + # This method should provide a bulletproof way to detect whether this answer
  128 + # changed compared with +other+.
105 129 #
106   - # Boolean
  130 + # @param [Whois::Answer] other The other answer instance to compare.
  131 + # @return [Boolean]
  132 + #
  133 + # @see Whois::Answer::Parser#changed?
107 134 #
108 135 def changed?(other)
109 136 !unchanged?(other)
110 137 end
111 138
112   - # The opposite of <tt>changed?</tt>.
113   - def unchanged?(other)
114   - self == other ||
115   - parser.unchanged?(other.parser)
116   - end
117   -
118   - def contacts
119   - parser.contacts
120   - end
121   -
122   -
123   - # Lazy-loads and returns the parser proxy for current answer.
  139 + # The opposite of {#changed?}.
124 140 #
125   - # ==== Returns
  141 + # @param [Whois::Answer] other The other answer instance to compare.
  142 + # @return [Boolean]
126 143 #
127   - # Whois::Answer::Parser
  144 + # @see Whois::Answer::Parser#unchanged?
128 145 #
129   - def parser
130   - @parser ||= Parser.new(self)
131   - end
  146 + def unchanged?(other)
  147 + unless other.is_a?(self.class)
  148 + raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
  149 + end
132 150
  151 + equal?(other) ||
  152 + parser.unchanged?(other.parser)
  153 + end
133 154
134   - # Returns a Hash containing all supported properties for this answer
135   - # along with corresponding values.
  155 + # Collects and returns all the contacts.
136 156 #
137   - # ==== Returns
  157 + # @return [Array<Whois::Aswer::Contact>]
138 158 #
139   - # Hash
  159 + # @see Whois::Answer::Parser#contacts?
140 160 #
141   - def properties
142   - hash = {}
143   - Parser::PROPERTIES.each { |property| hash[property] = send(property) }
144   - hash
  161 + def contacts
  162 + parser.contacts
145 163 end
146 164
147   - # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
148   - # is supported by any available parser for this answer.
149   - # See also <tt>Whois::Answer::Parser.supported?</tt>.
150   - #
151   - # ==== Parameters
  165 + # Checks whether this is a throttle response.
152 166 #
153   - # property:: A Symbol with the property name to check.
  167 + # @return [Boolean]
154 168 #
155   - # ==== Returns
  169 + # @see Whois::Answer::Parser#throttle?
156 170 #
157   - # Boolean
158   - #
159   - def property_supported?(property)
160   - parser.property_supported?(property)
  171 + def throttle?
  172 + parser.throttle?
161 173 end
162 174
163 175
68 lib/whois/answer/parser.rb
@@ -23,9 +23,9 @@ class Answer
23 23 class Parser
24 24
25 25 METHODS = [
26   - :contacts, :throttle?,
27   - # deprecated methods
28   - :registrant, :admin, :technical,
  26 + :changed?, :unchanged?,
  27 + :contacts,
  28 + # :throttle?,
29 29 ]
30 30
31 31 PROPERTIES = [
@@ -61,11 +61,60 @@ def property_supported?(property)
61 61 end
62 62
63 63
64   - # Collects and returns all the contacts from all parsers.
  64 + # Loop through all the answer parts to check if at least
  65 + # one part changed.
  66 + #
  67 + # @param [Whois::Answer::Parser] other The other parser instance to compare.
  68 + # @return [Boolean]
  69 + #
  70 + # @see Whois::Answer#changed?
  71 + # @see Whois::Answer::Parser::Base#changed?
  72 + #
  73 + def changed?(other)
  74 + !unchanged?(other)
  75 + end
  76 +
  77 + # The opposite of {#changed?}.
  78 + #
  79 + # @param [Whois::Answer::Parser] other The other parser instance to compare.
  80 + # @return [Boolean]
  81 + #
  82 + # @see Whois::Answer#unchanged?
  83 + # @see Whois::Answer::Parser::Base#unchanged?
  84 + #
  85 + def unchanged?(other)
  86 + unless other.is_a?(self.class)
  87 + raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
  88 + end
  89 +
  90 + equal?(other) ||
  91 + parsers.size == other.parsers.size &&
  92 + all_with_args?(parsers, other.parsers) { |one, two| one.unchanged?(two) }
  93 + end
  94 +
  95 + # Collects and returns all the contacts from all the answer parts.
  96 + #
  97 + # @return [Array<Whois::Aswer::Contact>]
  98 + #
  99 + # @see Whois::Answer#contacts?
  100 + # @see Whois::Answer::Parser::Base#contacts?
  101 + #
65 102 def contacts
66 103 parsers.inject([]) { |all, parser| all.concat(parser.contacts) }
67 104 end
68 105
  106 + # Loop through all the answer parts to check if at least
  107 + # one part is a throttle response.
  108 + #
  109 + # @return [Boolean]
  110 + #
  111 + # @see Whois::Answer#throttle?
  112 + # @see Whois::Answer::Parser::Base#throttle?
  113 + #
  114 + def throttle?
  115 + parsers.any?(&:throttle?)
  116 + end
  117 +
69 118
70 119 private
71 120
@@ -156,6 +205,17 @@ def select_parser(property, status = :any)
156 205 nil
157 206 end
158 207
  208 + def all_with_args?(*args, &block)
  209 + count = args.first.size
  210 + index = 0
  211 +
  212 + while index < count
  213 + return false unless yield(*args.map { |arg| arg[index] })
  214 + index += 1
  215 + end
  216 + true
  217 + end
  218 +
159 219
160 220 # Returns the proper parser instance for given <tt>part</tt>.
161 221 # The parser class is selected according to the
95 lib/whois/answer/parser/base.rb
@@ -60,7 +60,7 @@ def self.property_registry(klass = nil)
60 60 end
61 61 end
62 62
63   - # Returns the status for <tt>property</tt> passed as symbol.
  63 + # Returns the status for the <tt>property</tt> passed as symbol.
64 64 #
65 65 # property_status(:disclaimer)
66 66 # # => nil
@@ -114,15 +114,6 @@ def self.property_registered?(property, status = :any)
114 114 #
115 115 # property_registered?(:disclaimer)
116 116 # # => true
117   - #
118   - #
119   - # register_property(:changed?, :implemented) do |other|
120   - # ...
121   - # end
122   - #
123   - # # def changed?(other)
124   - # # ...
125   - # # end
126 117 #
127 118 def self.register_property(property, status, &block)
128 119 property = property.to_s.to_sym
@@ -184,8 +175,21 @@ def self.property_supported(property, &block)
184 175 register_property(property, :supported, &block)
185 176 end
186 177
  178 + # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
  179 + # is supported by the current parser.
  180 + #
  181 + # @param [Symbol] property The name of the property to check.
  182 + # @return [Boolean]
  183 + #
  184 + def property_supported?(property)
  185 + self.class.property_registered?(property, :supported)
  186 + end
187 187
188 188
  189 + # Initializes a new parser with given +part+.
  190 + #
  191 + # @param [Whois::Answer::Part] part
  192 + #
189 193 def initialize(part)
190 194 @part = part
191 195 end
@@ -194,7 +198,7 @@ def part
194 198 @part
195 199 end
196 200
197   - # This is an internal method primaly used as a common access point
  201 + # This is an internal method primary used as a common access point
198 202 # to get the content to be parsed as a string.
199 203 #
200 204 # The main reason behind this method is because I changed the internal
@@ -210,21 +214,59 @@ def content
210 214 end
211 215
212 216
213   - # Returns <tt>true</tt> if the <tt>property</tt> passed as symbol
214   - # is supported by the current parser.
215   - def property_supported?(property)
216   - self.class.property_registered?(property, :supported)
217   - end
218   -
219 217
220 218 Whois::Answer::Parser::PROPERTIES.each do |property|
221 219 property_not_implemented(property)
222 220 end
223 221
224 222
225   - # Gets all supported contacts merged into a single Array.
  223 + # Checks whether the content of this part is different than +other+.
  224 + #
  225 + # Comparing a WHOIS response is not as trivial as you may think.
  226 + # WHOIS servers can inject into the WHOIS response strings that changes at every request,
  227 + # such as the timestamp the request was generated or the number of requests left
  228 + # for your current IP.
  229 + #
  230 + # These strings causes a simple equal comparison to fail even if
  231 + # the registry data is the same.
  232 + #
  233 + # This method should provide a bulletproof way to detect whether this answer
  234 + # changed compared with +other+.
  235 + #
  236 + # @param [Base] other The other parser instance to compare.
  237 + # @return [Boolean]
  238 + #
  239 + # @see Whois::Answer#changed?
  240 + # @see Whois::Answer::Parser#changed?
  241 + #
  242 + def changed?(other)
  243 + !unchanged?(other)
  244 + end
  245 +
  246 + # The opposite of {#changed?}.
  247 + #
  248 + # @param [Base] other The other parser instance to compare.
  249 + # @return [Boolean]
  250 + #
  251 + # @see Whois::Answer#unchanged?
  252 + # @see Whois::Answer::Parser#unchanged?
  253 + #
  254 + def unchanged?(other)
  255 + unless other.is_a?(self.class)
  256 + raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
  257 + end
  258 +
  259 + equal?(other) ||
  260 + content_for_scanner == other.content_for_scanner
  261 + end
  262 +
  263 + # Collects and returns all the available contacts.
  264 + #
  265 + # @return [Array<Whois::Aswer::Contact>]
  266 + #
  267 + # @see Whois::Answer#contacts
  268 + # @see Whois::Answer::Parser#contacts
226 269 #
227   - # Returns an Array of Whois::Aswer::Contact.
228 270 def contacts
229 271 contacts = []
230 272 contacts.concat(registrant_contact.is_a?(Array) ? registrant_contact : [registrant_contact]) if property_supported?(:registrant_contact)
@@ -233,14 +275,16 @@ def contacts
233 275 contacts.compact
234 276 end
235 277
236   - # NEWPROPERTY
237   - #
238 278 # Checks whether this is a throttle response.
239   - # The default implementation always returns false.
  279 + # The default implementation always returns +false+.
240 280 #
241   - # This method is intended to be overrridden by child classes.
  281 + # @abstract This method returns false by default.
242 282 #
243   - # Returns false by default.
  283 + # @return [false]
  284 + #
  285 + # @see Whois::Answer#throttle?
  286 + # @see Whois::Answer::Parser#throttle?
  287 + #
244 288 def throttle?
245 289 false
246 290 end
@@ -252,9 +296,8 @@ def content_for_scanner
252 296 @content_for_scanner ||= content.to_s.gsub(/\r\n/, "\n")
253 297 end
254 298
255   -
256 299 end
257 300
258 301 end
259 302 end
260   -end
  303 +end
24 lib/whois/answer/parser/example.rb
@@ -160,30 +160,6 @@ class WhoisExampleCom < Base
160 160 @nameservers ||= []
161 161 end
162 162
163   -
164   - # Public: Checks whether this answer is different than <tt>other</tt>.
165   - #
166   - # Comparing the Answer contents is not always as trivial as it seems.
167   - # Whois servers sometimes inject dynamic method into the whois answer such as
168   - # the timestamp the request was generated.
169   - # This causes two answers to be different even if they actually should be considered equal
170   - # because the registry data didn't change.
171   - #
172   - # This method should provide a bulletproof way to detect whether this answer
173   - # changed if compared with <tt>other</tt>.
174   - #
175   - # Returns true/false depending whether this answer is different than <tt>other</tt>.
176   - property_supported :changed? do |other|
177   - !unchanged?(other)
178   - end
179   -
180   - # Public: The opposite of <tt>#changed?</tt>.
181   - #
182   - # Returns true/false depending whether this answer is not different than <tt>other</tt>.
183   - property_supported :unchanged? do |other|
184   - false
185   - end
186   -
187 163 end
188 164
189 165 end
12 lib/whois/answer/parser/whois.co.pl.rb
@@ -87,18 +87,6 @@ class WhoisCoPl < Base
87 87 @nameservers ||= content_for_scanner.scan(/nserver:\s+(.+)\n/).flatten
88 88 end
89 89
90   -
91   - # NEWPROPERTY
92   - property_supported :changed? do |other|
93   - !unchanged?(other)
94   - end
95   -
96   - # NEWPROPERTY
97   - property_supported :unchanged? do |other|
98   - (self === other) ||
99   - (self.content == other.content)
100   - end
101   -
102 90 end
103 91
104 92 end
12 lib/whois/answer/parser/whois.coza.net.za.rb
@@ -78,18 +78,6 @@ class WhoisCozaNetZa < Base
78 78 property_not_supported :nameservers
79 79
80 80
81   - # NEWPROPERTY
82   - property_supported :changed? do |other|
83   - !unchanged?(other)
84   - end
85   -
86   - # NEWPROPERTY
87   - property_supported :unchanged? do |other|
88   - (self === other) ||
89   - (self.content == other.content)
90   - end
91   -
92   -
93 81 protected
94 82
95 83 # Very often the .to server returns a partial response, which is a response
12 lib/whois/answer/parser/whois.nic.ac.rb
@@ -80,18 +80,6 @@ class WhoisNicAc < Base
80 80
81 81 property_not_supported :nameservers
82 82
83   -
84   - # NEWPROPERTY
85   - def changed?(other)
86   - !unchanged?(other)
87   - end
88   -
89   - # NEWPROPERTY
90   - def unchanged?(other)
91   - self.equal?(other) ||
92   - self.content_for_scanner == other.content_for_scanner
93   - end
94   -
95 83 end
96 84
97 85 end
12 lib/whois/answer/parser/whois.nic.io.rb
@@ -80,18 +80,6 @@ class WhoisNicIo < Base
80 80
81 81 property_not_supported :nameservers
82 82
83   -
84   - # NEWPROPERTY
85   - def changed?(other)
86   - !unchanged?(other)
87   - end
88   -
89   - # NEWPROPERTY
90   - def unchanged?(other)
91   - self.equal?(other) ||
92   - self.content_for_scanner == other.content_for_scanner
93   - end
94   -
95 83 end
96 84
97 85 end
10 lib/whois/answer/parser/whois.nic.it.rb
@@ -101,16 +101,6 @@ class WhoisNicIt < Base
101 101 end
102 102
103 103
104   - property_supported :changed? do |other|
105   - !unchanged?(other)
106   - end
107   -
108   - property_supported :unchanged? do |other|
109   - (self === other) ||
110   - (self.content == other.content)
111   - end
112   -
113   -
114 104 protected
115 105
116 106 def parse
12 lib/whois/answer/parser/whois.nic.sh.rb
@@ -80,18 +80,6 @@ class WhoisNicSh < Base
80 80
81 81 property_not_supported :nameservers
82 82
83   -
84   - # NEWPROPERTY
85   - def changed?(other)
86   - !unchanged?(other)
87   - end
88   -
89   - # NEWPROPERTY
90   - def unchanged?(other)
91   - self.equal?(other) ||
92   - self.content_for_scanner == other.content_for_scanner
93   - end
94   -
95 83 end
96 84
97 85 end
12 lib/whois/answer/parser/whois.nic.sn.rb
@@ -105,18 +105,6 @@ class WhoisNicSn < Base
105 105 end
106 106
107 107
108   - # NEWPROPERTY
109   - property_supported :changed? do |other|
110   - !unchanged?(other)
111   - end
112   -
113   - # NEWPROPERTY
114   - property_supported :unchanged? do |other|
115   - (self.equal? other) ||
116   - (self.content == other.content)
117   - end
118   -
119   -
120 108 private
121 109
122 110 def contact(string)
12 lib/whois/answer/parser/whois.nic.tm.rb
@@ -80,18 +80,6 @@ class WhoisNicTm < Base
80 80
81 81 property_not_supported :nameservers
82 82
83   -
84   - # NEWPROPERTY
85   - def changed?(other)
86   - !unchanged?(other)
87   - end
88   -
89   - # NEWPROPERTY
90   - def unchanged?(other)
91   - self.equal?(other) ||
92   - self.content_for_scanner == other.content_for_scanner
93   - end
94   -
95 83 end
96 84
97 85 end
12 lib/whois/answer/parser/whois.org.za.rb
@@ -77,18 +77,6 @@ class WhoisOrgZa < Base
77 77
78 78 property_not_supported :nameservers
79 79
80   -
81   - # NEWPROPERTY
82   - property_supported :changed? do |other|
83   - !unchanged?(other)
84   - end
85   -
86   - # NEWPROPERTY
87   - property_supported :unchanged? do |other|
88   - (self === other) ||
89   - (self.content == other.content)
90   - end
91   -
92 80 end
93 81
94 82 end
11 lib/whois/answer/parser/whois.publicinterestregistry.net.rb
@@ -103,17 +103,6 @@ class WhoisPublicinterestregistryNet < Base
103 103
104 104
105 105 # NEWPROPERTY
106   - property_supported :changed? do |other|
107   - !unchanged?(other)
108   - end
109   -
110   - # NEWPROPERTY
111   - property_supported :unchanged? do |other|
112   - self == other ||
113   - self.content.to_s == other.content.to_s
114   - end
115   -
116   - # NEWPROPERTY
117 106 def throttle?
118 107 !!node("status-throttle")
119 108 end
12 lib/whois/answer/parser/whois.tonic.to.rb
@@ -82,18 +82,6 @@ class WhoisTonicTo < Base
82 82 property_not_supported :nameservers
83 83
84 84
85   - # NEWPROPERTY
86   - property_supported :changed? do |other|
87   - !unchanged?(other)
88   - end
89   -
90   - # NEWPROPERTY
91   - property_supported :unchanged? do |other|
92   - (self === other) ||
93   - (self.content == other.content)
94   - end
95   -
96   -
97 85 protected
98 86
99 87 # Very often the .to server returns a partial response, which is a response
10 spec/spec_helper.rb
@@ -17,6 +17,16 @@ def with_definitions(&block)
17 17 Whois::Server.send :class_variable_set, :@@definitions, @_definitions
18 18 end
19 19
  20 + # Temporary resets parser @@registry
  21 + # to let the test setup a custom registry.
  22 + def with_registry(&block)
  23 + @_property_registry = Whois::Answer::Parser::Base.send :class_variable_get, :@@property_registry
  24 + Whois::Answer::Parser::Base.send :class_variable_set, :@@property_registry, {}
  25 + yield
  26 + ensure
  27 + Whois::Answer::Parser::Base.send :class_variable_set, :@@property_registry, @_property_registry
  28 + end
  29 +
20 30 # Gets the currently described class.
21 31 # Conversely to +subject+, it returns the class
22 32 # instead of an instance.
156 spec/whois/answer/parser/base_spec.rb
... ... @@ -0,0 +1,156 @@
  1 +require "spec_helper"
  2 +
  3 +describe Whois::Answer::Parser::Base do
  4 +
  5 + before(:each) do
  6 + @part = Whois::Answer::Part.new("This is the response.", "whois.example.test")
  7 + end
  8 +
  9 +
  10 + describe ".property_registry" do
  11 + it "returns the @@registry variable when no argument is passed" do
  12 + with_registry do
  13 + klass.property_registry.should == klass.send(:class_variable_get, :@@property_registry)
  14 + end
  15 + end
  16 +
  17 + it "returns the hash for given class when class argument is passed" do
  18 + with_registry do
  19 + test_parser = Class.new(klass)
  20 + klass.send(:class_variable_set, :@@property_registry, { test_parser => {} })
  21 +
  22 + klass.property_registry[test_parser].should == Hash.new
  23 + end
  24 + end
  25 +
  26 + it "lazy initializes the hash for given class" do
  27 + with_registry do
  28 + test_parser = Class.new(klass)
  29 + klass.send(:class_variable_set, :@@property_registry, Hash.new)
  30 + klass.property_registry[test_parser]
  31 + klass.send(:class_variable_get, :@@property_registry).should == {}
  32 + end
  33 + end
  34 + end
  35 +
  36 + describe "#property_supported?" do
  37 + it "returns false if the property is not supported" do
  38 + pclass = Class.new(klass) do
  39 + end
  40 + pclass.new(@part).property_supported?(:disclaimer).should be_false
  41 + pclass.new(@part).respond_to?(:disclaimer).should be_true
  42 + end
  43 +
  44 + it "returns true if the property is supported" do
  45 + pclass = Class.new(klass) do
  46 + register_property(:disclaimer, :supported) {}
  47 + end
  48 + pclass.new(@part).property_supported?(:disclaimer).should be_true
  49 + pclass.new(@part).respond_to?(:disclaimer).should be_true
  50 + end
  51 + end
  52 +
  53 +
  54 + describe ".new" do
  55 + it "requires a part" do
  56 + lambda { klass.new }.should raise_error(ArgumentError)
  57 + lambda { klass.new(@part) }.should_not raise_error
  58 + end
  59 +
  60 + it "sets the part" do
  61 + klass.new(@part).part.should be(@part)
  62 + end
  63 + end
  64 +
  65 + describe "#content" do
  66 + it "returns the part body" do
  67 + instance = klass.new(@part)
  68 + instance.content.should be(@part.body)
  69 + end
  70 + end
  71 +
  72 + describe "#content_for_scanner" do
  73 + it "returns the part body with line feed normalized" do
  74 + instance = klass.new(Whois::Answer::Part.new("This is\r\nthe response.", "whois.example.test"))
  75 + instance.send(:content_for_scanner).should == "This is\nthe response."
  76 + end
  77 +
  78 + it "caches the result" do
  79 + instance = klass.new(Whois::Answer::Part.new("This is\r\nthe response.", "whois.example.test"))
  80 + instance.instance_eval { @content_for_scanner }.should be_nil
  81 + instance.send(:content_for_scanner)
  82 + instance.instance_eval { @content_for_scanner }.should == "This is\nthe response."
  83 + end
  84 + end
  85 +
  86 +
  87 + describe "#changed?" do
  88 + it "raises if the argument is not an instance of the same class" do
  89 + lambda do
  90 + klass.new(@part).changed?(Object.new)
  91 + end.should raise_error
  92 +
  93 + lambda do
  94 + klass.new(@part).changed?(klass.new(@part))
  95 + end.should_not raise_error
  96 + end
  97 + end
  98 +
  99 + describe "#unchanged?" do
  100 + it "raises if the argument is not an instance of the same class" do
  101 + lambda do
  102 + klass.new(@part).unchanged?(Object.new)
  103 + end.should raise_error
  104 +
  105 + lambda do
  106 + klass.new(@part).unchanged?(klass.new(@part))
  107 + end.should_not raise_error
  108 + end
  109 +
  110 + it "returns true if self and other references the same object" do
  111 + instance = klass.new(@part)
  112 + instance.unchanged?(instance).should be_true
  113 + end
  114 +
  115 + it "returns true if the content_for_scanner is the same" do
  116 + instance = klass.new(Whois::Answer::Part.new("This is the\nresponse 1.", "whois.example.test"))
  117 + other = klass.new(Whois::Answer::Part.new("This is the\r\nresponse 1.", "whois.example.test"))
  118 + instance.unchanged?(other).should be_true
  119 + end
  120 +
  121 + it "returns false if the content_for_scanner is not the same" do
  122 + instance = klass.new(Whois::Answer::Part.new("This is the response 1.", "whois.example.test"))
  123 + other = klass.new(Whois::Answer::Part.new("This is the response 2.", "whois.example.test"))
  124 + instance.unchanged?(other).should be_false
  125 + end
  126 + end
  127 +
  128 + describe "#contacts" do
  129 + it "returns an array of contacts" do
  130 + c1 = Whois::Answer::Contact.new(:id => "1st", :name => "foo")
  131 + c2 = Whois::Answer::Contact.new(:id => "2nd", :name => "foo")
  132 + c3 = Whois::Answer::Contact.new(:id => "3rd", :name => "foo")
  133 + pclass = Class.new(klass) do
  134 + register_property(:registrant_contact, :supported) { [c1, c2] }
  135 + register_property(:admin_contact, :supported) { nil }
  136 + register_property(:technical_contact, :supported) { c3 }
  137 + end
  138 +
  139 + instance = pclass.new(@part)
  140 + instance.contacts.should == [c1, c2, c3]
  141 + end
  142 +
  143 + it "returns an empty array when no contact is supported" do
  144 + instance = klass.new(@part)
  145 + instance.contacts.should == []
  146 + end
  147 + end
  148 +
  149 + describe "#throttle?" do
  150 + it "returns false" do
  151 + instance = klass.new(@part)
  152 + instance.throttle?.should be_false
  153 + end
  154 + end
  155 +
  156 +end
65 spec/whois/answer/parser_spec.rb
... ... @@ -0,0 +1,65 @@
  1 +require "spec_helper"
  2 +
  3 +describe Whois::Answer::Parser do
  4 +
  5 + before(:each) do
  6 + @answer = Whois::Answer.new(nil, [])
  7 + end
  8 +
  9 +
  10 + describe "#changed?" do
  11 + it "raises if the argument is not an instance of the same class" do
  12 + lambda do
  13 + klass.new(@answer).changed?(Object.new)
  14 + end.should raise_error
  15 +
  16 + lambda do
  17 + klass.new(@answer).changed?(klass.new(@answer))
  18 + end.should_not raise_error
  19 + end
  20 + end
  21 +
  22 + describe "#unchanged?" do
  23 + it "raises if the argument is not an instance of the same class" do
  24 + lambda do
  25 + klass.new(@answer).unchanged?(Object.new)
  26 + end.should raise_error
  27 +
  28 + lambda do
  29 + klass.new(@answer).unchanged?(klass.new(@answer))
  30 + end.should_not raise_error
  31 + end
  32 +
  33 + it "returns true if self and other references the same object" do
  34 + instance = klass.new(@answer)
  35 + instance.unchanged?(instance).should be_true
  36 + end
  37 +
  38 + it "returns false if parser and other.parser have different number of elements" do
  39 + instance = klass.new(Whois::Answer.new(nil, []))
  40 + other = klass.new(Whois::Answer.new(nil, [Whois::Answer::Part.new("", "foo.example.test")]))
  41 + instance.unchanged?(other).should be_false
  42 + end
  43 +
  44 + it "returns true if parsers and other.parsers have 0 elements" do
  45 + instance = klass.new(Whois::Answer.new(nil, []))
  46 + other = klass.new(Whois::Answer.new(nil, []))
  47 + instance.unchanged?(other).should be_true
  48 + end
  49 + end
  50 +
  51 + it "returns true if every parser in self marches the corresponding parser in other" do
  52 + instance = klass.new(Whois::Answer.new(nil, [Whois::Answer::Part.new("hello", "foo.example.test"), Whois::Answer::Part.new("world", "bar.example.test")]))
  53 + other = klass.new(Whois::Answer.new(nil, [Whois::Answer::Part.new("hello", "foo.example.test"), Whois::Answer::Part.new("world", "bar.example.test")]))
  54 +
  55 + instance.unchanged?(other).should be_true
  56 + end
  57 +
  58 + it "returns false unless every parser in self marches the corresponding parser in other" do
  59 + instance = klass.new(Whois::Answer.new(nil, [Whois::Answer::Part.new("hello", "foo.example.test"), Whois::Answer::Part.new("world", "bar.example.test")]))
  60 + other = klass.new(Whois::Answer.new(nil, [Whois::Answer::Part.new("hello", "foo.example.test"), Whois::Answer::Part.new("baby!", "bar.example.test")]))
  61 +
  62 + instance.unchanged?(other).should be_false
  63 + end
  64 +
  65 +end
62 spec/whois/answer_spec.rb
... ... @@ -0,0 +1,62 @@
  1 +require "spec_helper"
  2 +
  3 +describe Whois::Answer do
  4 +
  5 + before(:each) do
  6 + @server = Whois::Server.factory(:tld, ".foo", "whois.example.test")
  7 + @parts = [
  8 + Whois::Answer::Part.new("This is a answer from foo.", "foo.example.test"),
  9 + Whois::Answer::Part.new("This is a answer from bar.", "bar.example.test")
  10 + ]
  11 + @content = "This is a answer from foo.\nThis is a answer from bar."
  12 + @answer = klass.new(@server, @parts)
  13 + end
  14 +
  15 +
  16 + describe "#changed?" do
  17 + it "raises if the argument is not an instance of the same class" do
  18 + lambda do
  19 + klass.new(nil, []).changed?(Object.new)
  20 + end.should raise_error
  21 +
  22 + lambda do
  23 + klass.new(nil, []).changed?(klass.new(nil, []))
  24 + end.should_not raise_error
  25 + end
  26 + end
  27 +
  28 + describe "#unchanged?" do
  29 + it "raises if the argument is not an instance of the same class" do
  30 + lambda do
  31 + klass.new(nil, []).unchanged?(Object.new)
  32 + end.should raise_error
  33 +
  34 + lambda do
  35 + klass.new(nil, []).unchanged?(klass.new(nil, []))
  36 + end.should_not raise_error
  37 + end
  38 +
  39 + it "returns true if self and other references the same object" do
  40 + instance = klass.new(nil, [])
  41 + instance.unchanged?(instance).should be_true
  42 + end
  43 +
  44 + it "delegates to #parser if self and other references different objects" do
  45 + other = klass.new(nil, @parts)
  46 + instance = klass.new(nil, @parts)
  47 + instance.parser.expects(:unchanged?).with(other.parser)
  48 +
  49 + instance.unchanged?(other)
  50 + end
  51 + end
  52 +
  53 + describe "#throttle?" do
  54 + it "delegates to #parser" do
  55 + instance = klass.new(nil, @parts)
  56 + instance.parser.expects(:throttle?)
  57 +
  58 + instance.throttle?
  59 + end
  60 + end
  61 +
  62 +end
84 test/whois/answer/parser/base_test.rb
... ... @@ -1,84 +0,0 @@
1   -require 'test_helper'
2   -require 'whois/answer/parser/base'
3   -
4   -class AnswerParserBaseTest < Test::Unit::TestCase
5   -
6   - def setup
7   - @klass = Whois::Answer::Parser::Base
8   - @part = Whois::Answer::Part.new("This is the response.", "whois.foo.com")
9   - end
10   -
11   -
12   - def test_initialize
13   - parser = @klass.new(@part)
14   - assert_instance_of @klass, parser
15   - end
16   -
17   - def test_initialize_should_require_part
18   - assert_raise(ArgumentError) { @klass.new }
19   - end
20   -
21   -
22   - def test_content
23   - parser = @klass.new(@part)
24   - assert_equal @part.body, parser.content
25   - end
26   -
27   - def test_content_for_scanner
28   - parser = @klass.new(Whois::Answer::Part.new("This is\r\nthe response.", "whois.foo.com"))
29   - assert_equal "This is\nthe response.", parser.send(:content_for_scanner)
30   - assert_equal "This is\nthe response.", parser.instance_variable_get(:"@content_for_scanner")
31   - end
32   -
33   -
34   - def test_property_supported?
35   - klass = Class.new(@klass) do
36   - end
37   - assert !klass.new(@part).property_supported?(:disclaimer)
38   - assert klass.new(@part).respond_to?(:disclaimer)
39   -
40   - klass = Class.new(@klass) do
41   - register_property(:disclaimer, :supported) {}
42   - end
43   - assert klass.new(@part).property_supported?(:disclaimer)
44   - assert klass.new(@part).respond_to?(:disclaimer)
45   - end
46   -
47   -
48   - def test_contacts_should_return_empty_array_with_all_unsupported
49   - parser = @klass.new(@part)
50   - assert_equal [], parser.contacts
51   - end
52   -
53   - def test_contacts_should_return_all_supported_contacts
54   - c1 = Whois::Answer::Contact.new(:id => "1st", :name => "foo")
55   - c2 = Whois::Answer::Contact.new(:id => "2nd", :name => "foo")
56   - c3 = Whois::Answer::Contact.new(:id => "3rd", :name => "foo")
57   - klass = Class.new(@klass) do
58   - register_property(:registrant_contact, :supported) { [c1, c2] }
59   - register_property(:admin_contact, :supported) { nil }
60   - register_property(:technical_contact, :supported) { c3 }
61   - end
62   - assert_equal ["1st", "2nd", "3rd"], klass.new(@part).contacts.map(&:id)
63   - end
64   -
65   -
66   - def test_throttle_question
67   - assert !@klass.new(@part).throttle?
68   - end
69   -
70   -
71   - def test_self_property_registry
72   - assert_instance_of Hash, @klass.property_registry
73   - end
74   -
75   - def test_self_property_registry_with_klass
76   - assert_instance_of Hash, @klass.property_registry(Whois::Answer::Parser::WhoisNicIt)
77   - end
78   -
79   - def test_self_property_registry_with_klass_should_initialize_to_empty_hash
80   - parser = Class.new
81   - assert_equal Hash.new, @klass.property_registry(parser)
82   - end
83   -
84   -end
31 test/whois/answer/parser/whois.nic.ac_test.rb
@@ -123,35 +123,4 @@ def test_nameservers
123 123 assert_raise(Whois::PropertyNotSupported) { @klass.new(load_part('available.txt')).nameservers }
124 124 end
125 125
126   -
127   - def test_changed?
128   - parser_r1 = @klass.new(load_part('registered.txt'))
129   - parser_r2 = @klass.new(load_part('registered.txt'))
130   - parser_a1 = @klass.new(load_part('available.txt'))
131   - parser_a2 = @klass.new(load_part('available.txt'))
132   -
133   - assert !parser_r1.changed?(parser_r1)
134   - assert !parser_r1.changed?(parser_r2)
135   - assert parser_r1.changed?(parser_a1)
136   -
137   - assert !parser_a1.changed?(parser_a1)
138   - assert !parser_a1.changed?(parser_a2)
139   - assert parser_a1.changed?(parser_r1)
140   - end
141   -
142   - def test_unchanged?
143   - parser_r1 = @klass.new(load_part('registered.txt'))
144   - parser_r2 = @klass.new(load_part('registered.txt'))
145   - parser_a1 = @klass.new(load_part('available.txt'))
146   - parser_a2 = @klass.new(load_part('available.txt'))
147   -
148   - assert parser_r1.unchanged?(parser_r1)
149   - assert parser_r1.unchanged?(parser_r2)
150   - assert !parser_r1.unchanged?(parser_a1)
151   -
152   - assert parser_a1.unchanged?(parser_a1)
153   - assert parser_a1.unchanged?(parser_a2)
154   - assert !parser_a1.unchanged?(parser_r1)
155   - end
156   -
157 126 end
31 test/whois/answer/parser/whois.nic.io_test.rb
@@ -123,35 +123,4 @@ def test_nameservers
123 123 assert_raise(Whois::PropertyNotSupported) { @klass.new(load_part('available.txt')).nameservers }
124 124 end
125 125
126   -
127   - def test_changed?
128   - parser_r1 = @klass.new(load_part('registered.txt'))
129   - parser_r2 = @klass.new(load_part('registered.txt'))
130   - parser_a1 = @klass.new(load_part('available.txt'))
131   - parser_a2 = @klass.new(load_part('available.txt'))
132   -
133   - assert !parser_r1.changed?(parser_r1)
134   - assert !parser_r1.changed?(parser_r2)
135   - assert parser_r1.changed?(parser_a1)
136