Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
305 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require "active_attr/attributes" | ||
require "active_attr/unknown_attribute_error" | ||
require "active_support/concern" | ||
require "active_support/core_ext/object/blank" | ||
|
||
module ActiveAttr | ||
# QueryAttributes provides instance methods for querying attributes. | ||
# | ||
# @example Usage | ||
# class Person | ||
# include ActiveAttr::QueryAttributes | ||
# attribute :name | ||
# end | ||
# | ||
# person = Person.new | ||
# person.name? #=> false | ||
# person.name = "Chris Griego" | ||
# person.name? #=> true | ||
# | ||
# @since 0.3.0 | ||
module QueryAttributes | ||
extend ActiveSupport::Concern | ||
include Attributes | ||
|
||
included do | ||
attribute_method_suffix "?" | ||
end | ||
|
||
# Test the presence of an attribute | ||
# | ||
# Similar to an ActiveRecord model, when the attribute is a zero value or | ||
# is a string that represents false, the method returns false. | ||
# | ||
# @example Query an attribute | ||
# person.query_attribute(:name) | ||
# | ||
# @param [String, Symbol, #to_s] name The name of the attribute to query | ||
# | ||
# @return [true, false] The presence of the attribute | ||
# | ||
# @since 0.3.0 | ||
def query_attribute(name) | ||
if respond_to? "#{name}?" | ||
send "#{name}?" | ||
else | ||
raise UnknownAttributeError, "unknown attribute: #{name}" | ||
end | ||
end | ||
|
||
private | ||
|
||
def attribute?(name) | ||
case value = read_attribute(name) | ||
when "false", "FALSE", "f", "F" then false | ||
when Numeric, /^\-?[0-9]/ then !value.to_f.zero? | ||
else value.present? | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
require "spec_helper" | ||
require "active_attr/query_attributes" | ||
require "bigdecimal" | ||
|
||
module ActiveAttr | ||
describe QueryAttributes do | ||
subject { model_class.new } | ||
|
||
let :model_class do | ||
Class.new do | ||
include QueryAttributes | ||
|
||
attribute :value | ||
attribute :overridden | ||
|
||
def overridden? | ||
super | ||
end | ||
|
||
def true? | ||
true | ||
end | ||
|
||
def false? | ||
false | ||
end | ||
end | ||
end | ||
|
||
describe ".attribute" do | ||
it "defines an attribute predicate method that calls #attribute?" do | ||
subject.should_receive(:attribute?).with("value") | ||
subject.value? | ||
end | ||
|
||
it "defines an attribute reader that can be called via super" do | ||
subject.should_receive(:attribute?).with("overridden") | ||
subject.overridden? | ||
end | ||
end | ||
|
||
describe "#query_attribute" do | ||
it "raises ArgumentError when called with two arguments" do | ||
expect { subject.query_attribute(:a, :b) }.to raise_error ArgumentError | ||
end | ||
|
||
it "does not raise when called with a single argument" do | ||
expect { subject.query_attribute(:a) }.not_to raise_error ArgumentError | ||
end | ||
|
||
it "raises ArgumentError when called with no arguments" do | ||
expect { subject.query_attribute }.to raise_error ArgumentError | ||
end | ||
|
||
it "calls the predicate method if defined" do | ||
subject.query_attribute(:true).should == true | ||
subject.query_attribute(:false).should == false | ||
end | ||
|
||
it "raises when getting an undefined attribute" do | ||
expect { subject.query_attribute(:initials) }.to raise_error UnknownAttributeError, "unknown attribute: initials" | ||
end | ||
|
||
it "is false when the attribute is false" do | ||
subject.value = false | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is true" do | ||
subject.value = true | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is nil" do | ||
subject.value = nil | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is an Object" do | ||
subject.value = Object.new | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is an empty string" do | ||
subject.value = "" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is a non-empty string" do | ||
subject.value = "Chris" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 0" do | ||
subject.value = 0 | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is 1" do | ||
subject.value = 1 | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 0.0" do | ||
subject.value = 0.0 | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is 0.1" do | ||
subject.value = 0.1 | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is a zero BigDecimal" do | ||
subject.value = BigDecimal.new("0.0") | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is a non-zero BigDecimal" do | ||
subject.value = BigDecimal.new("0.1") | ||
subject.value?.should == true | ||
end | ||
|
||
it "is true when the attribute is -1" do | ||
subject.value = -1 | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is -0.0" do | ||
subject.value = -0.0 | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is -0.1" do | ||
subject.value = -0.1 | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is a negative zero BigDecimal" do | ||
subject.value = BigDecimal.new("-0.0") | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is a negative BigDecimal" do | ||
subject.value = BigDecimal.new("-0.1") | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is '0'" do | ||
subject.value = "0" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is '1'" do | ||
subject.value = "1" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is '0.0'" do | ||
subject.value = "0.0" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is '0.1'" do | ||
subject.value = "0.1" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is true when the attribute is '-1'" do | ||
subject.value = "-1" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is '-0.0'" do | ||
subject.value = "-0.0" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is '-0.1'" do | ||
subject.value = "-0.1" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is true when the attribute is 'true'" do | ||
subject.value = "true" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 'false'" do | ||
subject.value = "false" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is 't'" do | ||
subject.value = "t" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 'f'" do | ||
subject.value = "f" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is 'T'" do | ||
subject.value = "T" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 'F'" do | ||
subject.value = "F" | ||
subject.value?.should == false | ||
end | ||
|
||
it "is true when the attribute is 'TRUE'" do | ||
subject.value = "TRUE" | ||
subject.value?.should == true | ||
end | ||
|
||
it "is false when the attribute is 'FALSE" do | ||
subject.value = "FALSE" | ||
subject.value?.should == false | ||
end | ||
end | ||
end | ||
end |