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.
Files changed (99) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +19 -0
  4. data/Changelog.md +4 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.devtools +44 -0
  7. data/Guardfile +58 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +64 -0
  10. data/Rakefile +2 -0
  11. data/coercible.gemspec +22 -0
  12. data/config/flay.yml +3 -0
  13. data/config/flog.yml +2 -0
  14. data/config/mutant.yml +3 -0
  15. data/config/roodi.yml +17 -0
  16. data/config/site.reek +91 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/coercible.rb +42 -0
  19. data/lib/coercible/coercer.rb +155 -0
  20. data/lib/coercible/coercer/array.rb +24 -0
  21. data/lib/coercible/coercer/configurable.rb +54 -0
  22. data/lib/coercible/coercer/date.rb +27 -0
  23. data/lib/coercible/coercer/date_time.rb +27 -0
  24. data/lib/coercible/coercer/decimal.rb +41 -0
  25. data/lib/coercible/coercer/false_class.rb +25 -0
  26. data/lib/coercible/coercer/float.rb +40 -0
  27. data/lib/coercible/coercer/hash.rb +72 -0
  28. data/lib/coercible/coercer/integer.rb +130 -0
  29. data/lib/coercible/coercer/numeric.rb +67 -0
  30. data/lib/coercible/coercer/object.rb +160 -0
  31. data/lib/coercible/coercer/string.rb +251 -0
  32. data/lib/coercible/coercer/symbol.rb +25 -0
  33. data/lib/coercible/coercer/time.rb +41 -0
  34. data/lib/coercible/coercer/time_coercions.rb +87 -0
  35. data/lib/coercible/coercer/true_class.rb +25 -0
  36. data/lib/coercible/configuration.rb +33 -0
  37. data/lib/coercible/version.rb +3 -0
  38. data/lib/support/options.rb +113 -0
  39. data/lib/support/type_lookup.rb +113 -0
  40. data/spec/integration/configuring_coercers_spec.rb +14 -0
  41. data/spec/shared/unit/configurable.rb +27 -0
  42. data/spec/spec_helper.rb +30 -0
  43. data/spec/unit/coercible/coercer/array/to_set_spec.rb +12 -0
  44. data/spec/unit/coercible/coercer/class_methods/new_spec.rb +13 -0
  45. data/spec/unit/coercible/coercer/date/to_date_spec.rb +10 -0
  46. data/spec/unit/coercible/coercer/date/to_datetime_spec.rb +30 -0
  47. data/spec/unit/coercible/coercer/date/to_string_spec.rb +12 -0
  48. data/spec/unit/coercible/coercer/date/to_time_spec.rb +12 -0
  49. data/spec/unit/coercible/coercer/date_time/to_date_spec.rb +30 -0
  50. data/spec/unit/coercible/coercer/date_time/to_datetime_spec.rb +10 -0
  51. data/spec/unit/coercible/coercer/date_time/to_string_spec.rb +12 -0
  52. data/spec/unit/coercible/coercer/date_time/to_time_spec.rb +30 -0
  53. data/spec/unit/coercible/coercer/decimal/to_decimal_spec.rb +9 -0
  54. data/spec/unit/coercible/coercer/decimal/to_float_spec.rb +12 -0
  55. data/spec/unit/coercible/coercer/decimal/to_integer_spec.rb +12 -0
  56. data/spec/unit/coercible/coercer/decimal/to_string_spec.rb +12 -0
  57. data/spec/unit/coercible/coercer/element_reference_spec.rb +19 -0
  58. data/spec/unit/coercible/coercer/false_class/to_string_spec.rb +12 -0
  59. data/spec/unit/coercible/coercer/float/to_decimal_spec.rb +12 -0
  60. data/spec/unit/coercible/coercer/float/to_float_spec.rb +9 -0
  61. data/spec/unit/coercible/coercer/float/to_integer_spec.rb +12 -0
  62. data/spec/unit/coercible/coercer/float/to_string_spec.rb +12 -0
  63. data/spec/unit/coercible/coercer/hash/to_date_spec.rb +38 -0
  64. data/spec/unit/coercible/coercer/hash/to_datetime_spec.rb +38 -0
  65. data/spec/unit/coercible/coercer/hash/to_time_spec.rb +38 -0
  66. data/spec/unit/coercible/coercer/integer/to_boolean_spec.rb +27 -0
  67. data/spec/unit/coercible/coercer/integer/to_decimal_spec.rb +12 -0
  68. data/spec/unit/coercible/coercer/integer/to_float_spec.rb +12 -0
  69. data/spec/unit/coercible/coercer/integer/to_integer_spec.rb +9 -0
  70. data/spec/unit/coercible/coercer/integer/to_string_spec.rb +12 -0
  71. data/spec/unit/coercible/coercer/integer_spec.rb +11 -0
  72. data/spec/unit/coercible/coercer/numeric/to_decimal_spec.rb +10 -0
  73. data/spec/unit/coercible/coercer/numeric/to_float_spec.rb +10 -0
  74. data/spec/unit/coercible/coercer/numeric/to_integer_spec.rb +10 -0
  75. data/spec/unit/coercible/coercer/numeric/to_string_spec.rb +12 -0
  76. data/spec/unit/coercible/coercer/object/to_array_spec.rb +51 -0
  77. data/spec/unit/coercible/coercer/object/to_hash_spec.rb +22 -0
  78. data/spec/unit/coercible/coercer/object/to_integer_spec.rb +22 -0
  79. data/spec/unit/coercible/coercer/object/to_string_spec.rb +22 -0
  80. data/spec/unit/coercible/coercer/string/to_boolean_spec.rb +31 -0
  81. data/spec/unit/coercible/coercer/string/to_constant_spec.rb +49 -0
  82. data/spec/unit/coercible/coercer/string/to_date_spec.rb +25 -0
  83. data/spec/unit/coercible/coercer/string/to_datetime_spec.rb +52 -0
  84. data/spec/unit/coercible/coercer/string/to_decimal_spec.rb +47 -0
  85. data/spec/unit/coercible/coercer/string/to_float_spec.rb +57 -0
  86. data/spec/unit/coercible/coercer/string/to_integer_spec.rb +68 -0
  87. data/spec/unit/coercible/coercer/string/to_symbol_spec.rb +9 -0
  88. data/spec/unit/coercible/coercer/string/to_time_spec.rb +52 -0
  89. data/spec/unit/coercible/coercer/string_spec.rb +11 -0
  90. data/spec/unit/coercible/coercer/symbol/to_string_spec.rb +12 -0
  91. data/spec/unit/coercible/coercer/time/to_integer_spec.rb +10 -0
  92. data/spec/unit/coercible/coercer/time/to_time_spec.rb +10 -0
  93. data/spec/unit/coercible/coercer/time_coercions/to_date_spec.rb +30 -0
  94. data/spec/unit/coercible/coercer/time_coercions/to_datetime_spec.rb +34 -0
  95. data/spec/unit/coercible/coercer/time_coercions/to_string_spec.rb +19 -0
  96. data/spec/unit/coercible/coercer/time_coercions/to_time_spec.rb +34 -0
  97. data/spec/unit/coercible/coercer/true_class/to_string_spec.rb +12 -0
  98. data/spec/unit/coercible/configuration/class_methods/build_spec.rb +15 -0
  99. 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::Integer, '.to_float' do
