coercible 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/Changelog.md +4 -0
- data/Gemfile +6 -0
- data/Gemfile.devtools +44 -0
- data/Guardfile +58 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +2 -0
- data/coercible.gemspec +22 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/roodi.yml +17 -0
- data/config/site.reek +91 -0
- data/config/yardstick.yml +2 -0
- data/lib/coercible.rb +42 -0
- data/lib/coercible/coercer.rb +155 -0
- data/lib/coercible/coercer/array.rb +24 -0
- data/lib/coercible/coercer/configurable.rb +54 -0
- data/lib/coercible/coercer/date.rb +27 -0
- data/lib/coercible/coercer/date_time.rb +27 -0
- data/lib/coercible/coercer/decimal.rb +41 -0
- data/lib/coercible/coercer/false_class.rb +25 -0
- data/lib/coercible/coercer/float.rb +40 -0
- data/lib/coercible/coercer/hash.rb +72 -0
- data/lib/coercible/coercer/integer.rb +130 -0
- data/lib/coercible/coercer/numeric.rb +67 -0
- data/lib/coercible/coercer/object.rb +160 -0
- data/lib/coercible/coercer/string.rb +251 -0
- data/lib/coercible/coercer/symbol.rb +25 -0
- data/lib/coercible/coercer/time.rb +41 -0
- data/lib/coercible/coercer/time_coercions.rb +87 -0
- data/lib/coercible/coercer/true_class.rb +25 -0
- data/lib/coercible/configuration.rb +33 -0
- data/lib/coercible/version.rb +3 -0
- data/lib/support/options.rb +113 -0
- data/lib/support/type_lookup.rb +113 -0
- data/spec/integration/configuring_coercers_spec.rb +14 -0
- data/spec/shared/unit/configurable.rb +27 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/unit/coercible/coercer/array/to_set_spec.rb +12 -0
- data/spec/unit/coercible/coercer/class_methods/new_spec.rb +13 -0
- data/spec/unit/coercible/coercer/date/to_date_spec.rb +10 -0
- data/spec/unit/coercible/coercer/date/to_datetime_spec.rb +30 -0
- data/spec/unit/coercible/coercer/date/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/date/to_time_spec.rb +12 -0
- data/spec/unit/coercible/coercer/date_time/to_date_spec.rb +30 -0
- data/spec/unit/coercible/coercer/date_time/to_datetime_spec.rb +10 -0
- data/spec/unit/coercible/coercer/date_time/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/date_time/to_time_spec.rb +30 -0
- data/spec/unit/coercible/coercer/decimal/to_decimal_spec.rb +9 -0
- data/spec/unit/coercible/coercer/decimal/to_float_spec.rb +12 -0
- data/spec/unit/coercible/coercer/decimal/to_integer_spec.rb +12 -0
- data/spec/unit/coercible/coercer/decimal/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/element_reference_spec.rb +19 -0
- data/spec/unit/coercible/coercer/false_class/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/float/to_decimal_spec.rb +12 -0
- data/spec/unit/coercible/coercer/float/to_float_spec.rb +9 -0
- data/spec/unit/coercible/coercer/float/to_integer_spec.rb +12 -0
- data/spec/unit/coercible/coercer/float/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/hash/to_date_spec.rb +38 -0
- data/spec/unit/coercible/coercer/hash/to_datetime_spec.rb +38 -0
- data/spec/unit/coercible/coercer/hash/to_time_spec.rb +38 -0
- data/spec/unit/coercible/coercer/integer/to_boolean_spec.rb +27 -0
- data/spec/unit/coercible/coercer/integer/to_decimal_spec.rb +12 -0
- data/spec/unit/coercible/coercer/integer/to_float_spec.rb +12 -0
- data/spec/unit/coercible/coercer/integer/to_integer_spec.rb +9 -0
- data/spec/unit/coercible/coercer/integer/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/integer_spec.rb +11 -0
- data/spec/unit/coercible/coercer/numeric/to_decimal_spec.rb +10 -0
- data/spec/unit/coercible/coercer/numeric/to_float_spec.rb +10 -0
- data/spec/unit/coercible/coercer/numeric/to_integer_spec.rb +10 -0
- data/spec/unit/coercible/coercer/numeric/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/object/to_array_spec.rb +51 -0
- data/spec/unit/coercible/coercer/object/to_hash_spec.rb +22 -0
- data/spec/unit/coercible/coercer/object/to_integer_spec.rb +22 -0
- data/spec/unit/coercible/coercer/object/to_string_spec.rb +22 -0
- data/spec/unit/coercible/coercer/string/to_boolean_spec.rb +31 -0
- data/spec/unit/coercible/coercer/string/to_constant_spec.rb +49 -0
- data/spec/unit/coercible/coercer/string/to_date_spec.rb +25 -0
- data/spec/unit/coercible/coercer/string/to_datetime_spec.rb +52 -0
- data/spec/unit/coercible/coercer/string/to_decimal_spec.rb +47 -0
- data/spec/unit/coercible/coercer/string/to_float_spec.rb +57 -0
- data/spec/unit/coercible/coercer/string/to_integer_spec.rb +68 -0
- data/spec/unit/coercible/coercer/string/to_symbol_spec.rb +9 -0
- data/spec/unit/coercible/coercer/string/to_time_spec.rb +52 -0
- data/spec/unit/coercible/coercer/string_spec.rb +11 -0
- data/spec/unit/coercible/coercer/symbol/to_string_spec.rb +12 -0
- data/spec/unit/coercible/coercer/time/to_integer_spec.rb +10 -0
- data/spec/unit/coercible/coercer/time/to_time_spec.rb +10 -0
- data/spec/unit/coercible/coercer/time_coercions/to_date_spec.rb +30 -0
- data/spec/unit/coercible/coercer/time_coercions/to_datetime_spec.rb +34 -0
- data/spec/unit/coercible/coercer/time_coercions/to_string_spec.rb +19 -0
- data/spec/unit/coercible/coercer/time_coercions/to_time_spec.rb +34 -0
- data/spec/unit/coercible/coercer/true_class/to_string_spec.rb +12 -0
- data/spec/unit/coercible/configuration/class_methods/build_spec.rb +15 -0
- metadata +235 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Hash, '.to_time' do
|
4
|
+
subject { object.to_time(hash) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
|
8
|
+
context 'when time segments are missing' do
|
9
|
+
let(:time_now) { Time.local(2011, 1, 1) }
|
10
|
+
let(:hash) { {} }
|
11
|
+
|
12
|
+
before do
|
13
|
+
Time.stub!(:now).and_return(time_now) # freeze time
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should be_instance_of(Time) }
|
17
|
+
|
18
|
+
it 'uses the Time now to populate the segments' do
|
19
|
+
should eql(time_now)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when time segments are integers' do
|
24
|
+
let(:hash) { { :year => 2011, :month => 1, :day => 1, :hour => 1, :min => 1, :sec => 1 } }
|
25
|
+
|
26
|
+
it { should be_instance_of(Time) }
|
27
|
+
|
28
|
+
it { should eql(Time.local(2011, 1, 1, 1, 1, 1)) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when time segments are strings' do
|
32
|
+
let(:hash) { { :year => '2011', :month => '1', :day => '1', :hour => '1', :min => '1', :sec => '1' } }
|
33
|
+
|
34
|
+
it { should be_instance_of(Time) }
|
35
|
+
|
36
|
+
it { should eql(Time.local(2011, 1, 1, 1, 1, 1)) }
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Integer, '.to_boolean' do
|
4
|
+
subject { object.to_boolean(fixnum) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
|
8
|
+
context 'when the fixnum is 1' do
|
9
|
+
let(:fixnum) { 1 }
|
10
|
+
|
11
|
+
it { should be(true) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the fixnum is 0' do
|
15
|
+
let(:fixnum) { 0 }
|
16
|
+
|
17
|
+
it { should be(false) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the fixnum is not 1 or 0' do
|
21
|
+
let(:fixnum) { -1 }
|
22
|
+
|
23
|
+
specify do
|
24
|
+
expect { subject }.to raise_error(UnsupportedCoercion)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Integer, '.to_decimal' do
|
4
|
+
subject { object.to_decimal(fixnum) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:fixnum) { 1 }
|
8
|
+
|
9
|
+
it { should be_instance_of(BigDecimal) }
|
10
|
+
|
11
|
+
it { should eql(BigDecimal('1.0')) }
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Numeric, '.to_string' do
|
4
|
+
subject { object.to_string(numeric) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:numeric) { Rational(2, 2) }
|
8
|
+
|
9
|
+
let(:coerced_value) { RUBY_VERSION < '1.9' ? '1' : '1/1' }
|
10
|
+
|
11
|
+
it { should eql(coerced_value) }
|
12
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Object, '.to_array' do
|
4
|
+
subject { object.to_array(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:value) { Object.new }
|
8
|
+
let(:coerced) { [ value ] }
|
9
|
+
|
10
|
+
context 'when the value responds to #to_ary' do
|
11
|
+
before do
|
12
|
+
value.should_receive(:to_ary).with().and_return(coerced)
|
13
|
+
end
|
14
|
+
|
15
|
+
it { should be(coerced) }
|
16
|
+
|
17
|
+
it 'does not call #to_a if #to_ary is available' do
|
18
|
+
value.should_not_receive(:to_a)
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the value responds to #to_a but not #to_ary' do
|
24
|
+
before do
|
25
|
+
value.should_receive(:to_a).with().and_return(coerced)
|
26
|
+
end
|
27
|
+
|
28
|
+
it { should be(coerced) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when the value does not respond to #to_ary or #to_a' do
|
32
|
+
it { should be_instance_of(Array) }
|
33
|
+
|
34
|
+
it { should == coerced }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when the value returns nil from #to_ary' do
|
38
|
+
before do
|
39
|
+
value.should_receive(:to_ary).with().and_return(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'calls #to_a as a fallback' do
|
43
|
+
value.should_receive(:to_a).with().and_return(coerced)
|
44
|
+
should be(coerced)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'wraps the value in an Array if #to_a is not available' do
|
48
|
+
should == coerced
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Object, '.to_hash' do
|
4
|
+
subject { object.to_hash(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:value) { stub('value') }
|
8
|
+
|
9
|
+
context 'when the value responds to #to_hash' do
|
10
|
+
let(:coerced) { stub('coerced') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
value.should_receive(:to_hash).with().and_return(coerced)
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should be(coerced) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when the value does not respond to #to_hash' do
|
20
|
+
it { should be(value) }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Object, '.to_integer' do
|
4
|
+
subject { object.to_integer(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:value) { stub('value') }
|
8
|
+
|
9
|
+
context 'when the value responds to #to_int' do
|
10
|
+
let(:coerced) { stub('coerced') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
value.should_receive(:to_int).with().and_return(coerced)
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should be(coerced) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when the value does not respond to #to_int' do
|
20
|
+
it { should be(value) }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::Object, '.to_string' do
|
4
|
+
subject { object.to_string(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
let(:value) { Object.new }
|
8
|
+
|
9
|
+
context 'when the value responds to #to_str' do
|
10
|
+
let(:coerced) { stub('coerced') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
value.should_receive(:to_str).with().and_return(coerced)
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should be(coerced) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when the value does not respond to #to_str' do
|
20
|
+
it { should be(value) }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::String, '.to_boolean' do
|
4
|
+
subject { object.to_boolean(string) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
|
8
|
+
%w[ 1 on ON t true T TRUE y yes Y YES ].each do |value|
|
9
|
+
context "with #{value.inspect}" do
|
10
|
+
let(:string) { value }
|
11
|
+
|
12
|
+
it { should be(true) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
%w[ 0 off OFF f false F FALSE n no N NO ].each do |value|
|
17
|
+
context "with #{value.inspect}" do
|
18
|
+
let(:string) { value }
|
19
|
+
|
20
|
+
it { should be(false) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with an invalid boolean string' do
|
25
|
+
let(:string) { 'non-boolean' }
|
26
|
+
|
27
|
+
specify do
|
28
|
+
expect { subject }.to raise_error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::String, '.to_constant' do
|
4
|
+
subject { object.to_constant(string) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
|
8
|
+
context 'with a non-namespaced name' do
|
9
|
+
let(:string) { 'String' }
|
10
|
+
|
11
|
+
it { should be(String) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with a non-namespaced qualified name' do
|
15
|
+
let(:string) { '::String' }
|
16
|
+
|
17
|
+
it { should be(String) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with a namespaced name' do
|
21
|
+
let(:string) { 'Coercible::Coercer::String' }
|
22
|
+
|
23
|
+
it { should be(Coercer::String) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with a namespaced qualified name' do
|
27
|
+
let(:string) { '::Coercible::Coercer::String' }
|
28
|
+
|
29
|
+
it { should be(Coercer::String) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with a name outside of the namespace' do
|
33
|
+
let(:string) { 'Virtus::Object' }
|
34
|
+
|
35
|
+
specify { expect { subject }.to raise_error(NameError) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when the name is unknown' do
|
39
|
+
let(:string) { 'Unknown' }
|
40
|
+
|
41
|
+
specify { expect { subject }.to raise_error(NameError) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when the name is invalid' do
|
45
|
+
let(:string) { 'invalid' }
|
46
|
+
|
47
|
+
specify { expect { subject }.to raise_error(NameError) }
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Coercer::String, '.to_date' do
|
4
|
+
subject { object.to_date(string) }
|
5
|
+
|
6
|
+
let(:object) { described_class.new }
|
7
|
+
|
8
|
+
context 'with a valid date string' do
|
9
|
+
let(:string) { 'July, 22th, 2011' }
|
10
|
+
|
11
|
+
it { should be_instance_of(Date) }
|
12
|
+
|
13
|
+
its(:year) { should == 2011 }
|
14
|
+
its(:month) { should == 7 }
|
15
|
+
its(:day) { should == 22 }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with an invalid date string' do
|
19
|
+
let(:string) { 'non-date' }
|
20
|
+
|
21
|
+
specify do
|
22
|
+
expect { subject }.to raise_error(UnsupportedCoercion)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'a correct datetime object' do
|
4
|
+
it { should be_instance_of(DateTime) }
|
5
|
+
|
6
|
+
its(:year) { should == year }
|
7
|
+
its(:month) { should == month }
|
8
|
+
its(:day) { should == day }
|
9
|
+
its(:hour) { should == hour }
|
10
|
+
its(:min) { should == min }
|
11
|
+
its(:sec) { should == sec }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Coercer::String, '.to_datetime' do
|
15
|
+
subject { object.to_datetime(string) }
|
16
|
+
|
17
|
+
let(:object) { described_class.new }
|
18
|
+
|
19
|
+
context 'with a valid date string' do
|
20
|
+
let(:year) { 2011 }
|
21
|
+
let(:month) { 7 }
|
22
|
+
let(:day) { 22 }
|
23
|
+
|
24
|
+
context 'not including time part' do
|
25
|
+
let(:string) { "July, #{day}th, #{year}" }
|
26
|
+
|
27
|
+
let(:hour) { 0 }
|
28
|
+
let(:min) { 0 }
|
29
|
+
let(:sec) { 0 }
|
30
|
+
|
31
|
+
it_should_behave_like 'a correct datetime object'
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'including time part' do
|
35
|
+
let(:string) { "July, #{day}, #{year}, #{hour}:#{min}:#{sec}" }
|
36
|
+
|
37
|
+
let(:hour) { 13 }
|
38
|
+
let(:min) { 44 }
|
39
|
+
let(:sec) { 50 }
|
40
|
+
|
41
|
+
it_should_behave_like 'a correct datetime object'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with an invalid date time string' do
|
46
|
+
let(:string) { 'non-datetime' }
|
47
|
+
|
48
|
+
specify {
|
49
|
+
expect { subject }.to raise_error(UnsupportedCoercion)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|