virtus 0.0.10 → 0.1.0

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 (154) hide show
  1. data/.gitignore +33 -7
  2. data/.travis.yml +4 -74
  3. data/Changelog.md +11 -2
  4. data/Gemfile +10 -9
  5. data/README.md +85 -1
  6. data/TODO +18 -0
  7. data/config/flay.yml +2 -2
  8. data/config/flog.yml +1 -1
  9. data/config/roodi.yml +3 -3
  10. data/config/site.reek +8 -3
  11. data/lib/virtus.rb +5 -0
  12. data/lib/virtus/attribute.rb +137 -30
  13. data/lib/virtus/attribute/array.rb +17 -1
  14. data/lib/virtus/attribute/boolean.rb +8 -13
  15. data/lib/virtus/attribute/collection.rb +96 -0
  16. data/lib/virtus/attribute/default_value.rb +11 -7
  17. data/lib/virtus/attribute/embedded_value.rb +70 -0
  18. data/lib/virtus/attribute/set.rb +25 -0
  19. data/lib/virtus/attribute_set.rb +18 -16
  20. data/lib/virtus/attributes_accessor.rb +66 -0
  21. data/lib/virtus/class_methods.rb +50 -28
  22. data/lib/virtus/coercion/array.rb +23 -0
  23. data/lib/virtus/coercion/string.rb +10 -4
  24. data/lib/virtus/instance_methods.rb +38 -31
  25. data/lib/virtus/support/options.rb +6 -8
  26. data/lib/virtus/support/type_lookup.rb +4 -11
  27. data/lib/virtus/version.rb +1 -1
  28. data/spec/integration/collection_member_coercion_spec.rb +75 -0
  29. data/spec/integration/custom_attributes_spec.rb +49 -0
  30. data/spec/integration/default_values_spec.rb +32 -0
  31. data/spec/integration/defining_attributes_spec.rb +79 -0
  32. data/spec/integration/embedded_value_spec.rb +50 -0
  33. data/spec/integration/overriding_virtus_spec.rb +46 -0
  34. data/spec/integration/virtus/instance_level_attributes_spec.rb +23 -0
  35. data/spec/rcov.opts +1 -0
  36. data/spec/shared/constants_helpers.rb +9 -0
  37. data/spec/shared/options_class_method.rb +19 -0
  38. data/spec/spec_helper.rb +20 -7
  39. data/spec/unit/virtus/attribute/array/coerce_spec.rb +13 -0
  40. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +85 -0
  41. data/spec/unit/virtus/attribute/boolean/define_reader_method_spec.rb +15 -0
  42. data/spec/unit/virtus/attribute/boolean/value_coerced_spec.rb +97 -0
  43. data/spec/unit/virtus/attribute/boolean_spec.rb +2 -81
  44. data/spec/unit/virtus/attribute/class/coerce_spec.rb +13 -0
  45. data/spec/unit/virtus/attribute/class_methods/accessor_spec.rb +12 -0
  46. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +37 -0
  47. data/spec/unit/virtus/attribute/class_methods/coercion_method_spec.rb +9 -0
  48. data/spec/unit/virtus/attribute/class_methods/default_spec.rb +9 -0
  49. data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +31 -1
  50. data/spec/unit/virtus/attribute/class_methods/merge_options_spec.rb +11 -0
  51. data/spec/unit/virtus/attribute/class_methods/primitive_spec.rb +9 -0
  52. data/spec/unit/virtus/attribute/class_methods/reader_spec.rb +9 -0
  53. data/spec/unit/virtus/attribute/class_methods/writer_spec.rb +9 -0
  54. data/spec/unit/virtus/attribute/coerce_spec.rb +30 -0
  55. data/spec/unit/virtus/attribute/coercion_method_spec.rb +12 -0
  56. data/spec/unit/virtus/attribute/collection/class_methods/merge_options_spec.rb +40 -0
  57. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +26 -0
  58. data/spec/unit/virtus/attribute/date/coerce_spec.rb +47 -0
  59. data/spec/unit/virtus/attribute/date/value_coerced_spec.rb +46 -0
  60. data/spec/unit/virtus/attribute/date_time/coerce_spec.rb +68 -0
  61. data/spec/unit/virtus/attribute/decimal/coerce_spec.rb +117 -0
  62. data/spec/unit/virtus/attribute/default_spec.rb +32 -0
  63. data/spec/unit/virtus/attribute/default_value/attribute_spec.rb +11 -0
  64. data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +4 -2
  65. data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +51 -0
  66. data/spec/unit/virtus/attribute/default_value/instance_methods/evaluate_spec.rb +9 -6
  67. data/spec/unit/virtus/attribute/default_value/value_spec.rb +11 -0
  68. data/spec/unit/virtus/attribute/define_accessor_methods_spec.rb +26 -0
  69. data/spec/unit/virtus/attribute/define_reader_method_spec.rb +24 -0
  70. data/spec/unit/virtus/attribute/define_writer_method_spec.rb +24 -0
  71. data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +17 -0
  72. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +50 -0
  73. data/spec/unit/virtus/attribute/float/coerce_spec.rb +117 -0
  74. data/spec/unit/virtus/attribute/get_spec.rb +80 -0
  75. data/spec/unit/virtus/attribute/inspect_spec.rb +27 -0
  76. data/spec/unit/virtus/attribute/instance_variable_name_spec.rb +12 -0
  77. data/spec/unit/virtus/attribute/integer/coerce_spec.rb +105 -0
  78. data/spec/unit/virtus/attribute/name_spec.rb +12 -0
  79. data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +1 -1
  80. data/spec/unit/virtus/attribute/numeric/class_methods/max_spec.rb +9 -0
  81. data/spec/unit/virtus/attribute/numeric/class_methods/min_spec.rb +9 -0
  82. data/spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb +9 -7
  83. data/spec/unit/virtus/attribute/options_spec.rb +14 -0
  84. data/spec/unit/virtus/attribute/public_reader_spec.rb +24 -0
  85. data/spec/unit/virtus/attribute/public_writer_spec.rb +24 -0
  86. data/spec/unit/virtus/attribute/reader_visibility_spec.rb +24 -0
  87. data/spec/unit/virtus/attribute/set/coerce_spec.rb +13 -0
  88. data/spec/unit/virtus/attribute/set_spec.rb +49 -0
  89. data/spec/unit/virtus/attribute/string/coerce_spec.rb +11 -0
  90. data/spec/unit/virtus/attribute/time/coerce_spec.rb +67 -0
  91. data/spec/unit/virtus/attribute/value_coerced_spec.rb +19 -0
  92. data/spec/unit/virtus/attribute/writer_visibility_spec.rb +24 -0
  93. data/spec/unit/virtus/attribute_set/append_spec.rb +12 -0
  94. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +4 -0
  95. data/spec/unit/virtus/attribute_set/element_set_spec.rb +29 -9
  96. data/spec/unit/virtus/attributes_accessor/inspect_spec.rb +9 -0
  97. data/spec/unit/virtus/class_methods/attribute_spec.rb +23 -5
  98. data/spec/unit/virtus/class_methods/attributes_spec.rb +3 -5
  99. data/spec/unit/virtus/class_methods/const_missing_spec.rb +27 -0
  100. data/spec/unit/virtus/class_methods/inherited_spec.rb +21 -0
  101. data/spec/unit/virtus/coercion/array/to_set_spec.rb +12 -0
  102. data/spec/unit/virtus/coercion/date/class_methods/to_date_spec.rb +10 -0
  103. data/spec/unit/virtus/coercion/date_time/class_methods/to_datetime_spec.rb +10 -0
  104. data/spec/unit/virtus/coercion/hash/class_methods/to_date_spec.rb +10 -3
  105. data/spec/unit/virtus/coercion/hash/class_methods/to_datetime_spec.rb +10 -3
  106. data/spec/unit/virtus/coercion/hash/class_methods/to_time_spec.rb +10 -3
  107. data/spec/unit/virtus/coercion/object/class_methods/method_missing_spec.rb +8 -8
  108. data/spec/unit/virtus/coercion/string/class_methods/to_boolean_spec.rb +2 -2
  109. data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +1 -1
  110. data/spec/unit/virtus/coercion/string/class_methods/to_date_spec.rb +1 -1
  111. data/spec/unit/virtus/coercion/string/class_methods/to_datetime_spec.rb +13 -13
  112. data/spec/unit/virtus/coercion/string/class_methods/to_decimal_spec.rb +25 -1
  113. data/spec/unit/virtus/coercion/string/class_methods/to_float_spec.rb +25 -1
  114. data/spec/unit/virtus/coercion/string/class_methods/to_integer_spec.rb +30 -1
  115. data/spec/unit/virtus/coercion/string/class_methods/to_time_spec.rb +13 -13
  116. data/spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb +10 -0
  117. data/spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb +1 -1
  118. data/spec/unit/virtus/instance_methods/attributes_spec.rb +77 -20
  119. data/spec/unit/virtus/instance_methods/element_reference_spec.rb +1 -1
  120. data/spec/unit/virtus/instance_methods/element_set_spec.rb +2 -2
  121. data/spec/unit/virtus/instance_methods/to_hash_spec.rb +23 -0
  122. data/spec/unit/virtus/options/accept_options_spec.rb +10 -11
  123. data/spec/unit/virtus/options/accepted_options_spec.rb +1 -1
  124. data/spec/unit/virtus/options/options_spec.rb +27 -4
  125. data/tasks/metrics/ci.rake +2 -1
  126. data/tasks/metrics/heckle.rake +207 -0
  127. data/tasks/spec.rake +14 -7
  128. data/virtus.gemspec +1 -1
  129. metadata +111 -97
  130. data/VERSION +0 -1
  131. data/examples/custom_coercion_spec.rb +0 -50
  132. data/examples/default_values_spec.rb +0 -21
  133. data/examples/override_attribute_methods_spec.rb +0 -40
  134. data/spec/integration/virtus/attributes/attribute/set_spec.rb +0 -36
  135. data/spec/integration/virtus/class_methods/attribute_spec.rb +0 -82
  136. data/spec/integration/virtus/class_methods/attributes_spec.rb +0 -22
  137. data/spec/integration/virtus/class_methods/const_missing_spec.rb +0 -44
  138. data/spec/unit/shared/attribute.rb +0 -7
  139. data/spec/unit/shared/attribute/accept_options.rb +0 -37
  140. data/spec/unit/shared/attribute/accepted_options.rb +0 -5
  141. data/spec/unit/shared/attribute/get.rb +0 -44
  142. data/spec/unit/shared/attribute/inspect.rb +0 -7
  143. data/spec/unit/shared/attribute/set.rb +0 -37
  144. data/spec/unit/virtus/attribute/array_spec.rb +0 -24
  145. data/spec/unit/virtus/attribute/class_spec.rb +0 -24
  146. data/spec/unit/virtus/attribute/date_spec.rb +0 -59
  147. data/spec/unit/virtus/attribute/date_time_spec.rb +0 -87
  148. data/spec/unit/virtus/attribute/decimal_spec.rb +0 -109
  149. data/spec/unit/virtus/attribute/float_spec.rb +0 -109
  150. data/spec/unit/virtus/attribute/hash_spec.rb +0 -11
  151. data/spec/unit/virtus/attribute/integer_spec.rb +0 -99
  152. data/spec/unit/virtus/attribute/string_spec.rb +0 -21
  153. data/spec/unit/virtus/attribute/time_spec.rb +0 -82
  154. data/spec/unit/virtus/class_methods/new_spec.rb +0 -41
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::DefaultValue, '#value' do
4
+ subject { object.value }
5
+
6
+ let(:object) { described_class.new(attribute, value) }
7
+ let(:attribute) { mock('attribute') }
8
+ let(:value) { mock('value') }
9
+
10
+ it { should be(value) }
11
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#define_accessor_methods' do
4
+ subject { object.define_accessor_methods(mod) }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+ let(:mod) { stub('mod') }
11
+
12
+ before do
13
+ object.stub(:define_reader_method).with(mod)
14
+ object.stub(:define_writer_method).with(mod)
15
+ end
16
+
17
+ it 'delegates to #define_reader_method' do
18
+ object.should_receive(:define_reader_method).with(mod)
19
+ subject
20
+ end
21
+
22
+ it 'delegates to #define_writer_method' do
23
+ object.should_receive(:define_writer_method).with(mod)
24
+ subject
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#define_reader_method' do
4
+ subject { object.define_reader_method(mod) }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+ let(:reader_visibility) { stub('reader_visibility') }
11
+ let(:mod) { mock('mod') }
12
+
13
+ before do
14
+ options.update(:reader => reader_visibility)
15
+ mod.stub(:define_reader_method).with(object, :name, reader_visibility)
16
+ end
17
+
18
+ it { should be(object) }
19
+
20
+ it 'calls #define_reader_method on the module' do
21
+ mod.should_receive(:define_reader_method).with(object, :name, reader_visibility)
22
+ subject
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#define_writer_method' do
4
+ subject { object.define_writer_method(mod) }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+ let(:writer_visibility) { stub('writer_visibility') }
11
+ let(:mod) { mock('mod') }
12
+
13
+ before do
14
+ options.update(:writer => writer_visibility)
15
+ mod.stub(:define_writer_method).with(object, :name=, writer_visibility)
16
+ end
17
+
18
+ it { should be(object) }
19
+
20
+ it 'calls #define_writer_method on the module' do
21
+ mod.should_receive(:define_writer_method).with(object, :name=, writer_visibility)
22
+ subject
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::EmbeddedValue, '.merge_options' do
4
+ subject { object.merge_options(type, options) }
5
+
6
+ let(:object) { described_class }
7
+ let(:type) { stub('type') }
8
+ let(:options) { {}.freeze }
9
+
10
+ it { should be_instance_of(Hash) }
11
+
12
+ it { should_not equal(options) }
13
+
14
+ it 'merges the type in as the model' do
15
+ should eql(:model => type)
16
+ end
17
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::EmbeddedValue, '#coerce' do
4
+ subject { object.coerce(value) }
5
+
6
+ let(:attribute_name) { :attribute_name }
7
+ let(:model) { OpenStruct }
8
+ let(:instance) { Object.new }
9
+
10
+ context 'when the value is a hash' do
11
+ let(:value) { Hash[:foo => 'bar'] }
12
+
13
+ context 'when the options include the model' do
14
+ let(:object) { described_class.new(attribute_name, :model => model) }
15
+ let(:model) { mock('model') }
16
+ let(:model_instance) { mock('model_instance') }
17
+
18
+ before do
19
+ model.should_receive(:new).with(value).and_return(model_instance)
20
+ end
21
+
22
+ it { should be(model_instance) }
23
+ end
24
+
25
+ context 'with the default OpenStruct model' do
26
+ let(:model_instance) { OpenStruct.new(value) }
27
+
28
+ context 'when the options are an empty Hash' do
29
+ let(:object) { described_class.new(attribute_name, {}) }
30
+
31
+ it { should == model_instance }
32
+ end
33
+
34
+ context 'when the options are not provided' do
35
+ let(:object) { described_class.new(attribute_name) }
36
+
37
+ it { should == model_instance }
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'when the value is not a hash' do
43
+ let(:object) { described_class.new(attribute_name) }
44
+ let(:value) { mock('value') }
45
+
46
+ before { model.should_not_receive(:new) }
47
+
48
+ it { should be(value) }
49
+ end
50
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Float, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { described_class.new(:score) }
7
+
8
+ context 'with a float' do
9
+ let(:value) { 24.0 }
10
+
11
+ it { should eql(value) }
12
+ end
13
+
14
+ context 'with a zero string integer' do
15
+ let(:value) { '0' }
16
+
17
+ it { should eql(0.0) }
18
+ end
19
+
20
+ context 'with a positive string integer' do
21
+ let(:value) { '24' }
22
+
23
+ it { should eql(24.0) }
24
+ end
25
+
26
+ context 'with a negative string integer' do
27
+ let(:value) { '-24' }
28
+
29
+ it { should eql(-24.0) }
30
+ end
31
+
32
+ context 'with a zero string float' do
33
+ let(:value) { '0.0' }
34
+
35
+ it { should eql(0.0) }
36
+ end
37
+
38
+ context 'with a positive string float' do
39
+ let(:value) { '24.35' }
40
+
41
+ it { should eql(24.35) }
42
+ end
43
+
44
+ context 'with a negative string float' do
45
+ let(:value) { '-24.35' }
46
+
47
+ it { should eql(-24.35) }
48
+ end
49
+
50
+ context 'with a zero string float, with no leading digits' do
51
+ let(:value) { '.0' }
52
+
53
+ it { should eql(0.0) }
54
+ end
55
+
56
+ context 'with a positive string float, with no leading digits' do
57
+ let(:value) { '.41' }
58
+
59
+ it { should eql(0.41) }
60
+ end
61
+
62
+ context 'with a zero integer' do
63
+ let(:value) { 0 }
64
+
65
+ it { should eql(0.0) }
66
+ end
67
+
68
+ context 'with a positive integer' do
69
+ let(:value) { 24 }
70
+
71
+ it { should eql(24.0) }
72
+ end
73
+
74
+ context 'with a negative integer' do
75
+ let(:value) { -24 }
76
+
77
+ it { should eql(-24.0) }
78
+ end
79
+
80
+ context 'with a positive bignum' do
81
+ let(:value) { 1311935550 }
82
+
83
+ it { should eql(1311935550.0) }
84
+ end
85
+
86
+ context 'with a negative bignum' do
87
+ let(:value) { -1311935550 }
88
+
89
+ it { should eql(-1311935550.0) }
90
+ end
91
+
92
+ context 'with a zero decimal' do
93
+ let(:value) { BigDecimal('0.0') }
94
+
95
+ it { should eql(0.0) }
96
+ end
97
+
98
+ context 'with a positive decimal' do
99
+ let(:value) { BigDecimal('24.35') }
100
+
101
+ it { should eql(24.35) }
102
+ end
103
+
104
+ context 'with a negative decimal' do
105
+ let(:value) { BigDecimal('-24.35') }
106
+
107
+ it { should eql(-24.35) }
108
+ end
109
+
110
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |non_num_value|
111
+ context 'does not coerce non-numeric value #{non_num_value.inspect}' do
112
+ let(:value) { non_num_value }
113
+
114
+ it { should equal(non_num_value) }
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#get' do
4
+ subject { object.get(instance) }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+ let(:instance) { Object.new }
11
+
12
+ context 'when the instance variable is set' do
13
+ let(:value) { stub('value') }
14
+
15
+ before do
16
+ instance.instance_variable_set(:@name, value)
17
+ end
18
+
19
+ it 'gets the value from the instance variable' do
20
+ should be(value)
21
+ end
22
+ end
23
+
24
+ context 'when the instance variable is not set' do
25
+ context 'when there is no default' do
26
+ it 'returns nil' do
27
+ should be_nil
28
+ end
29
+
30
+ it 'sets the ivar' do
31
+ expect { subject }.to change { instance.instance_variable_defined?(:@name) }.from(false).to(true)
32
+ end
33
+ end
34
+
35
+ context 'when there is a default' do
36
+ let(:default) { stub('default') }
37
+
38
+ before do
39
+ default.stub(:clone).and_return(default)
40
+ options.update(:default => default)
41
+ end
42
+
43
+ it 'gets the default from the instance variable' do
44
+ should be(default)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ describe Virtus::Attribute, '#get!' do
51
+ subject { object.get!(instance) }
52
+
53
+ let(:object) { described_class.new(:name, options) }
54
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
55
+ let(:primitive) { stub('primitive') }
56
+ let(:coercion_method) { stub('coercion_method') }
57
+ let(:instance) { Object.new }
58
+
59
+ context 'when the instance variable is set' do
60
+ let(:value) { stub('value') }
61
+
62
+ before do
63
+ instance.instance_variable_set(:@name, value)
64
+ end
65
+
66
+ it 'gets the value from the instance variable' do
67
+ should be(value)
68
+ end
69
+ end
70
+
71
+ context 'when the instance variable is not set' do
72
+ it 'returns nil' do
73
+ should be_nil
74
+ end
75
+
76
+ it 'does not set the ivar' do
77
+ expect { subject }.to_not change { instance.instance_variable_defined?(:@name) }
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#inspect' do
4
+ subject { object.inspect }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+
11
+ context 'with a named attribute class' do
12
+ let(:described_class) { NamedAttribute = Class.new(Virtus::Attribute) }
13
+
14
+ after do
15
+ klass = Object.class_eval { remove_const(:NamedAttribute) }
16
+ Virtus::Attribute.descendants.delete(klass)
17
+ end
18
+
19
+ it { should eql("#<NamedAttribute @name=:name>") }
20
+ end
21
+
22
+ context 'with an anonymous attribute class' do
23
+ let(:described_class) { Class.new(Virtus::Attribute) }
24
+
25
+ it { should eql("#<#{described_class} @name=:name>") }
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#instance_variable_name' do
4
+ subject { object.instance_variable_name }
5
+
6
+ let(:object) { described_class.new(:name, options) }
7
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
8
+ let(:primitive) { stub('primitive') }
9
+ let(:coercion_method) { stub('coercion_method') }
10
+
11
+ it { should be(:@name) }
12
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Integer, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { described_class.new(:age) }
7
+
8
+ context 'with an integer' do
9
+ let(:value) { 24 }
10
+
11
+ it { should eql(value) }
12
+ end
13
+
14
+ context 'with a zero string integer' do
15
+ let(:value) { 24 }
16
+
17
+ it { should eql(value) }
18
+ end
19
+
20
+ context 'with a positive string integer' do
21
+ let(:value) { '24' }
22
+
23
+ it { should eql(24) }
24
+ end
25
+
26
+ context 'with a negative string integer' do
27
+ let(:value) { '-24' }
28
+
29
+ it { should eql(-24) }
30
+ end
31
+
32
+ context 'with a zero string float' do
33
+ let(:value) { 0.0 }
34
+
35
+ it { should eql(0) }
36
+ end
37
+
38
+ context 'with a positive string float' do
39
+ let(:value) { '24.35' }
40
+
41
+ it { should eql(24) }
42
+ end
43
+
44
+ context 'with a negative string float' do
45
+ let(:value) { '-24.35' }
46
+
47
+ it { should eql(-24) }
48
+ end
49
+
50
+ context 'with a zero string float, with no leading digits' do
51
+ let(:value) { '.0' }
52
+
53
+ it { should eql(0) }
54
+ end
55
+
56
+ context 'with a positive string float, with no leading digits' do
57
+ let(:value) { '.41' }
58
+
59
+ it { should eql(0) }
60
+ end
61
+
62
+ context 'with a zero float' do
63
+ let(:value) { 0.0 }
64
+
65
+ it { should eql(0) }
66
+ end
67
+
68
+ context 'with a positive float' do
69
+ let(:value) { 24.35 }
70
+
71
+ it { should eql(24) }
72
+ end
73
+
74
+ context 'with a negative float' do
75
+ let(:value) { -24.35 }
76
+
77
+ it { should eql(-24) }
78
+ end
79
+
80
+ context 'with a zero decimal' do
81
+ let(:value) { BigDecimal('0.0') }
82
+
83
+ it { should eql(0) }
84
+ end
85
+
86
+ context 'with a positive decimal' do
87
+ let(:value) { BigDecimal('24.35') }
88
+
89
+ it { should eql(24) }
90
+ end
91
+
92
+ context 'with a negative decimal' do
93
+ let(:value) { BigDecimal('-24.35') }
94
+
95
+ it { should eql(-24) }
96
+ end
97
+
98
+ [ Object.new, true, false, '00.0', '0.', '-.0', 'string' ].each do |non_num_value|
99
+ context 'does not coerce non-numeric value #{non_num_value.inspect}' do
100
+ let(:value) { non_num_value }
101
+
102
+ it { should equal(non_num_value) }
103
+ end
104
+ end
105
+ end