4
+ subject { object.to_float(fixnum) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:fixnum) { 1 }
8
+
9
+ it { should be_instance_of(Float) }
10
+
11
+ it { should eql(1.0) }
12
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Integer, '.to_integer' do
4
+ subject { described_class.new.to_integer(value) }
5
+
6
+ let(:value) { 1 }
7
+
8
+ it { should be(value) }
9
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Integer, '.to_string' do
4
+ subject { object.to_string(integer) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:integer) { 1 }
8
+
9
+ it { should be_instance_of(String) }
10
+
11
+ it { should eql('1') }
12
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Integer do
4
+ it_behaves_like 'Configurable' do
5
+ describe '.config_name' do
6
+ subject { described_class.config_name }
7
+
8
+ it { should be(:integer) }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Numeric, '.to_decimal' do
4
+ subject { object.to_decimal(numeric) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:numeric) { Rational(2, 2) }
8
+
9
+ it { should eql(BigDecimal('1.0')) }
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Numeric, '.to_float' do
4
+ subject { object.to_float(numeric) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:numeric) { Rational(2, 2) }
8
+
9
+ it { should eql(1.0) }
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Coercer::Numeric, '.to_integer' do
4
+ subject { object.to_integer(numeric) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:numeric) { Rational(2, 2) }
8
+
9
+ it { should eql(1) }
10
+ 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