coercible-1.0.0/0000755000175000017500000000000012304121575013015 5ustar boutilboutilcoercible-1.0.0/coercible.gemspec0000644000175000017500000000152612304121575016315 0ustar boutilboutil# -*- encoding: utf-8 -*- lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'coercible/version' Gem::Specification.new do |gem| gem.name = "coercible" gem.version = Coercible::VERSION gem.authors = ["Piotr Solnica"] gem.email = ["piotr.solnica@gmail.com"] gem.description = %q{Powerful, flexible and configurable coercion library. And nothing more.} gem.summary = gem.description gem.homepage = "https://github.com/solnic/coercible" gem.license = "MIT" gem.files = `git ls-files`.split($/) gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ["lib"] gem.add_dependency 'descendants_tracker', '~> 0.0.1' end coercible-1.0.0/spec/0000755000175000017500000000000012304121575013747 5ustar boutilboutilcoercible-1.0.0/spec/unit/0000755000175000017500000000000012304121575014726 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/0000755000175000017500000000000012304121575016655 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/0000755000175000017500000000000012304121575020277 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/string/0000755000175000017500000000000012304121575021605 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/string/to_symbol_spec.rb0000644000175000017500000000025712304121575025157 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_symbol' do subject { described_class.new.to_symbol(value) } let(:value) { 'value' } it { should be(:value) } end coercible-1.0.0/spec/unit/coercible/coercer/string/to_constant_spec.rb0000644000175000017500000000211512304121575025476 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_constant' do subject { object.to_constant(string) } let(:object) { described_class.new } context 'with a non-namespaced name' do let(:string) { 'String' } it { should be(String) } end context 'with a non-namespaced qualified name' do let(:string) { '::String' } it { should be(String) } end context 'with a namespaced name' do let(:string) { 'Coercible::Coercer::String' } it { should be(Coercer::String) } end context 'with a namespaced qualified name' do let(:string) { '::Coercible::Coercer::String' } it { should be(Coercer::String) } end context 'with a name outside of the namespace' do let(:string) { 'Virtus::Object' } specify { expect { subject }.to raise_error(NameError) } end context 'when the name is unknown' do let(:string) { 'Unknown' } specify { expect { subject }.to raise_error(NameError) } end context 'when the name is invalid' do let(:string) { 'invalid' } specify { expect { subject }.to raise_error(NameError) } end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_datetime_spec.rb0000644000175000017500000000230512304121575025442 0ustar boutilboutilrequire 'spec_helper' shared_examples_for 'a correct datetime object' do it { should be_instance_of(DateTime) } its(:year) { should == year } its(:month) { should == month } its(:day) { should == day } its(:hour) { should == hour } its(:min) { should == min } its(:sec) { should == sec } end describe Coercer::String, '.to_datetime' do subject { object.to_datetime(string) } let(:object) { described_class.new } context 'with a valid date string' do let(:year) { 2011 } let(:month) { 7 } let(:day) { 22 } context 'not including time part' do let(:string) { "July, #{day}th, #{year}" } let(:hour) { 0 } let(:min) { 0 } let(:sec) { 0 } it_should_behave_like 'a correct datetime object' end context 'including time part' do let(:string) { "July, #{day}, #{year}, #{hour}:#{min}:#{sec}" } let(:hour) { 13 } let(:min) { 44 } let(:sec) { 50 } it_should_behave_like 'a correct datetime object' end end context 'with an invalid date time string' do let(:string) { 'non-datetime' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_decimal_spec.rb0000644000175000017500000000251012304121575025242 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_decimal' do subject { object.to_decimal(string) } let(:object) { described_class.new } { '1' => BigDecimal('1.0'), '+1' => BigDecimal('1.0'), '-1' => BigDecimal('-1.0'), '1.0' => BigDecimal('1.0'), '1.0e+1' => BigDecimal('10.0'), '1.0e-1' => BigDecimal('0.1'), '1.0E+1' => BigDecimal('10.0'), '1.0E-1' => BigDecimal('0.1'), '+1.0' => BigDecimal('1.0'), '+1.0e+1' => BigDecimal('10.0'), '+1.0e-1' => BigDecimal('0.1'), '+1.0E+1' => BigDecimal('10.0'), '+1.0E-1' => BigDecimal('0.1'), '-1.0' => BigDecimal('-1.0'), '-1.0e+1' => BigDecimal('-10.0'), '-1.0e-1' => BigDecimal('-0.1'), '-1.0E+1' => BigDecimal('-10.0'), '-1.0E-1' => BigDecimal('-0.1'), '.1' => BigDecimal('0.1'), '.1e+1' => BigDecimal('1.0'), '.1e-1' => BigDecimal('0.01'), '.1E+1' => BigDecimal('1.0'), '.1E-1' => BigDecimal('0.01'), }.each do |value, expected| context "with #{value.inspect}" do let(:string) { value } it { should be_instance_of(BigDecimal) } it { should eql(expected) } end end context 'with an invalid decimal string' do let(:string) { 'non-decimal' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/string/class_methods/0000755000175000017500000000000012304121575024435 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/string/class_methods/config_spec.rb0000644000175000017500000000025012304121575027236 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.config' do subject { described_class.config } its(:boolean_map) { should be(described_class::BOOLEAN_MAP) } end coercible-1.0.0/spec/unit/coercible/coercer/string/to_time_spec.rb0000644000175000017500000000225012304121575024603 0ustar boutilboutilrequire 'spec_helper' shared_examples_for 'a correct time object' do it { should be_instance_of(Time) } its(:year) { should == year } its(:month) { should == month } its(:day) { should == day } its(:hour) { should == hour } its(:min) { should == min } its(:sec) { should == sec } end describe Coercer::String, '.to_time' do subject { object.to_time(string) } let(:object) { described_class.new } context 'with a valid time string' do let(:year) { 2011 } let(:month) { 7 } let(:day) { 22 } context 'not including time part' do let(:string) { "July, #{day}th, #{year}" } let(:hour) { 0 } let(:min) { 0 } let(:sec) { 0 } it_should_behave_like 'a correct time object' end context 'including time part' do let(:string) { "July, #{day}, #{year}, #{hour}:#{min}:#{sec}" } let(:hour) { 13 } let(:min) { 44 } let(:sec) { 50 } it_should_behave_like 'a correct time object' end end context 'with an invalid date time string' do let(:string) { '2999' } specify do expect { subject }.to raise_error(UnsupportedCoercion) end end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_integer_spec.rb0000644000175000017500000000315412304121575025306 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_integer' do subject { described_class.new.to_integer(string) } min_float = Float::MIN max_float = (Float::MAX / 10).to_s.to_f # largest float that can be parsed { '1' => 1, '+1' => 1, '-1' => -1, '1.0' => 1, '1.0e+1' => 10, '1.0e-1' => 0, '1.0E+1' => 10, '1.0E-1' => 0, '+1.0' => 1, '+1.0e+1' => 10, '+1.0e-1' => 0, '+1.0E+1' => 10, '+1.0E-1' => 0, '-1.0' => -1, '-1.0e+1' => -10, '-1.0e-1' => 0, '-1.0E+1' => -10, '-1.0E-1' => 0, '.1' => 0, '.1e+1' => 1, '.1e-1' => 0, '.1E+1' => 1, '.1E-1' => 0, '1e1' => 10, '1E+1' => 10, '+1e-1' => 0, '-1E1' => -10, '-1e-1' => 0, min_float.to_s => min_float.to_i, max_float.to_s => max_float.to_i, }.each do |value, expected| context "with #{value.inspect}" do let(:string) { value } it { should be_kind_of(Integer) } it { should eql(expected) } end end context 'with an invalid integer string' do let(:string) { 'non-integer' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end context 'when integer string is big' do let(:string) { '334490140000101135' } it { should == 334490140000101135 } end context 'string starts with e' do let(:string) { 'e1' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_float_spec.rb0000644000175000017500000000233612304121575024757 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_float' do subject { described_class.new.to_float(string) } { '1' => 1.0, '+1' => 1.0, '-1' => -1.0, '1.0' => 1.0, '1.0e+1' => 10.0, '1.0e-1' => 0.1, '1.0E+1' => 10.0, '1.0E-1' => 0.1, '+1.0' => 1.0, '+1.0e+1' => 10.0, '+1.0e-1' => 0.1, '+1.0E+1' => 10.0, '+1.0E-1' => 0.1, '-1.0' => -1.0, '-1.0e+1' => -10.0, '-1.0e-1' => -0.1, '-1.0E+1' => -10.0, '-1.0E-1' => -0.1, '.1' => 0.1, '.1e+1' => 1.0, '.1e-1' => 0.01, '.1E+1' => 1.0, '.1E-1' => 0.01, '1e1' => 10.0, '1E+1' => 10.0, '+1e-1' => 0.1, '-1E1' => -10.0, '-1e-1' => -0.1, }.each do |value, expected| context "with #{value.inspect}" do let(:string) { value } it { should be_instance_of(Float) } it { should eql(expected) } end end context 'with an invalid float string' do let(:string) { 'non-float' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end context 'string starts with e' do let(:string) { 'e1' } specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_boolean_spec.rb0000644000175000017500000000120712304121575025265 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_boolean' do subject { object.to_boolean(string) } let(:object) { described_class.new } %w[ 1 on ON t true T TRUE y yes Y YES ].each do |value| context "with #{value.inspect}" do let(:string) { value } it { should be(true) } end end %w[ 0 off OFF f false F FALSE n no N NO ].each do |value| context "with #{value.inspect}" do let(:string) { value } it { should be(false) } end end context 'with an invalid boolean string' do let(:string) { 'non-boolean' } specify do expect { subject }.to raise_error end end end coercible-1.0.0/spec/unit/coercible/coercer/string/to_date_spec.rb0000644000175000017500000000104012304121575024556 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '.to_date' do subject { object.to_date(string) } let(:object) { described_class.new } context 'with a valid date string' do let(:string) { 'July, 22th, 2011' } it { should be_instance_of(Date) } its(:year) { should == 2011 } its(:month) { should == 7 } its(:day) { should == 22 } end context 'with an invalid date string' do let(:string) { 'non-date' } specify do expect { subject }.to raise_error(UnsupportedCoercion) end end end coercible-1.0.0/spec/unit/coercible/coercer/string/coerced_predicate_spec.rb0000644000175000017500000000037612304121575026576 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { 'a string' } let(:non_primitive_value) { :a_symbol } end end coercible-1.0.0/spec/unit/coercible/coercer/date_time/0000755000175000017500000000000012304121575022232 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/date_time/to_datetime_spec.rb0000644000175000017500000000037212304121575026071 0ustar boutilboutilrequire 'spec_helper' describe Coercer::DateTime, '.to_datetime' do subject { object.to_datetime(date_time) } let(:object) { described_class.new } let(:date_time) { DateTime.new(2012, 1, 1) } it { should equal(date_time) } end coercible-1.0.0/spec/unit/coercible/coercer/date_time/to_time_spec.rb0000644000175000017500000000123412304121575025231 0ustar boutilboutilrequire 'spec_helper' describe Coercer::DateTime, '.to_time' do subject { object.to_time(date_time) } let(:object) { described_class.new } let(:date_time) { DateTime.new(2011, 1, 1) } context 'when DateTime does not support #to_time' do if RUBY_VERSION < '1.9' before do date_time.should_not respond_to(:to_time) end end it { should be_instance_of(Time) } it { should eql(Time.local(2011, 1, 1)) } end context 'when DateTime supports #to_time' do let(:time) { Time.local(2011, 1, 1) } before do date_time.stub!(:to_time).and_return(time) end it { should equal(time) } end end coercible-1.0.0/spec/unit/coercible/coercer/date_time/to_string_spec.rb0000644000175000017500000000046112304121575025602 0ustar boutilboutilrequire 'spec_helper' describe Coercer::DateTime, '.to_string' do subject { object.to_string(date_time) } let(:object) { described_class.new } let(:date_time) { DateTime.new(2011, 1, 1, 0, 0, 0, 0) } it { should be_instance_of(String) } it { should eql('2011-01-01T00:00:00+00:00') } end coercible-1.0.0/spec/unit/coercible/coercer/date_time/to_date_spec.rb0000644000175000017500000000123012304121575025204 0ustar boutilboutilrequire 'spec_helper' describe Coercer::DateTime, '.to_date' do subject { object.to_date(date_time) } let(:object) { described_class.new } let(:date_time) { DateTime.new(2011, 1, 1) } context 'when DateTime does not support #to_date' do if RUBY_VERSION < '1.9' before do date_time.should_not respond_to(:to_date) end end it { should be_instance_of(Date) } it { should eql(Date.new(2011, 1, 1)) } end context 'when DateTime supports #to_date' do let(:date) { Date.new(2011, 1, 1) } before do date_time.stub!(:to_date).and_return(date) end it { should equal(date) } end end coercible-1.0.0/spec/unit/coercible/coercer/date_time/coerced_predicate_spec.rb0000644000175000017500000000040012304121575027207 0ustar boutilboutilrequire 'spec_helper' describe Coercer::DateTime, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { DateTime.new } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/object/0000755000175000017500000000000012304121575021545 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/object/to_integer_spec.rb0000644000175000017500000000102412304121575025240 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '.to_integer' do subject { object.to_integer(value) } let(:object) { described_class.new } let(:value) { stub('value') } context 'when the value responds to #to_int' do let(:coerced) { stub('coerced') } before do value.should_receive(:to_int).with().and_return(coerced) end it { should be(coerced) } end context 'when the value does not respond to #to_int' do specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/object/to_array_spec.rb0000644000175000017500000000227412304121575024731 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '.to_array' do subject { object.to_array(value) } let(:object) { described_class.new } let(:value) { Object.new } let(:coerced) { [ value ] } context 'when the value responds to #to_ary' do before do value.should_receive(:to_ary).with().and_return(coerced) end it { should be(coerced) } it 'does not call #to_a if #to_ary is available' do value.should_not_receive(:to_a) subject end end context 'when the value responds to #to_a but not #to_ary' do before do value.should_receive(:to_a).with().and_return(coerced) end it { should be(coerced) } end context 'when the value does not respond to #to_ary or #to_a' do it { should be_instance_of(Array) } it { should == coerced } end context 'when the value returns nil from #to_ary' do before do value.should_receive(:to_ary).with().and_return(nil) end it 'calls #to_a as a fallback' do value.should_receive(:to_a).with().and_return(coerced) should be(coerced) end it 'wraps the value in an Array if #to_a is not available' do should == coerced end end end coercible-1.0.0/spec/unit/coercible/coercer/object/to_hash_spec.rb0000644000175000017500000000102112304121575024523 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '.to_hash' do subject { object.to_hash(value) } let(:object) { described_class.new } let(:value) { stub('value') } context 'when the value responds to #to_hash' do let(:coerced) { stub('coerced') } before do value.should_receive(:to_hash).with().and_return(coerced) end it { should be(coerced) } end context 'when the value does not respond to #to_hash' do specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/object/to_string_spec.rb0000644000175000017500000000102212304121575025107 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '.to_string' do subject { object.to_string(value) } let(:object) { described_class.new } let(:value) { Object.new } context 'when the value responds to #to_str' do let(:coerced) { stub('coerced') } before do value.should_receive(:to_str).with().and_return(coerced) end it { should be(coerced) } end context 'when the value does not respond to #to_str' do specify { expect { subject }.to raise_error(UnsupportedCoercion) } end end coercible-1.0.0/spec/unit/coercible/coercer/object/coerced_predicate_spec.rb0000644000175000017500000000031212304121575026524 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '#coerced?' do subject { object.coerced?(value) } let(:object) { described_class.new } let(:value) { 'something' } it { should be(true) } end coercible-1.0.0/spec/unit/coercible/coercer/object/method_missing_spec.rb0000644000175000017500000000076012304121575026120 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '#method_missing' do subject { object.send(method_name, value) } let(:object) { described_class.new } let(:value) { Object.new } context "when method matches coercion method regexp" do let(:method_name) { :to_whatever } it { should be(value) } end context "when method doesn't match coercion method regexp" do let(:method_name) { :not_here } specify { expect { subject }.to raise_error(NoMethodError) } end end coercible-1.0.0/spec/unit/coercible/coercer/object/inspect_spec.rb0000644000175000017500000000031412304121575024547 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Object, '#inspect' do subject { object.inspect } let(:object) { described_class.new } it { should == '#'} end coercible-1.0.0/spec/unit/coercible/coercer/false_class/0000755000175000017500000000000012304121575022556 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/false_class/to_string_spec.rb0000644000175000017500000000042012304121575026121 0ustar boutilboutilrequire 'spec_helper' describe Coercer::FalseClass, '.to_string' do subject { object.to_string(false_class) } let(:object) { described_class.new } let(:false_class) { false } it { should be_instance_of(String) } it { should eql('false') } end coercible-1.0.0/spec/unit/coercible/coercer/false_class/coerced_predicate_spec.rb0000644000175000017500000000037312304121575027544 0ustar boutilboutilrequire 'spec_helper' describe Coercer::FalseClass, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { false } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/element_reader_spec.rb0000644000175000017500000000055012304121575024611 0ustar boutilboutilrequire 'spec_helper' describe Coercer, '#[]' do subject { object[type] } let(:object) { described_class.new } context "with a known type" do let(:type) { ::String } it { should be_instance_of(Coercer::String) } end context "with an unknown type" do let(:type) { Object } it { should be_instance_of(Coercer::Object) } end end coercible-1.0.0/spec/unit/coercible/coercer/numeric/0000755000175000017500000000000012304121575021741 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/numeric/to_decimal_spec.rb0000644000175000017500000000067612304121575025411 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Numeric, '.to_decimal' do subject { object.to_decimal(value) } let(:object) { described_class.new } context "with an object responding to #to_d" do let(:value) { Rational(2, 2) } it { should eql(BigDecimal('1.0')) } end context "with an object not responding to #to_d" do let(:value) { Class.new { def to_s; '1'; end }.new } it { should eql(BigDecimal('1.0')) } end end coercible-1.0.0/spec/unit/coercible/coercer/numeric/to_integer_spec.rb0000644000175000017500000000032512304121575025437 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Numeric, '.to_integer' do subject { object.to_integer(numeric) } let(:object) { described_class.new } let(:numeric) { Rational(2, 2) } it { should eql(1) } end coercible-1.0.0/spec/unit/coercible/coercer/numeric/to_float_spec.rb0000644000175000017500000000032312304121575025105 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Numeric, '.to_float' do subject { object.to_float(numeric) } let(:object) { described_class.new } let(:numeric) { Rational(2, 2) } it { should eql(1.0) } end coercible-1.0.0/spec/unit/coercible/coercer/numeric/to_string_spec.rb0000644000175000017500000000043512304121575025312 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Numeric, '.to_string' do subject { object.to_string(numeric) } let(:object) { described_class.new } let(:numeric) { Rational(2, 2) } let(:coerced_value) { RUBY_VERSION < '1.9' ? '1' : '1/1' } it { should eql(coerced_value) } end coercible-1.0.0/spec/unit/coercible/coercer/class_methods/0000755000175000017500000000000012304121575023127 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/class_methods/new_spec.rb0000644000175000017500000000051212304121575025255 0ustar boutilboutilrequire 'spec_helper' describe Coercer, '.new' do subject { described_class.new(&block) } let(:block) { Proc.new {} } it { should be_instance_of(Coercer) } its(:config) { should be_instance_of(Coercible::Configuration) } its(:config) { should respond_to(:string) } its(:config) { should respond_to(:string=) } end coercible-1.0.0/spec/unit/coercible/coercer/integer/0000755000175000017500000000000012304121575021734 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/integer/to_datetime_spec.rb0000644000175000017500000000044112304121575025570 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '#to_datetime' do subject { object.to_datetime(value) } let(:object) { described_class.new } let(:value) { 1361036672 } specify do expect(subject.strftime('%Y-%m-%d %H:%M:%S.%L')).to eql('2013-02-16 17:44:32.000') end end coercible-1.0.0/spec/unit/coercible/coercer/integer/to_decimal_spec.rb0000644000175000017500000000041612304121575025374 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '.to_decimal' do subject { object.to_decimal(fixnum) } let(:object) { described_class.new } let(:fixnum) { 1 } it { should be_instance_of(BigDecimal) } it { should eql(BigDecimal('1.0')) } end coercible-1.0.0/spec/unit/coercible/coercer/integer/to_integer_spec.rb0000644000175000017500000000025312304121575025432 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '.to_integer' do subject { described_class.new.to_integer(value) } let(:value) { 1 } it { should be(value) } end coercible-1.0.0/spec/unit/coercible/coercer/integer/to_float_spec.rb0000644000175000017500000000036712304121575025110 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '.to_float' do subject { object.to_float(fixnum) } let(:object) { described_class.new } let(:fixnum) { 1 } it { should be_instance_of(Float) } it { should eql(1.0) } end coercible-1.0.0/spec/unit/coercible/coercer/integer/to_boolean_spec.rb0000644000175000017500000000076512304121575025424 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '.to_boolean' do subject { object.to_boolean(fixnum) } let(:object) { described_class.new } context 'when the fixnum is 1' do let(:fixnum) { 1 } it { should be(true) } end context 'when the fixnum is 0' do let(:fixnum) { 0 } it { should be(false) } end context 'when the fixnum is not 1 or 0' do let(:fixnum) { -1 } specify do expect { subject }.to raise_error(UnsupportedCoercion) end end end coercible-1.0.0/spec/unit/coercible/coercer/integer/to_string_spec.rb0000644000175000017500000000037512304121575025310 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '.to_string' do subject { object.to_string(integer) } let(:object) { described_class.new } let(:integer) { 1 } it { should be_instance_of(String) } it { should eql('1') } end coercible-1.0.0/spec/unit/coercible/coercer/integer/coerced_predicate_spec.rb0000644000175000017500000000036012304121575026716 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { 1 } let(:non_primitive_value) { 1.0 } end end coercible-1.0.0/spec/unit/coercible/coercer/integer/datetime_proc_spec.rb0000644000175000017500000000062512304121575026115 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '#datetime_proc' do subject { object.datetime_proc } let(:object) { described_class.new } context "with Rubinius" do before do unless Coercible.rbx? Coercible.stub!(:rbx? => true) end end it { should be_instance_of(Proc) } end context "with other Ruby VMs" do it { should be_instance_of(Proc) } end end coercible-1.0.0/spec/unit/coercible/coercer/integer/datetime_format_spec.rb0000644000175000017500000000074012304121575026440 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer, '#datetime_format' do subject { object.datetime_format } let(:object) { described_class.new } context "with Rubinius" do before do unless Coercible.rbx? Coercible.stub!(:rbx? => true) end end it { should == '%Q' } end context "with other Ruby VMs" do before do if Coercible.rbx? Coercible.stub!(:rbx? => false) end end it { should == '%s' } end end coercible-1.0.0/spec/unit/coercible/coercer/hash/0000755000175000017500000000000012304121575021222 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/hash/to_datetime_spec.rb0000644000175000017500000000201712304121575025057 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Hash, '.to_datetime' do subject { object.to_datetime(hash) } let(:object) { described_class.new } context 'when time segments are missing' do let(:time_now) { Time.local(2011, 1, 1) } let(:hash) { {} } before do Time.stub!(:now).and_return(time_now) # freeze time end it { should be_instance_of(DateTime) } it 'uses the Time now to populate the segments' do should eql(DateTime.new(2011, 1, 1)) end end context 'when time segments are integers' do let(:hash) { { :year => 2011, :month => 1, :day => 1, :hour => 1, :min => 1, :sec => 1 } } it { should be_instance_of(DateTime) } it { should eql(DateTime.new(2011, 1, 1, 1, 1, 1)) } end context 'when time segments are strings' do let(:hash) { { :year => '2011', :month => '1', :day => '1', :hour => '1', :min => '1', :sec => '1' } } it { should be_instance_of(DateTime) } it { should eql(DateTime.new(2011, 1, 1, 1, 1, 1)) } end end coercible-1.0.0/spec/unit/coercible/coercer/hash/to_time_spec.rb0000644000175000017500000000174712304121575024232 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Hash, '.to_time' do subject { object.to_time(hash) } let(:object) { described_class.new } context 'when time segments are missing' do let(:time_now) { Time.local(2011, 1, 1) } let(:hash) { {} } before do Time.stub!(:now).and_return(time_now) # freeze time end it { should be_instance_of(Time) } it 'uses the Time now to populate the segments' do should eql(time_now) end end context 'when time segments are integers' do let(:hash) { { :year => 2011, :month => 1, :day => 1, :hour => 1, :min => 1, :sec => 1 } } it { should be_instance_of(Time) } it { should eql(Time.local(2011, 1, 1, 1, 1, 1)) } end context 'when time segments are strings' do let(:hash) { { :year => '2011', :month => '1', :day => '1', :hour => '1', :min => '1', :sec => '1' } } it { should be_instance_of(Time) } it { should eql(Time.local(2011, 1, 1, 1, 1, 1)) } end end coercible-1.0.0/spec/unit/coercible/coercer/hash/to_date_spec.rb0000644000175000017500000000162312304121575024202 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Hash, '.to_date' do subject { object.to_date(hash) } let(:object) { described_class.new } context 'when time segments are missing' do let(:time_now) { Time.local(2011, 1, 1) } let(:hash) { {} } before do Time.stub!(:now).and_return(time_now) # freeze time end it { should be_instance_of(Date) } it 'uses the Time now to populate the segments' do should eql(Date.new(2011, 1, 1)) end end context 'when time segments are integers' do let(:hash) { { :year => 2011, :month => 1, :day => 1 } } it { should be_instance_of(Date) } it { should eql(Date.new(2011, 1, 1)) } end context 'when time segments are strings' do let(:hash) { { :year => '2011', :month => '1', :day => '1' } } it { should be_instance_of(Date) } it { should eql(Date.new(2011, 1, 1)) } end end coercible-1.0.0/spec/unit/coercible/coercer/hash/coerced_predicate_spec.rb0000644000175000017500000000037012304121575026205 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Hash, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { Hash.new } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/string_spec.rb0000644000175000017500000000032712304121575023146 0ustar boutilboutilrequire 'spec_helper' describe Coercer::String do it_behaves_like 'Configurable' do describe '.config_name' do subject { described_class.config_name } it { should be(:string) } end end end coercible-1.0.0/spec/unit/coercible/coercer/time_coercions/0000755000175000017500000000000012304121575023301 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/time_coercions/to_datetime_spec.rb0000644000175000017500000000176612304121575027150 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TimeCoercions, '.to_datetime' do subject { object.to_datetime(value) } let(:object) { coercer.new } let(:coercer) { Class.new(Coercer::Object) { include Coercer::TimeCoercions } } let(:value) { mock('value') } after do Coercer::Object.descendants.delete(coercer) end context 'when the value responds to #to_datetime' do before do object.extend Coercer::TimeCoercions value.should_receive(:to_datetime).and_return(DateTime.new(2011, 1, 1, 0, 0, 0)) end it { should be_instance_of(DateTime) } it { should eql(DateTime.new(2011, 1, 1, 0, 0, 0)) } end context 'when the value does not respond to #to_datetime' do before do object.extend Coercer::TimeCoercions # use a string that DateTime.parse can handle value.should_receive(:to_s).and_return('2011-01-01T00:00:00+00:00') end it { should be_instance_of(DateTime) } it { should eql(DateTime.new(2011, 1, 1, 0, 0, 0)) } end end coercible-1.0.0/spec/unit/coercible/coercer/time_coercions/to_time_spec.rb0000644000175000017500000000166212304121575026305 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TimeCoercions, '.to_time' do subject { object.to_time(value) } let(:object) { coercer.new } let(:coercer) { Class.new(Coercer::Object) { include Coercer::TimeCoercions } } let(:value) { mock('value') } after do Coercer::Object.descendants.delete(coercer) end context 'when the value responds to #to_time' do before do object.extend Coercer::TimeCoercions value.should_receive(:to_time).and_return(Time.utc(2011, 1, 1)) end it { should be_instance_of(Time) } it { should eql(Time.utc(2011, 1, 1)) } end context 'when the value does not respond to #to_time' do before do object.extend Coercer::TimeCoercions # use a string that Time.parse can handle value.should_receive(:to_s).and_return('Sat Jan 01 00:00:00 UTC 2011') end it { should be_instance_of(Time) } it { should eql(Time.utc(2011, 1, 1)) } end end coercible-1.0.0/spec/unit/coercible/coercer/time_coercions/to_string_spec.rb0000644000175000017500000000101212304121575026642 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TimeCoercions, '.to_string' do subject { object.to_string(value) } let(:object) { coercer.new } let(:coercer) { Class.new(Coercer::Object) { include Coercer::TimeCoercions } } let(:value) { mock('value') } after do Coercer::Object.descendants.delete(coercer) end before do object.extend Coercer::TimeCoercions value.should_receive(:to_s).and_return('2011-01-01') end it { should be_instance_of(String) } it { should eql('2011-01-01') } end coercible-1.0.0/spec/unit/coercible/coercer/time_coercions/to_date_spec.rb0000644000175000017500000000151012304121575026254 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TimeCoercions, '.to_date' do subject { object.to_date(value) } let(:object) { coercer.new } let(:coercer) { Class.new(Coercer::Object) { include Coercer::TimeCoercions } } let(:value) { mock('value') } after do Coercer::Object.descendants.delete(coercer) end context 'when the value responds to #to_date' do before do value.should_receive(:to_date).and_return(Date.new(2011, 1, 1)) end it { should be_instance_of(Date) } it { should eql(Date.new(2011, 1, 1)) } end context 'when the value does not respond to #to_date' do before do # use a string that Date.parse can handle value.should_receive(:to_s).and_return('2011-01-01') end it { should be_instance_of(Date) } it { should eql(Date.new(2011, 1, 1)) } end end coercible-1.0.0/spec/unit/coercible/coercer/decimal/0000755000175000017500000000000012304121575021675 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/decimal/to_decimal_spec.rb0000644000175000017500000000027312304121575025336 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Decimal, '.to_decimal' do subject { described_class.new.to_decimal(value) } let(:value) { BigDecimal('1.0') } it { should be(value) } end coercible-1.0.0/spec/unit/coercible/coercer/decimal/to_integer_spec.rb0000644000175000017500000000041212304121575025370 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Decimal, '.to_integer' do subject { object.to_integer(big_decimal) } let(:object) { described_class.new } let(:big_decimal) { BigDecimal('1.0') } it { should be_kind_of(Integer) } it { should eql(1) } end coercible-1.0.0/spec/unit/coercible/coercer/decimal/to_float_spec.rb0000644000175000017500000000041212304121575025040 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Decimal, '.to_float' do subject { object.to_float(big_decimal) } let(:object) { described_class.new } let(:big_decimal) { BigDecimal('1.0') } it { should be_instance_of(Float) } it { should eql(1.0) } end coercible-1.0.0/spec/unit/coercible/coercer/decimal/to_string_spec.rb0000644000175000017500000000041712304121575025246 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Decimal, '.to_string' do subject { object.to_string(big_decimal) } let(:object) { described_class.new } let(:big_decimal) { BigDecimal('1.0') } it { should be_instance_of(String) } it { should eql('1.0') } end coercible-1.0.0/spec/unit/coercible/coercer/decimal/coerced_predicate_spec.rb0000644000175000017500000000040412304121575026656 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Decimal, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { BigDecimal('1.2') } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/integer_spec.rb0000644000175000017500000000033112304121575023270 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Integer do it_behaves_like 'Configurable' do describe '.config_name' do subject { described_class.config_name } it { should be(:integer) } end end end coercible-1.0.0/spec/unit/coercible/coercer/symbol/0000755000175000017500000000000012304121575021604 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/symbol/to_string_spec.rb0000644000175000017500000000037512304121575025160 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Symbol, '.to_string' do subject { object.to_string(symbol) } let(:object) { described_class.new } let(:symbol) { :piotr } it { should be_instance_of(String) } it { should eql('piotr') } end coercible-1.0.0/spec/unit/coercible/coercer/symbol/coerced_predicate_spec.rb0000644000175000017500000000037112304121575026570 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Symbol, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { :symbol } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/array/0000755000175000017500000000000012304121575021415 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/array/to_set_spec.rb0000644000175000017500000000042312304121575024250 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Array, '#to_set' do subject { object.to_set(array) } let(:object) { described_class.new } let(:array) { [ 'a', 1, 'b', 2, 'b', 1, 'a', 2 ] } it { should be_instance_of(Set) } it { should eql(Set[ 'a', 1, 'b', 2 ]) } end coercible-1.0.0/spec/unit/coercible/coercer/array/coerced_predicate_spec.rb0000644000175000017500000000037412304121575026404 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Array, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { [ 1, 2, 3 ] } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/true_class/0000755000175000017500000000000012304121575022443 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/true_class/to_string_spec.rb0000644000175000017500000000041312304121575026010 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TrueClass, '.to_string' do subject { object.to_string(true_class) } let(:object) { described_class.new } let(:true_class) { true } it { should be_instance_of(String) } it { should eql('true') } end coercible-1.0.0/spec/unit/coercible/coercer/true_class/coerced_predicate_spec.rb0000644000175000017500000000036712304121575027434 0ustar boutilboutilrequire 'spec_helper' describe Coercer::TrueClass, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { true } let(:non_primitive_value) { false } end end coercible-1.0.0/spec/unit/coercible/coercer/float/0000755000175000017500000000000012304121575021404 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/float/to_datetime_spec.rb0000644000175000017500000000043712304121575025245 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '#to_float' do subject { object.to_datetime(value) } let(:object) { described_class.new } let(:value) { 1361036672.12 } specify do expect(subject.strftime('%Y-%m-%d %H:%M:%S.%L')).to eql('2013-02-16 17:44:32.120') end end coercible-1.0.0/spec/unit/coercible/coercer/float/to_decimal_spec.rb0000644000175000017500000000041312304121575025041 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '.to_decimal' do subject { object.to_decimal(float) } let(:object) { described_class.new } let(:float) { 1.0 } it { should be_instance_of(BigDecimal) } it { should eql(BigDecimal('1.0')) } end coercible-1.0.0/spec/unit/coercible/coercer/float/to_integer_spec.rb0000644000175000017500000000036412304121575025105 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '.to_integer' do subject { object.to_integer(float) } let(:object) { described_class.new } let(:float) { 1.0 } it { should be_kind_of(Integer) } it { should eql(1) } end coercible-1.0.0/spec/unit/coercible/coercer/float/to_float_spec.rb0000644000175000017500000000024712304121575024555 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '.to_float' do subject { described_class.new.to_float(value) } let(:value) { 1.0 } it { should be(value) } end coercible-1.0.0/spec/unit/coercible/coercer/float/to_string_spec.rb0000644000175000017500000000037112304121575024754 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '.to_string' do subject { object.to_string(float) } let(:object) { described_class.new } let(:float) { 1.0 } it { should be_instance_of(String) } it { should eql('1.0') } end coercible-1.0.0/spec/unit/coercible/coercer/float/coerced_predicate_spec.rb0000644000175000017500000000036412304121575026372 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Float, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { 1.2 } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/configurable/0000755000175000017500000000000012304121575022737 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/configurable/config_spec.rb0000644000175000017500000000124012304121575025540 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Configurable, '.config' do subject { object.config(&block) } let(:object) { Class.new { extend Coercer::Configurable, Options config_keys [ :one, :two ] } } let(:block) { Proc.new { |config| config.test } } let(:configuration) { mock('configuration') } let(:configuration_class) { mock('configuration_class') } before do object.stub!(:configuration_class => configuration_class) configuration_class.should_receive(:build).with(object.config_keys). and_return(configuration) configuration.should_receive(:test) end it { should be(configuration) } end coercible-1.0.0/spec/unit/coercible/coercer/configurable/config_name_spec.rb0000644000175000017500000000047612304121575026552 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Configurable, '.config_name' do subject { object.config_name } let(:object) { Class.new { extend Coercer::Configurable, Options config_keys [ :one, :two ] def self.name "Some::Class::Test" end } } it { should be(:test) } end coercible-1.0.0/spec/unit/coercible/coercer/date/0000755000175000017500000000000012304121575021214 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/date/to_datetime_spec.rb0000644000175000017500000000123712304121575025054 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Date, '.to_datetime' do subject { object.to_datetime(date) } let(:object) { described_class.new } let(:date) { Date.new(2011, 1, 1) } context 'when Date does not support #to_datetime' do if RUBY_VERSION < '1.9' before do date.should_not respond_to(:to_datetime) end end it { should be_instance_of(DateTime) } it { should eql(DateTime.new(2011, 1, 1)) } end context 'when Date supports #to_datetime' do let(:datetime) { DateTime.new(2011, 1, 1) } before do date.stub!(:to_datetime).and_return(datetime) end it { should equal(datetime) } end end coercible-1.0.0/spec/unit/coercible/coercer/date/to_time_spec.rb0000644000175000017500000000041412304121575024212 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Date, '.to_time' do subject { object.to_time(date) } let(:object) { described_class.new } let(:date) { Date.new(2011, 1, 1) } it { should be_instance_of(Time) } it { should eql(Time.local(2011, 1, 1)) } end coercible-1.0.0/spec/unit/coercible/coercer/date/to_string_spec.rb0000644000175000017500000000041012304121575024556 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Date, '.to_string' do subject { object.to_string(date) } let(:object) { described_class.new } let(:date) { Date.new(2011, 1, 1) } it { should be_instance_of(String) } it { should eql('2011-01-01') } end coercible-1.0.0/spec/unit/coercible/coercer/date/to_date_spec.rb0000644000175000017500000000032612304121575024173 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Date, '.to_date' do subject { object.to_date(date) } let(:object) { described_class.new } let(:date) { Date.new(2012, 1, 1) } it { should equal(date) } end coercible-1.0.0/spec/unit/coercible/coercer/date/coerced_predicate_spec.rb0000644000175000017500000000037012304121575026177 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Date, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { Date.new } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/coercer/time/0000755000175000017500000000000012304121575021235 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/coercer/time/to_time_spec.rb0000644000175000017500000000033212304121575024232 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Time, '.to_time' do subject { object.to_time(time) } let(:object) { described_class.new } let(:time) { Time.local(2012, 1, 1) } it { should equal(time) } end coercible-1.0.0/spec/unit/coercible/coercer/time/to_integer_spec.rb0000644000175000017500000000031712304121575024734 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Time, '.to_integer' do subject { described_class.new.to_integer(value) } let(:time) { Time.now } let(:value) { time } it { should eql(time.to_i) } end coercible-1.0.0/spec/unit/coercible/coercer/time/coerced_predicate_spec.rb0000644000175000017500000000037012304121575026220 0ustar boutilboutilrequire 'spec_helper' describe Coercer::Time, '#coerced?' do let(:object) { described_class.new } it_behaves_like 'Coercible::Coercer#coerced?' do let(:primitive_value) { Time.now } let(:non_primitive_value) { 'other' } end end coercible-1.0.0/spec/unit/coercible/configuration/0000755000175000017500000000000012304121575021524 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/configuration/class_methods/0000755000175000017500000000000012304121575024354 5ustar boutilboutilcoercible-1.0.0/spec/unit/coercible/configuration/class_methods/build_spec.rb0000644000175000017500000000050312304121575027010 0ustar boutilboutilrequire 'spec_helper' describe Configuration, '.build' do subject { described_class.build(keys) } let(:keys) { [ :foo, :bar ] } it { should be_instance_of(described_class) } it { should respond_to(:foo) } it { should respond_to(:foo=) } it { should respond_to(:bar) } it { should respond_to(:bar=) } end coercible-1.0.0/spec/shared/0000755000175000017500000000000012304121575015215 5ustar boutilboutilcoercible-1.0.0/spec/shared/unit/0000755000175000017500000000000012304121575016174 5ustar boutilboutilcoercible-1.0.0/spec/shared/unit/coerced_predicate.rb0000644000175000017500000000046512304121575022152 0ustar boutilboutilshared_examples_for 'Coercible::Coercer#coerced?' do context "with a primitive value" do subject { object.coerced?(primitive_value) } it { should be(true) } end context "with a non-primitive value" do subject { object.coerced?(non_primitive_value) } it { should be(false) } end end coercible-1.0.0/spec/shared/unit/configurable.rb0000644000175000017500000000120712304121575021161 0ustar boutilboutilshared_examples_for 'Configurable' do describe '.config_name' do subject { described_class.config_name } it { should be_instance_of(Symbol) } end describe '.config_keys' do subject { described_class.config_keys } it { should be_instance_of(Array) } it { should_not be_empty } end describe '.config' do subject { described_class.config } it { should be_instance_of(Coercible::Configuration) } it 'responds to configuration keys' do described_class.config_keys.each do |key| expect(subject).to respond_to(key) expect(subject).to respond_to("#{key}=") end end end end coercible-1.0.0/spec/integration/0000755000175000017500000000000012304121575016272 5ustar boutilboutilcoercible-1.0.0/spec/integration/configuring_coercers_spec.rb0000644000175000017500000000062412304121575024032 0ustar boutilboutilrequire 'spec_helper' describe "Configuring coercers" do it "allows to configure coercers" do coercer = Coercer.new do |config| config.string.boolean_map = { 'yup' => true, 'nope' => false } end expect(coercer[String].to_boolean('yup')).to be(true) expect(coercer[String].to_boolean('nope')).to be(false) expect { coercer[String].to_boolean('1') }.to raise_error end end coercible-1.0.0/spec/spec_helper.rb0000644000175000017500000000175212304121575016572 0ustar boutilboutilif ENV['COVERAGE'] require 'simplecov' SimpleCov.start do add_filter "/spec/" add_filter "lib/support" end end require 'coercible' include Coercible ENV['TZ'] = 'UTC' Dir[File.expand_path('../shared/**/*.rb', __FILE__)].each { |file| require file } # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # Require this file using `require "spec_helper"` to ensure that it is only # loaded once. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| config.treat_symbols_as_metadata_keys_with_true_values = true config.run_all_when_everything_filtered = true config.filter_run :focus # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = 'random' end coercible-1.0.0/Rakefile0000644000175000017500000000005412304121575014461 0ustar boutilboutilrequire 'devtools' Devtools.init_rake_tasks coercible-1.0.0/Gemfile.devtools0000644000175000017500000000265612304121575016157 0ustar boutilboutil# encoding: utf-8 group :development do gem 'rake', '~> 10.0.3' gem 'rspec', '~> 2.13.0' gem 'yard', '~> 0.8.5' end group :yard do gem 'kramdown', '~> 0.14.2' end group :guard do gem 'guard', '~> 1.6.2' gem 'guard-bundler', '~> 1.0.0' gem 'guard-rspec', '~> 2.5.0' # file system change event handling gem 'rb-fchange', '~> 0.0.6', :require => false gem 'rb-fsevent', '~> 0.9.3', :require => false gem 'rb-inotify', '~> 0.9.0', :require => false gem 'listen', '~> 0.7.3' # notification handling gem 'libnotify', '~> 0.8.0', :require => false gem 'rb-notifu', '~> 0.0.4', :require => false gem 'terminal-notifier-guard', '~> 1.5.3', :require => false end group :metrics do gem 'flay', '~> 2.1.0' gem 'flog', '~> 3.2.2' gem 'reek', '~> 1.3.1', :git => 'https://github.com/troessner/reek.git' gem 'metric_fu-roodi', '~> 2.2.1' gem 'yardstick', '~> 0.9.4' platforms :ruby_18, :ruby_19 do # this indirectly depends on ffi which does not build on ruby-head gem 'yard-spellcheck', '~> 0.1.5' end platforms :mri_19, :rbx do gem 'mutant', '~> 0.2.20' end platforms :mri_19 do gem 'simplecov', '~> 0.7.1' end platforms :rbx do gem 'pelusa', '~> 0.2.2' end end group :benchmarks do gem 'rbench', '~> 0.2.3' end platform :jruby do group :jruby do gem 'jruby-openssl', '~> 0.8.2' end end coercible-1.0.0/checksums.yaml.gz0000444000175000017500000000041312304121575016301 0ustar boutilboutil‹õ¦Re1V@Dûœ"ˆØ……tvöžÖÊÆ—ÊÓ‹)µ›fæÿ¹Ýn—÷·W¼_®×ÏzxúÃ_>¾ï×VET£†FŒ¢-´$“öªÌ9ÑGtïÙyø×³—g[­ÅP8UÕÅöq^§–qA­02Í_*#ýãBM®mˆÕÈ™D‹`V”ÚtqD‹„.€` žbp@÷ö£pRgn3‰+µ¢pô©^×Ékw1±ï õ÷09ôxzcÌLHcØ6Z:P¼Ü‡¦ˆzïŽØ-›ýQÁ­‰dH9R©À*¡œ,:FÇ6¢{Éh§£žÅŠ'Ê‹€·Œ2…Ë´FÑ:¢coercible-1.0.0/Guardfile0000644000175000017500000000467012304121575014651 0ustar boutilboutil# A sample Guardfile # More info at https://github.com/guard/guard#readme guard 'bundler' do watch('Gemfile') # Uncomment next line if Gemfile contain `gemspec' command # watch(/^.+\.gemspec/) end guard 'rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('config/routes.rb') { "spec/routing" } watch('app/controllers/application_controller.rb') { "spec/controllers" } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end guard 'bundler' do watch('Gemfile') # Uncomment next line if Gemfile contain `gemspec' command # watch(/^.+\.gemspec/) end guard 'rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('config/routes.rb') { "spec/routing" } watch('app/controllers/application_controller.rb') { "spec/controllers" } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end coercible-1.0.0/metadata.yml0000644000175000017500000002647112304121575015332 0ustar boutilboutil--- !ruby/object:Gem::Specification name: coercible version: !ruby/object:Gem::Version version: 1.0.0 platform: ruby authors: - Piotr Solnica autorequire: bindir: bin cert_chain: [] date: 2013-12-10 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: descendants_tracker requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.1 description: Powerful, flexible and configurable coercion library. And nothing more. email: - piotr.solnica@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - .gitignore - .rspec - .travis.yml - Changelog.md - Gemfile - Gemfile.devtools - Guardfile - LICENSE.txt - README.md - Rakefile - coercible.gemspec - config/flay.yml - config/flog.yml - config/mutant.yml - config/roodi.yml - config/site.reek - lib/coercible.rb - lib/coercible/coercer.rb - lib/coercible/coercer/array.rb - lib/coercible/coercer/configurable.rb - lib/coercible/coercer/date.rb - lib/coercible/coercer/date_time.rb - lib/coercible/coercer/decimal.rb - lib/coercible/coercer/false_class.rb - lib/coercible/coercer/float.rb - lib/coercible/coercer/hash.rb - lib/coercible/coercer/integer.rb - lib/coercible/coercer/numeric.rb - lib/coercible/coercer/object.rb - lib/coercible/coercer/string.rb - lib/coercible/coercer/symbol.rb - lib/coercible/coercer/time.rb - lib/coercible/coercer/time_coercions.rb - lib/coercible/coercer/true_class.rb - lib/coercible/configuration.rb - lib/coercible/version.rb - lib/support/options.rb - lib/support/type_lookup.rb - spec/integration/configuring_coercers_spec.rb - spec/shared/unit/coerced_predicate.rb - spec/shared/unit/configurable.rb - spec/spec_helper.rb - spec/unit/coercible/coercer/array/coerced_predicate_spec.rb - spec/unit/coercible/coercer/array/to_set_spec.rb - spec/unit/coercible/coercer/class_methods/new_spec.rb - spec/unit/coercible/coercer/configurable/config_name_spec.rb - spec/unit/coercible/coercer/configurable/config_spec.rb - spec/unit/coercible/coercer/date/coerced_predicate_spec.rb - spec/unit/coercible/coercer/date/to_date_spec.rb - spec/unit/coercible/coercer/date/to_datetime_spec.rb - spec/unit/coercible/coercer/date/to_string_spec.rb - spec/unit/coercible/coercer/date/to_time_spec.rb - spec/unit/coercible/coercer/date_time/coerced_predicate_spec.rb - spec/unit/coercible/coercer/date_time/to_date_spec.rb - spec/unit/coercible/coercer/date_time/to_datetime_spec.rb - spec/unit/coercible/coercer/date_time/to_string_spec.rb - spec/unit/coercible/coercer/date_time/to_time_spec.rb - spec/unit/coercible/coercer/decimal/coerced_predicate_spec.rb - spec/unit/coercible/coercer/decimal/to_decimal_spec.rb - spec/unit/coercible/coercer/decimal/to_float_spec.rb - spec/unit/coercible/coercer/decimal/to_integer_spec.rb - spec/unit/coercible/coercer/decimal/to_string_spec.rb - spec/unit/coercible/coercer/element_reader_spec.rb - spec/unit/coercible/coercer/false_class/coerced_predicate_spec.rb - spec/unit/coercible/coercer/false_class/to_string_spec.rb - spec/unit/coercible/coercer/float/coerced_predicate_spec.rb - spec/unit/coercible/coercer/float/to_datetime_spec.rb - spec/unit/coercible/coercer/float/to_decimal_spec.rb - spec/unit/coercible/coercer/float/to_float_spec.rb - spec/unit/coercible/coercer/float/to_integer_spec.rb - spec/unit/coercible/coercer/float/to_string_spec.rb - spec/unit/coercible/coercer/hash/coerced_predicate_spec.rb - spec/unit/coercible/coercer/hash/to_date_spec.rb - spec/unit/coercible/coercer/hash/to_datetime_spec.rb - spec/unit/coercible/coercer/hash/to_time_spec.rb - spec/unit/coercible/coercer/integer/coerced_predicate_spec.rb - spec/unit/coercible/coercer/integer/datetime_format_spec.rb - spec/unit/coercible/coercer/integer/datetime_proc_spec.rb - spec/unit/coercible/coercer/integer/to_boolean_spec.rb - spec/unit/coercible/coercer/integer/to_datetime_spec.rb - spec/unit/coercible/coercer/integer/to_decimal_spec.rb - spec/unit/coercible/coercer/integer/to_float_spec.rb - spec/unit/coercible/coercer/integer/to_integer_spec.rb - spec/unit/coercible/coercer/integer/to_string_spec.rb - spec/unit/coercible/coercer/integer_spec.rb - spec/unit/coercible/coercer/numeric/to_decimal_spec.rb - spec/unit/coercible/coercer/numeric/to_float_spec.rb - spec/unit/coercible/coercer/numeric/to_integer_spec.rb - spec/unit/coercible/coercer/numeric/to_string_spec.rb - spec/unit/coercible/coercer/object/coerced_predicate_spec.rb - spec/unit/coercible/coercer/object/inspect_spec.rb - spec/unit/coercible/coercer/object/method_missing_spec.rb - spec/unit/coercible/coercer/object/to_array_spec.rb - spec/unit/coercible/coercer/object/to_hash_spec.rb - spec/unit/coercible/coercer/object/to_integer_spec.rb - spec/unit/coercible/coercer/object/to_string_spec.rb - spec/unit/coercible/coercer/string/class_methods/config_spec.rb - spec/unit/coercible/coercer/string/coerced_predicate_spec.rb - spec/unit/coercible/coercer/string/to_boolean_spec.rb - spec/unit/coercible/coercer/string/to_constant_spec.rb - spec/unit/coercible/coercer/string/to_date_spec.rb - spec/unit/coercible/coercer/string/to_datetime_spec.rb - spec/unit/coercible/coercer/string/to_decimal_spec.rb - spec/unit/coercible/coercer/string/to_float_spec.rb - spec/unit/coercible/coercer/string/to_integer_spec.rb - spec/unit/coercible/coercer/string/to_symbol_spec.rb - spec/unit/coercible/coercer/string/to_time_spec.rb - spec/unit/coercible/coercer/string_spec.rb - spec/unit/coercible/coercer/symbol/coerced_predicate_spec.rb - spec/unit/coercible/coercer/symbol/to_string_spec.rb - spec/unit/coercible/coercer/time/coerced_predicate_spec.rb - spec/unit/coercible/coercer/time/to_integer_spec.rb - spec/unit/coercible/coercer/time/to_time_spec.rb - spec/unit/coercible/coercer/time_coercions/to_date_spec.rb - spec/unit/coercible/coercer/time_coercions/to_datetime_spec.rb - spec/unit/coercible/coercer/time_coercions/to_string_spec.rb - spec/unit/coercible/coercer/time_coercions/to_time_spec.rb - spec/unit/coercible/coercer/true_class/coerced_predicate_spec.rb - spec/unit/coercible/coercer/true_class/to_string_spec.rb - spec/unit/coercible/configuration/class_methods/build_spec.rb homepage: https://github.com/solnic/coercible licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.0.3 signing_key: specification_version: 4 summary: Powerful, flexible and configurable coercion library. And nothing more. test_files: - spec/integration/configuring_coercers_spec.rb - spec/shared/unit/coerced_predicate.rb - spec/shared/unit/configurable.rb - spec/spec_helper.rb - spec/unit/coercible/coercer/array/coerced_predicate_spec.rb - spec/unit/coercible/coercer/array/to_set_spec.rb - spec/unit/coercible/coercer/class_methods/new_spec.rb - spec/unit/coercible/coercer/configurable/config_name_spec.rb - spec/unit/coercible/coercer/configurable/config_spec.rb - spec/unit/coercible/coercer/date/coerced_predicate_spec.rb - spec/unit/coercible/coercer/date/to_date_spec.rb - spec/unit/coercible/coercer/date/to_datetime_spec.rb - spec/unit/coercible/coercer/date/to_string_spec.rb - spec/unit/coercible/coercer/date/to_time_spec.rb - spec/unit/coercible/coercer/date_time/coerced_predicate_spec.rb - spec/unit/coercible/coercer/date_time/to_date_spec.rb - spec/unit/coercible/coercer/date_time/to_datetime_spec.rb - spec/unit/coercible/coercer/date_time/to_string_spec.rb - spec/unit/coercible/coercer/date_time/to_time_spec.rb - spec/unit/coercible/coercer/decimal/coerced_predicate_spec.rb - spec/unit/coercible/coercer/decimal/to_decimal_spec.rb - spec/unit/coercible/coercer/decimal/to_float_spec.rb - spec/unit/coercible/coercer/decimal/to_integer_spec.rb - spec/unit/coercible/coercer/decimal/to_string_spec.rb - spec/unit/coercible/coercer/element_reader_spec.rb - spec/unit/coercible/coercer/false_class/coerced_predicate_spec.rb - spec/unit/coercible/coercer/false_class/to_string_spec.rb - spec/unit/coercible/coercer/float/coerced_predicate_spec.rb - spec/unit/coercible/coercer/float/to_datetime_spec.rb - spec/unit/coercible/coercer/float/to_decimal_spec.rb - spec/unit/coercible/coercer/float/to_float_spec.rb - spec/unit/coercible/coercer/float/to_integer_spec.rb - spec/unit/coercible/coercer/float/to_string_spec.rb - spec/unit/coercible/coercer/hash/coerced_predicate_spec.rb - spec/unit/coercible/coercer/hash/to_date_spec.rb - spec/unit/coercible/coercer/hash/to_datetime_spec.rb - spec/unit/coercible/coercer/hash/to_time_spec.rb - spec/unit/coercible/coercer/integer/coerced_predicate_spec.rb - spec/unit/coercible/coercer/integer/datetime_format_spec.rb - spec/unit/coercible/coercer/integer/datetime_proc_spec.rb - spec/unit/coercible/coercer/integer/to_boolean_spec.rb - spec/unit/coercible/coercer/integer/to_datetime_spec.rb - spec/unit/coercible/coercer/integer/to_decimal_spec.rb - spec/unit/coercible/coercer/integer/to_float_spec.rb - spec/unit/coercible/coercer/integer/to_integer_spec.rb - spec/unit/coercible/coercer/integer/to_string_spec.rb - spec/unit/coercible/coercer/integer_spec.rb - spec/unit/coercible/coercer/numeric/to_decimal_spec.rb - spec/unit/coercible/coercer/numeric/to_float_spec.rb - spec/unit/coercible/coercer/numeric/to_integer_spec.rb - spec/unit/coercible/coercer/numeric/to_string_spec.rb - spec/unit/coercible/coercer/object/coerced_predicate_spec.rb - spec/unit/coercible/coercer/object/inspect_spec.rb - spec/unit/coercible/coercer/object/method_missing_spec.rb - spec/unit/coercible/coercer/object/to_array_spec.rb - spec/unit/coercible/coercer/object/to_hash_spec.rb - spec/unit/coercible/coercer/object/to_integer_spec.rb - spec/unit/coercible/coercer/object/to_string_spec.rb - spec/unit/coercible/coercer/string/class_methods/config_spec.rb - spec/unit/coercible/coercer/string/coerced_predicate_spec.rb - spec/unit/coercible/coercer/string/to_boolean_spec.rb - spec/unit/coercible/coercer/string/to_constant_spec.rb - spec/unit/coercible/coercer/string/to_date_spec.rb - spec/unit/coercible/coercer/string/to_datetime_spec.rb - spec/unit/coercible/coercer/string/to_decimal_spec.rb - spec/unit/coercible/coercer/string/to_float_spec.rb - spec/unit/coercible/coercer/string/to_integer_spec.rb - spec/unit/coercible/coercer/string/to_symbol_spec.rb - spec/unit/coercible/coercer/string/to_time_spec.rb - spec/unit/coercible/coercer/string_spec.rb - spec/unit/coercible/coercer/symbol/coerced_predicate_spec.rb - spec/unit/coercible/coercer/symbol/to_string_spec.rb - spec/unit/coercible/coercer/time/coerced_predicate_spec.rb - spec/unit/coercible/coercer/time/to_integer_spec.rb - spec/unit/coercible/coercer/time/to_time_spec.rb - spec/unit/coercible/coercer/time_coercions/to_date_spec.rb - spec/unit/coercible/coercer/time_coercions/to_datetime_spec.rb - spec/unit/coercible/coercer/time_coercions/to_string_spec.rb - spec/unit/coercible/coercer/time_coercions/to_time_spec.rb - spec/unit/coercible/coercer/true_class/coerced_predicate_spec.rb - spec/unit/coercible/coercer/true_class/to_string_spec.rb - spec/unit/coercible/configuration/class_methods/build_spec.rb has_rdoc: coercible-1.0.0/Changelog.md0000644000175000017500000000061512304121575015230 0ustar boutilboutil# v1.0.0 2013-12-10 Dropped 1.8.7 support. # v0.2.0 2013-03-08 * [internal] Update to latest backports (solnic) # v0.1.0 2013-02-17 * [internal] Small clean-up and improved tests (solnic) # v0.0.2 2013-02-16 * [feature] Added Coercer::Object#coerced? (solnic) # v0.0.1 2012-12-25 * Add configurable coercers (solnic) * Port Virtus::Coercion and refactor into object-based system (solnic) coercible-1.0.0/config/0000755000175000017500000000000012304121575014262 5ustar boutilboutilcoercible-1.0.0/config/flay.yml0000644000175000017500000000004312304121575015735 0ustar boutilboutil--- threshold: 20 total_score: 245 coercible-1.0.0/config/roodi.yml0000644000175000017500000000164012304121575016122 0ustar boutilboutil--- AbcMetricMethodCheck: { score: 12.1 } AssignmentInConditionalCheck: { } CaseMissingElseCheck: { } ClassLineCountCheck: { line_count: 325 } ClassNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ } ClassVariableCheck: { } CyclomaticComplexityBlockCheck: { complexity: 4 } CyclomaticComplexityMethodCheck: { complexity: 4 } EmptyRescueBodyCheck: { } ForLoopCheck: { } MethodLineCountCheck: { line_count: 10 } MethodNameCheck: { pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/ } ModuleLineCountCheck: { line_count: 331 } ModuleNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ } # TODO: decrease parameter_count to 2 or less ParameterNumberCheck: { parameter_count: 3 } coercible-1.0.0/config/mutant.yml0000644000175000017500000000005112304121575016311 0ustar boutilboutil--- name: coercible namespace: Coercible coercible-1.0.0/config/flog.yml0000644000175000017500000000002412304121575015730 0ustar boutilboutil--- threshold: 16.2 coercible-1.0.0/config/site.reek0000644000175000017500000000302112304121575016072 0ustar boutilboutil--- UncommunicativeParameterName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ LargeClass: max_methods: 14 exclude: [] enabled: true max_instance_variables: 8 UncommunicativeMethodName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^[a-z]$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ LongParameterList: max_params: 3 exclude: [] enabled: true overrides: {} FeatureEnvy: exclude: [] enabled: true ClassVariable: exclude: [] enabled: true BooleanParameter: exclude: [] enabled: true IrresponsibleModule: exclude: [] enabled: true UncommunicativeModuleName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ NestedIterators: ignore_iterators: [] exclude: [] enabled: true max_allowed_nesting: 2 LongMethod: max_statements: 6 exclude: [] enabled: true Duplication: allow_calls: [] exclude: [] enabled: true max_calls: 1 UtilityFunction: max_helper_calls: 1 exclude: [] enabled: true Attribute: exclude: [] enabled: false UncommunicativeVariableName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ SimulatedPolymorphism: exclude: [] enabled: true max_ifs: 1 DataClump: exclude: [] enabled: true max_copies: 2 min_clump_size: 2 ControlCouple: exclude: [] enabled: true LongYieldList: max_params: 1 exclude: [] enabled: true coercible-1.0.0/Gemfile0000644000175000017500000000021112304121575014302 0ustar boutilboutilsource 'https://rubygems.org' gemspec gem 'devtools', :git => 'https://github.com/rom-rb/devtools.git' eval_gemfile 'Gemfile.devtools' coercible-1.0.0/.rspec0000644000175000017500000000002212304121575014124 0ustar boutilboutil--color --profile coercible-1.0.0/README.md0000644000175000017500000000340012304121575014271 0ustar boutilboutil# Coercible [![Build Status](https://travis-ci.org/solnic/coercible.png?branch=master)](https://travis-ci.org/solnic/coercible) [![Code Climate](https://codeclimate.com/github/solnic/coercible.png)](https://codeclimate.com/github/solnic/coercible) [![Dependency Status](https://gemnasium.com/solnic/coercible.png)](https://gemnasium.com/solnic/coercible) ## Installation Add this line to your application's Gemfile: gem 'coercible' And then execute: $ bundle Or install it yourself as: $ gem install coercible ## Usage Coercible gives you access to coercer objects where each object is responsible for coercing only one type into other types. For example a string coercer knows only how to coerce string objects, integer coercer knows only how to coerce integers etc. Here's the most basic example: ```ruby coercer = Coercible::Coercer.new # coerce a string to a date coercer[String].to_date('2012/12/25') # => # # coerce a string to a boolean value coercer[String].to_boolean('yes') # => true # you got the idea :) ``` For more control you can configure your coercer like that: ``` ruby # build coercer instance coercer = Coercible::Coercer.new do |config| config.string.boolean_map = { 'yup' => true, 'nope' => false } end # coerce a string to boolean coercer[String].to_boolean('yup') # => true coercer[String].to_boolean('nope') # => false ``` Note that at the moment only Integer and String are configurable. More configurable coercers will be added later whenever we find good usecases. ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request coercible-1.0.0/.gitignore0000644000175000017500000000024712304121575015010 0ustar boutilboutil*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp measurements coercible-1.0.0/lib/0000755000175000017500000000000012304121575013563 5ustar boutilboutilcoercible-1.0.0/lib/coercible/0000755000175000017500000000000012304121575015512 5ustar boutilboutilcoercible-1.0.0/lib/coercible/coercer/0000755000175000017500000000000012304121575017134 5ustar boutilboutilcoercible-1.0.0/lib/coercible/coercer/date_time.rb0000644000175000017500000000076312304121575021422 0ustar boutilboutilmodule Coercible class Coercer # Coerce DateTime values class DateTime < Object primitive ::DateTime include TimeCoercions # Passthrough the value # # @example # coercer[DateTime].to_datetime(datetime) # => DateTime object # # @param [DateTime] value # # @return [Date] # # @api public def to_datetime(value) value end end # class DateTime end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/decimal.rb0000644000175000017500000000151112304121575021055 0ustar boutilboutilmodule Coercible class Coercer # Coerce BigDecimal values class Decimal < Numeric primitive ::BigDecimal FLOAT_FORMAT = 'F'.freeze # Coerce given value to String # # @example # coercer[BigDecimal].to_string(BigDecimal('1.0')) # => "1.0" # # @param [BigDecimal] value # # @return [String] # # @api public def to_string(value) value.to_s(FLOAT_FORMAT) end # Passthrough the value # # @example # Coercible::Coercion::BigDecimal.to_decimal(BigDecimal('1.0')) # => BigDecimal('1.0') # # @param [BigDecimal] value # # @return [Fixnum] # # @api public def to_decimal(value) value end end # class BigDecimal end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/time.rb0000644000175000017500000000140512304121575020417 0ustar boutilboutilmodule Coercible class Coercer # Coerce Time values class Time < Object include TimeCoercions primitive ::Time # Passthrough the value # # @example # coercer[DateTime].to_time(time) # => Time object # # @param [DateTime] value # # @return [Date] # # @api public def to_time(value) value end # Creates a Fixnum instance from a Time object # # @example # Coercible::Coercion::Time.to_integer(time) # => Fixnum object # # @param [Time] value # # @return [Fixnum] # # @api public def to_integer(value) value.to_i end end # class Time end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/true_class.rb0000644000175000017500000000072412304121575021630 0ustar boutilboutilmodule Coercible class Coercer # Coerce true values class TrueClass < Object primitive ::TrueClass # Coerce given value to String # # @example # coercer[TrueClass].to_string(true) # => "true" # # @param [TrueClass] value # # @return [String] # # @api public def to_string(value) value.to_s end end # class TrueClass end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/numeric.rb0000644000175000017500000000262412304121575021127 0ustar boutilboutilmodule Coercible class Coercer # Base class for all numeric Coercion classes class Numeric < Object primitive ::Numeric # Coerce given value to String # # @example # coercer[Numeric].to_string(Rational(2, 2)) # => "1.0" # # @param [Numeric] value # # @return [String] # # @api public def to_string(value) value.to_s end # Creates an Integer instance from a numeric object # # @example # coercer[Numeric].to_integer(Rational(2, 2)) # => 1 # # @param [Numeric] value # # @return [Integer] # # @api public def to_integer(value) value.to_i end # Creates a Float instance from a numeric object # # @example # coercer[Numeric].to_float(Rational(2, 2)) # => 1.0 # # @param [Numeric] value # # @return [Float] # # @api public def to_float(value) value.to_f end # Coerce a BigDecimal instance from a numeric object # # @example # coercer[Numeric].to_decimal(Rational(2, 2)) # => BigDecimal('1.0') # # @param [Numeric] value # # @return [BigDecimal] # # @api public def to_decimal(value) to_string(value).to_d end end # class Numeric end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/float.rb0000644000175000017500000000152612304121575020572 0ustar boutilboutilmodule Coercible class Coercer # Coerce Float values class Float < Numeric primitive ::Float # Passthrough the value # # @example # coercer[Float].to_float(1.0) # => 1.0 # # @param [Float] value # # @return [Integer] # # @api public def to_float(value) value end # Coerce given value to a DateTime # # @example # datetime = Coercible::Coercion::Float.to_datetime(1000000000.999) # => Sun, 09 Sep 2001 01:46:40 +0000 # datetime.to_f # => 1000000000.999 # # @param [Float] value # # @return [DateTime] # # @api public def to_datetime(value) ::DateTime.strptime((value * 10**3).to_s, "%Q") end end # class Float end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/symbol.rb0000644000175000017500000000071012304121575020764 0ustar boutilboutilmodule Coercible class Coercer # Coerce Symbol values class Symbol < Object primitive ::Symbol # Coerce given value to String # # @example # coercer[Symbol].to_string(:name) # => "name" # # @param [Symbol] value # # @return [String] # # @api public def to_string(value) value.to_s end end # class Symbol end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/hash.rb0000644000175000017500000000303212304121575020402 0ustar boutilboutilmodule Coercible class Coercer # Coerce Hash values class Hash < Object primitive ::Hash TIME_SEGMENTS = [ :year, :month, :day, :hour, :min, :sec ].freeze # Creates a Time instance from a Hash # # Valid keys are: :year, :month, :day, :hour, :min, :sec # # @param [Hash] value # # @return [Time] # # @api private def to_time(value) ::Time.local(*extract(value)) end # Creates a Date instance from a Hash # # Valid keys are: :year, :month, :day, :hour # # @param [Hash] value # # @return [Date] # # @api private def to_date(value) ::Date.new(*extract(value).first(3)) end # Creates a DateTime instance from a Hash # # Valid keys are: :year, :month, :day, :hour, :min, :sec # # @param [Hash] value # # @return [DateTime] # # @api private def to_datetime(value) ::DateTime.new(*extract(value)) end private # Extracts the given args from a Hash # # If a value does not exist, it uses the value of Time.now # # @param [Hash] value # # @return [Array] # # @api private def extract(value) now = ::Time.now TIME_SEGMENTS.map do |segment| val = value.fetch(segment, now.public_send(segment)) coercers[val.class].to_integer(val) end end end # class Hash end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/string.rb0000644000175000017500000001377212304121575021001 0ustar boutilboutilmodule Coercible class Coercer # Coerce String values class String < Object extend Configurable primitive ::String config_keys [ :boolean_map ] TRUE_VALUES = %w[ 1 on t true y yes ].freeze FALSE_VALUES = %w[ 0 off f false n no ].freeze BOOLEAN_MAP = ::Hash[ TRUE_VALUES.product([ true ]) + FALSE_VALUES.product([ false ]) ].freeze INTEGER_REGEXP = /[-+]?(?:[0-9]\d*)/.freeze EXPONENT_REGEXP = /(?:[eE][-+]?\d+)/.freeze FRACTIONAL_REGEXP = /(?:\.\d+)/.freeze NUMERIC_REGEXP = /\A( #{INTEGER_REGEXP}#{FRACTIONAL_REGEXP}?#{EXPONENT_REGEXP}? | #{FRACTIONAL_REGEXP}#{EXPONENT_REGEXP}? )\z/x.freeze # Return default configuration for string coercer type # # @return [Configuration] # # @api private def self.config super { |config| config.boolean_map = BOOLEAN_MAP } end # Return boolean map from the config # # @return [::Hash] # # @api private attr_reader :boolean_map # Initialize a new string coercer instance # # @param [Coercer] # # @param [Configuration] # # @return [undefined] # # @api private def initialize(coercer = Coercer.new, config = self.class.config) super(coercer) @boolean_map = config.boolean_map end # Coerce give value to a constant # # @example # coercer[String].to_constant('String') # => String # # @param [String] value # # @return [Object] # # @api public def to_constant(value) names = value.split('::') names.shift if names.first.empty? names.inject(::Object) { |*args| constant_lookup(*args) } end # Coerce give value to a symbol # # @example # coercer[String].to_symbol('string') # => :string # # @param [String] value # # @return [Symbol] # # @api public def to_symbol(value) value.to_sym end # Coerce given value to Time # # @example # coercer[String].to_time(string) # => Time object # # @param [String] value # # @return [Time] # # @api public def to_time(value) parse_value(::Time, value, __method__) end # Coerce given value to Date # # @example # coercer[String].to_date(string) # => Date object # # @param [String] value # # @return [Date] # # @api public def to_date(value) parse_value(::Date, value, __method__) end # Coerce given value to DateTime # # @example # coercer[String].to_datetime(string) # => DateTime object # # @param [String] value # # @return [DateTime] # # @api public def to_datetime(value) parse_value(::DateTime, value, __method__) end # Coerce value to TrueClass or FalseClass # # @example with "T" # coercer[String].to_boolean('T') # => true # # @example with "F" # coercer[String].to_boolean('F') # => false # # @param [#to_s] # # @return [Boolean] # # @api public def to_boolean(value) boolean_map.fetch(value.downcase) { raise_unsupported_coercion(value, __method__) } end # Coerce value to integer # # @example # coercer[String].to_integer('1') # => 1 # # @param [Object] value # # @return [Integer] # # @api public def to_integer(value) if value =~ /\A#{INTEGER_REGEXP}\z/ value.to_i else # coerce to a Float first to evaluate scientific notation (if any) # that may change the integer part, then convert to an integer to_float(value).to_i end rescue UnsupportedCoercion raise_unsupported_coercion(value, __method__) end # Coerce value to float # # @example # coercer[String].to_float('1.2') # => 1.2 # # @param [Object] value # # @return [Float] # # @api public def to_float(value) to_numeric(value, :to_f) rescue UnsupportedCoercion raise_unsupported_coercion(value, __method__) end # Coerce value to decimal # # @example # coercer[String].to_decimal('1.2') # => # # # @param [Object] value # # @return [BigDecimal] # # @api public def to_decimal(value) to_numeric(value, :to_d) rescue UnsupportedCoercion raise_unsupported_coercion(value, __method__) end private # Lookup a constant within a module # # @param [Module] mod # # @param [String] name # # @return [Object] # # @api private def constant_lookup(mod, name) if mod.const_defined?(name, *EXTRA_CONST_ARGS) mod.const_get(name, *EXTRA_CONST_ARGS) else mod.const_missing(name) end end # Match numeric string # # @param [String] value # value to typecast # @param [Symbol] method # method to typecast with # # @return [Numeric] # number if matched, value if no match # # @api private def to_numeric(value, method) if value =~ NUMERIC_REGEXP $1.public_send(method) else raise_unsupported_coercion(value, method) end end # Parse the value or return it as-is if it is invalid # # @param [#parse] parser # # @param [String] value # # @return [Time] # # @api private def parse_value(parser, value, method) parser.parse(value) rescue ArgumentError raise_unsupported_coercion(value, method) end end # class String end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/integer.rb0000644000175000017500000000570612304121575021126 0ustar boutilboutilmodule Coercible class Coercer # Coerce Fixnum values class Integer < Numeric extend Configurable primitive ::Integer config_keys [ :datetime_format, :datetime_proc, :boolean_map ] # Return default config for Integer coercer type # # @return [Configuration] # # @see Configurable#config # # @api private def self.config super do |config| # FIXME: Remove after Rubinius 2.0 is released config.datetime_format, config.datetime_proc = if Coercible.rbx? [ '%Q', Proc.new { |value| "#{value * 10**3}" } ] else [ '%s', Proc.new { |value| "#{value}" } ] end config.boolean_map = { 0 => false, 1 => true } end end # Return datetime format from config # # @return [::String] # # @api private attr_reader :datetime_format # Return datetime proc from config # # @return [Proc] # # @api private attr_reader :datetime_proc # Return boolean map from config # # @return [::Hash] # # @api private attr_reader :boolean_map # Initialize a new Integer coercer instance and set its configuration # # @return [undefined] # # @api private def initialize(coercer = Coercer.new, config = self.class.config) super(coercer) @boolean_map = config.boolean_map @datetime_format = config.datetime_format @datetime_proc = config.datetime_proc end # Coerce given value to String # # @example # coercer[Integer].to_string(1) # => "1" # # @param [Fixnum] value # # @return [String] # # @api public def to_string(value) value.to_s end # Passthrough the value # # @example # coercer[Integer].to_integer(1) # => 1 # # @param [Fixnum] value # # @return [Float] # # @api public def to_integer(value) value end # Coerce given value to a Boolean # # @example with a 1 # coercer[Integer].to_boolean(1) # => true # # @example with a 0 # coercer[Integer].to_boolean(0) # => false # # @param [Fixnum] value # # @return [BigDecimal] # # @api public def to_boolean(value) boolean_map.fetch(value) { raise_unsupported_coercion(value, __method__) } end # Coerce given value to a DateTime # # @example # coercer[Integer].to_datetime(0) # => Thu, 01 Jan 1970 00:00:00 +0000 # # @param [Integer] value # # @return [DateTime] # # @api public def to_datetime(value) ::DateTime.strptime(datetime_proc.call(value), datetime_format) end end # class Fixnum end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/date.rb0000644000175000017500000000072312304121575020400 0ustar boutilboutilmodule Coercible class Coercer # Coerce Date values class Date < Object include TimeCoercions primitive ::Date # Passthrough the value # # @example # coercer[DateTime].to_date(date) # => Date object # # @param [DateTime] value # # @return [Date] # # @api public def to_date(value) value end end # class Date end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/array.rb0000644000175000017500000000070212304121575020576 0ustar boutilboutilmodule Coercible class Coercer # Coerce Array values class Array < Object primitive ::Array TIME_SEGMENTS = [ :year, :month, :day, :hour, :min, :sec ].freeze # Creates a Set instance from an Array # # @param [Array] value # # @return [Array] # # @api private def to_set(value) value.to_set end end # class Array end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/time_coercions.rb0000644000175000017500000000356712304121575022476 0ustar boutilboutilmodule Coercible class Coercer # Common time coercion methods module TimeCoercions # Coerce given value to String # # @example # coercer[Time].to_string(time) # => "Wed Jul 20 10:30:41 -0700 2011" # # @param [Date,Time,DateTime] value # # @return [String] # # @api public def to_string(value) value.to_s end # Coerce given value to Time # # @example # coercer[DateTime].to_time(datetime) # => Time object # # @param [Date,DateTime] value # # @return [Time] # # @api public def to_time(value) coerce_with_method(value, :to_time) end # Coerce given value to DateTime # # @example # coercer[Time].to_datetime(time) # => DateTime object # # @param [Date,Time] value # # @return [DateTime] # # @api public def to_datetime(value) coerce_with_method(value, :to_datetime) end # Coerce given value to Date # # @example # coercer[Time].to_date(time) # => Date object # # @param [Time,DateTime] value # # @return [Date] # # @api public def to_date(value) coerce_with_method(value, :to_date) end private # Try to use native coercion method on the given value # # Falls back to String-based parsing # # @param [Date,DateTime,Time] value # @param [Symbol] method # # @return [Date,DateTime,Time] # # @api private def coerce_with_method(value, method) if value.respond_to?(method) value.public_send(method) else coercers[::String].public_send(method, to_string(value)) end end end # module TimeCoercions end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/false_class.rb0000644000175000017500000000073412304121575021744 0ustar boutilboutilmodule Coercible class Coercer # Coerce false values class FalseClass < Object primitive ::FalseClass # Coerce given value to String # # @example # coercer[FalseClass].to_string(false) # => "false" # # @param [FalseClass] value # # @return [String] # # @api public def to_string(value) value.to_s end end # class FalseClass end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/configurable.rb0000644000175000017500000000251212304121575022121 0ustar boutilboutilmodule Coercible class Coercer module Configurable # Add configuration-specific option keys to the descendant # # @return [self] # # @api private def self.extended(coercer) coercer.accept_options :config_keys super end # Build configuration object for the coercer class # # @example # # coercer_class = Class.new(Coercer::Object) do # extend Configurable # # config_keys [ :foo, :bar ] # end # # coercer_class.config do |config| # config.foo = '1' # config.bar = '2' # end # # @yieldparam [Configuration] # # @return [Configuration] # # @api public def config(&block) configuration = configuration_class.build(config_keys) yield configuration configuration end # Return configuration name in the global config # # @return [Symbol] # # @api private def config_name name.downcase.split('::').last.to_sym end # Return configuration class # # @return [Class:Configuration] # # @api private def configuration_class Configuration end end # module Configurable end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/coercer/object.rb0000644000175000017500000001151512304121575020732 0ustar boutilboutilmodule Coercible class Coercer # Coerce Object values class Object extend TypeLookup, Options accept_options :primitive primitive ::Object COERCION_METHOD_REGEXP = /\Ato_/.freeze # Return coercers object # # @return [Coercer] # # @api private attr_reader :coercers # Initialize a new coercer instance # # @param [Coercer] coercers # # @return [undefined] # # @api private def initialize(coercers = Coercer.new) @coercers = coercers end # Inspect the coercer object # # @example # coercer[Object].inspect # => "" # # @return [String] # # @api public def inspect "#<#{self.class} primitive=#{self.class.primitive}>" end # Create an Array from any Object # # @example with an object that does not respond to #to_a or #to_ary # coercer[Object].to_array(value) # => [ value ] # # @example with an object that responds to #to_a # coercer[Object].to_array(Set[ value ]) # => [ value ] # # @example with n object that responds to #to_ary # coercer[Object].to_array([ value ]) # => [ value ] # # @param [#to_a,#to_ary,Object] value # @param [#to_a,#to_ary,Object] value # # @return [Array] # # @api public def to_array(value) Array(value) end # Create a Hash from the Object if possible # # @example with a coercible object # coercer[Object].to_hash(key => value) # => { key => value } # # @example with an object that is not coercible # coercer[Object].to_hash(value) # => value # # @param [#to_hash, Object] value # # @return [Hash] # returns a Hash when the object can be coerced # @return [Object] # returns the value when the object cannot be coerced # # @api public def to_hash(value) coerce_with_method(value, :to_hash, __method__) end # Create a String from the Object if possible # # @example with a coercible object # coercer[Object].to_string("string") # => "string" # # @example with an object that is not coercible # coercer[Object].to_string(value) # => value # # @param [#to_str, Object] value # # @return [String] # returns a String when the object can be coerced # @return [Object] # returns the value when the object cannot be coerced # # @api public def to_string(value) coerce_with_method(value, :to_str, __method__) end # Create an Integer from the Object if possible # # @example with a coercible object # coercer[Object].to_integer(1) # => 1 # # @example with an object that is not coercible # coercer[Object].to_integer(value) # => value # # @param [#to_int, Object] value # # @return [Integer] # returns an Integer when the object can be coerced # @return [Object] # returns the value when the object cannot be coerced # # @api public def to_integer(value) coerce_with_method(value, :to_int, __method__) end # Return if the value was successfuly coerced # # @example when coercion was successful # coercer[String].coerced?(1) # => true # # @example when coercion was NOT successful # coercer[String].coerced?("foo") # => false # # @return [TrueClass,FalseClass] # # @api public def coerced?(value) value.kind_of?(self.class.primitive) end private # Raise an unsupported coercion error # # @raises [UnsupportedCoercion] # # @return [undefined] # # @api private def raise_unsupported_coercion(value, method) raise( UnsupportedCoercion, "#{self.class}##{method} doesn't know how to coerce #{value.inspect}" ) end # Passthrough given value # # @param [Object] value # # @return [Object] # # @api private def method_missing(method, *args) if method.to_s =~ COERCION_METHOD_REGEXP && args.size == 1 args.first else super end end # Try to use native coercion method on the given value # # @param [Object] value # # @param [Symbol] method # # @return [Object] # # @api private def coerce_with_method(value, method, ref_method) value.respond_to?(method) ? value.public_send(method) : raise_unsupported_coercion(value, ref_method) end end # class Object end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/version.rb0000644000175000017500000000005112304121575017520 0ustar boutilboutilmodule Coercible VERSION = "1.0.0" end coercible-1.0.0/lib/coercible/coercer.rb0000644000175000017500000000562512304121575017471 0ustar boutilboutilmodule Coercible # Coercer object # # # @example # # coercer = Coercible::Coercer.new # # coercer[String].to_boolean('yes') # => true # coercer[Integer].to_string(1) # => '1' # # @api public class Coercer # Return coercer instances # # @return [Array] # # @api private attr_reader :coercers # Returns global configuration for coercers # # @return [Configuration] # # @api private attr_reader :config # Build a new coercer # # @example # # Coercible::Coercer.new { |config| # set configuration } # # @yieldparam [Configuration] # # @return [Coercer] # # @api public def self.new(&block) configuration = Configuration.build(config_keys) configurable_coercers.each do |coercer| configuration.send("#{coercer.config_name}=", coercer.config) end yield(configuration) if block_given? super(configuration) end # Return configuration keys for Coercer instance # # @return [Array] # # @api private def self.config_keys configurable_coercers.map(&:config_name) end private_class_method :config_keys # Return coercer classes that are configurable # # @return [Array] # # @api private def self.configurable_coercers(&block) Coercer::Object.descendants.select { |descendant| descendant.respond_to?(:config) } end private_class_method :configurable_coercers # Initialize a new coercer instance # # @param [Hash] coercers # # @param [Configuration] config # # @return [undefined] # # @api private def initialize(config, coercers = {}) @coercers = coercers @config = config end # Access a specific coercer object for the given type # # @example # # coercer[String] # => string coercer # coercer[Integer] # => integer coercer # # @param [Class] type # # @return [Coercer::Object] # # @api public def [](klass) coercers[klass] || initialize_coercer(klass) end private # Initialize a new coercer instance for the given type # # If a coercer class supports configuration it will receive it from the # global configuration object # # @return [Coercer::Object] # # @api private def initialize_coercer(klass) coercers[klass] = begin coercer = Coercer::Object.determine_type(klass) || Coercer::Object args = [ self ] args << config_for(coercer) if coercer.respond_to?(:config_name) coercer.new(*args) end end # Find configuration for the given coercer type # # @return [Configuration] # # @api private def config_for(coercer) config.send(coercer.config_name) end end # class Coercer end # module Coercible coercible-1.0.0/lib/coercible/configuration.rb0000644000175000017500000000117012304121575020705 0ustar boutilboutilmodule Coercible # Configuration object for global and per coercer type settings # class Configuration # Build a configuration instance # # @param [Array] list of accessor keys # # @return [Configuration] # # @api private def self.build(keys, &block) config = new keys.each do |key| config.instance_eval <<-RUBY def #{key} @#{key} end def #{key}=(value) @#{key} = value end RUBY end yield(config) if block_given? config end end # class Configuration end # module Coercible coercible-1.0.0/lib/coercible.rb0000644000175000017500000000231412304121575016037 0ustar boutilboutilmodule Coercible EXTRA_CONST_ARGS = (RUBY_VERSION < '1.9' ? [] : [ false ]).freeze UnsupportedCoercion = Class.new(StandardError) # Test for rubinius platform # # @return [true] # if running under rubinius # # @return [false] # otherwise # # @api private def self.rbx? @is_rbx ||= defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' end end require 'date' require 'time' require 'bigdecimal' require 'bigdecimal/util' require 'set' require 'descendants_tracker' require 'support/options' require 'support/type_lookup' require 'coercible/version' require 'coercible/configuration' require 'coercible/coercer' require 'coercible/coercer/configurable' require 'coercible/coercer/object' require 'coercible/coercer/numeric' require 'coercible/coercer/float' require 'coercible/coercer/integer' require 'coercible/coercer/decimal' require 'coercible/coercer/string' require 'coercible/coercer/symbol' require 'coercible/coercer/time_coercions' require 'coercible/coercer/date' require 'coercible/coercer/date_time' require 'coercible/coercer/time' require 'coercible/coercer/false_class' require 'coercible/coercer/true_class' require 'coercible/coercer/array' require 'coercible/coercer/hash' coercible-1.0.0/lib/support/0000755000175000017500000000000012304121575015277 5ustar boutilboutilcoercible-1.0.0/lib/support/type_lookup.rb0000644000175000017500000000522012304121575020175 0ustar boutilboutilmodule Coercible # A module that adds type lookup to a class module TypeLookup TYPE_FORMAT = /\A[A-Z]\w*\z/.freeze # Set cache ivar on the model # # @param [Class] model # # @return [undefined] # # @api private def self.extended(model) model.instance_variable_set('@type_lookup_cache', {}) end # Returns a descendant based on a name or class # # @example # MyClass.determine_type('String') # => MyClass::String # # @param [Class, #to_s] class_or_name # name of a class or a class itself # # @return [Class] # a descendant # # @return [nil] # nil if the type cannot be determined by the class_or_name # # @api public def determine_type(class_or_name) @type_lookup_cache[class_or_name] ||= determine_type_and_cache(class_or_name) end # Return the default primitive supported # # @return [Class] # # @api private def primitive raise NotImplementedError, "#{self}.primitive must be implemented" end private # Determine type and cache the class # # @return [Class] # # @api private def determine_type_and_cache(class_or_name) case class_or_name when singleton_class determine_type_from_descendant(class_or_name) when Class determine_type_from_primitive(class_or_name) else determine_type_from_string(class_or_name.to_s) end end # Return the class given a descendant # # @param [Class] descendant # # @return [Class] # # @api private def determine_type_from_descendant(descendant) descendant if descendant < self end # Return the class given a primitive # # @param [Class] primitive # # @return [Class] # # @return [nil] # nil if the type cannot be determined by the primitive # # @api private def determine_type_from_primitive(primitive) type = nil descendants.reverse_each do |descendant| descendant_primitive = descendant.primitive next unless primitive <= descendant_primitive type = descendant if type.nil? or type.primitive > descendant_primitive end type end # Return the class given a string # # @param [String] string # # @return [Class] # # @return [nil] # nil if the type cannot be determined by the string # # @api private def determine_type_from_string(string) if string =~ TYPE_FORMAT and const_defined?(string, *EXTRA_CONST_ARGS) const_get(string, *EXTRA_CONST_ARGS) end end end # module TypeLookup end # module Virtus coercible-1.0.0/lib/support/options.rb0000644000175000017500000000614212304121575017322 0ustar boutilboutilmodule Coercible # A module that adds class and instance level options module Options Undefined = Class.new.freeze # Hook called when descendant was extended # # @param [Class,Module] descendant # # @return [undefined] # # @api private def self.extended(descendant) descendant.extend(DescendantsTracker) end # Returns default options hash for a given attribute class # # @example # Virtus::Attribute::String.options # # => {:primitive => String} # # @return [Hash] # a hash of default option values # # @api public def options accepted_options.each_with_object({}) do |option_name, options| option_value = send(option_name) options[option_name] = option_value unless option_value.nil? end end # Returns an array of valid options # # @example # Virtus::Attribute::String.accepted_options # # => [:primitive, :accessor, :reader, :writer] # # @return [Array] # the array of valid option names # # @api public def accepted_options @accepted_options ||= [] end # Defines which options are valid for a given attribute class # # @example # class MyAttribute < Virtus::Attribute::Object # accept_options :foo, :bar # end # # @return [self] # # @api public def accept_options(*new_options) add_accepted_options(new_options) new_options.each { |option| define_option_method(option) } descendants.each { |descendant| descendant.add_accepted_options(new_options) } self end protected # Adds a reader/writer method for the give option name # # @return [undefined] # # @api private def define_option_method(option) class_eval <<-RUBY, __FILE__, __LINE__ + 1 def self.#{option}(value = Undefined) # def self.primitive(value = Undefined) return @#{option} if value.equal?(Undefined) # return @primitive if value.equal?(Undefined) @#{option} = value # @primitive = value self # self end # end RUBY end # Sets default options # # @param [#each] new_options # options to be set # # @return [self] # # @api private def set_options(new_options) new_options.each { |pair| send(*pair) } self end # Adds new options that an attribute class can accept # # @param [#to_ary] new_options # new options to be added # # @return [self] # # @api private def add_accepted_options(new_options) accepted_options.concat(new_options) self end private # Adds descendant to descendants array and inherits default options # # @param [Class] descendant # # @return [undefined] # # @api private def inherited(descendant) super descendant.add_accepted_options(accepted_options).set_options(options) end end # module Options end # module Virtus coercible-1.0.0/LICENSE.txt0000644000175000017500000000205512304121575014642 0ustar boutilboutilCopyright (c) 2012 Piotr Solnica MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.coercible-1.0.0/.travis.yml0000644000175000017500000000043312304121575015126 0ustar boutilboutillanguage: ruby before_install: gem install bundler bundler_args: --without guard metrics script: "bundle exec rake spec" rvm: - 1.9.2 - 1.9.3 - 2.0.0 - jruby-19mode - rbx-19mode - jruby-head notifications: email: - piotr.solnica@gmail.com - dan.kubb@gmail.com