diff options
author | Michael Herold <michael.j.herold@gmail.com> | 2015-10-23 14:39:16 -0500 |
---|---|---|
committer | Michael Herold <michael.j.herold@gmail.com> | 2015-10-23 15:43:05 -0500 |
commit | f39609d54dfd43c6b6a410067afcf6416b492161 (patch) | |
tree | ff11b1b872de7ba481429c3cabbc2832a00bd2f6 | |
parent | c652c5b04a51a4de9e62b79fdee0b13687d8f4b4 (diff) | |
download | hashie-boolean-method-query.tar.gz |
Ensure that MethodQuery methods return booleansboolean-method-query
The documentation about the MethodQuery module spells out the expected
behavior. While the spec suite appeared to be testing the same, the
RSpec matchers were not actually checking the behavior properly. This
lead to a divergence between the expected behavior, as outlined in the
module documentation, and the actual behavior, as tested in the spec
suite.
This is the reason that #299 is happening: the expected behavior is not
the actual behavior. I have included a test for #299 to show that it
works as expected in this branch.
This change makes the spec suite match the behavior in the module
documentation, then modifies the methods to match the documentated
specification.
Lastly, I took the time to clean up the MethodQuery module for two
reasons:
1. The old implementation used Regexps on the stringified
method names, which is unnecessary since we have the wonderful
`String#end_with?` method to check the suffix of a strings.
2. The old logic was difficult to reason through, so I clarified the
intent of the methods by reducing the complexity of the conditionals
and extracting meaningful methods where possible.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/hashie/extensions/method_access.rb | 35 | ||||
-rw-r--r-- | spec/hashie/dash_spec.rb | 23 | ||||
-rw-r--r-- | spec/hashie/extensions/method_access_spec.rb | 10 |
4 files changed, 61 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b758559..fbfc785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * [#310](https://github.com/intridea/hashie/pull/310): Fixed `Hashie::Extensions::SafeAssignment` bug with private methods - [@marshall-lee](https://github.com/marshall-lee). * [#313](https://github.com/intridea/hashie/pull/313): Restrict pending spec to only Ruby versions 2.2.0-2.2.2 - [@pboling](https://github.com/pboling). * [#315](https://github.com/intridea/hashie/pull/315): Default `bin/` scripts: `console` and `setup` - [@pboling](https://github.com/pboling). +* [#317](https://github.com/intridea/hashie/pull/317): Ensure `Hashie::Extensions::MethodQuery` methods return boolean values - [@michaelherold](https://github.com/michaelherold). ## 3.4.2 (6/2/2015) diff --git a/lib/hashie/extensions/method_access.rb b/lib/hashie/extensions/method_access.rb index 9c3d537..0ed2b22 100644 --- a/lib/hashie/extensions/method_access.rb +++ b/lib/hashie/extensions/method_access.rb @@ -107,16 +107,41 @@ module Hashie # h.hji? # => NoMethodError module MethodQuery def respond_to?(name, include_private = false) - return true if name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym)) - super + if query_method?(name) && indifferent_key?(key_from_query_method(name)) + true + else + super + end end def method_missing(name, *args) - if args.empty? && name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym)) - return self[Regexp.last_match[1]] || self[Regexp.last_match[1].to_sym] + return super unless args.empty? + + if query_method?(name) + key = key_from_query_method(name) + if indifferent_key?(key) + !!(self[key] || self[key.to_sym]) + else + super + end + else + super end + end - super + private + + def indifferent_key?(name) + name = name.to_s + key?(name) || key?(name.to_sym) + end + + def key_from_query_method(query_method) + query_method.to_s[0..-2] + end + + def query_method?(name) + name.to_s.end_with?('?') end end diff --git a/spec/hashie/dash_spec.rb b/spec/hashie/dash_spec.rb index 1de533f..453d62f 100644 --- a/spec/hashie/dash_spec.rb +++ b/spec/hashie/dash_spec.rb @@ -511,3 +511,26 @@ context 'Dynamic Dash Class' do expect(my_property).to eq(my_orig) end end + +context 'with method access' do + class DashWithMethodAccess < Hashie::Dash + include Hashie::Extensions::IndifferentAccess + include Hashie::Extensions::MethodQuery + + property :test + end + + subject(:dash) { DashWithMethodAccess.new(test: 'value') } + + describe '#test' do + subject { dash.test } + + it { is_expected.to eq('value') } + end + + describe '#test?' do + subject { dash.test? } + + it { is_expected.to eq true } + end +end diff --git a/spec/hashie/extensions/method_access_spec.rb b/spec/hashie/extensions/method_access_spec.rb index b48b4e1..03528e4 100644 --- a/spec/hashie/extensions/method_access_spec.rb +++ b/spec/hashie/extensions/method_access_spec.rb @@ -92,15 +92,19 @@ describe Hashie::Extensions::MethodQuery do subject { QueryHash } it 'is true for non-nil string key values' do - expect(subject.new('abc' => 123)).to be_abc + expect(subject.new('abc' => 123).abc?).to eq true end it 'is true for non-nil symbol key values' do - expect(subject.new(abc: 123)).to be_abc + expect(subject.new(abc: 123).abc?).to eq true + end + + it 'is false for false key values' do + expect(subject.new(abc: false).abc?).to eq false end it 'is false for nil key values' do - expect(subject.new(abc: false)).not_to be_abc + expect(subject.new(abc: nil).abc?).to eq false end it 'raises a NoMethodError for non-set keys' do |