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.
- data/.gitignore +33 -7
- data/.travis.yml +4 -74
- data/Changelog.md +11 -2
- data/Gemfile +10 -9
- data/README.md +85 -1
- data/TODO +18 -0
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/roodi.yml +3 -3
- data/config/site.reek +8 -3
- data/lib/virtus.rb +5 -0
- data/lib/virtus/attribute.rb +137 -30
- data/lib/virtus/attribute/array.rb +17 -1
- data/lib/virtus/attribute/boolean.rb +8 -13
- data/lib/virtus/attribute/collection.rb +96 -0
- data/lib/virtus/attribute/default_value.rb +11 -7
- data/lib/virtus/attribute/embedded_value.rb +70 -0
- data/lib/virtus/attribute/set.rb +25 -0
- data/lib/virtus/attribute_set.rb +18 -16
- data/lib/virtus/attributes_accessor.rb +66 -0
- data/lib/virtus/class_methods.rb +50 -28
- data/lib/virtus/coercion/array.rb +23 -0
- data/lib/virtus/coercion/string.rb +10 -4
- data/lib/virtus/instance_methods.rb +38 -31
- data/lib/virtus/support/options.rb +6 -8
- data/lib/virtus/support/type_lookup.rb +4 -11
- data/lib/virtus/version.rb +1 -1
- data/spec/integration/collection_member_coercion_spec.rb +75 -0
- data/spec/integration/custom_attributes_spec.rb +49 -0
- data/spec/integration/default_values_spec.rb +32 -0
- data/spec/integration/defining_attributes_spec.rb +79 -0
- data/spec/integration/embedded_value_spec.rb +50 -0
- data/spec/integration/overriding_virtus_spec.rb +46 -0
- data/spec/integration/virtus/instance_level_attributes_spec.rb +23 -0
- data/spec/rcov.opts +1 -0
- data/spec/shared/constants_helpers.rb +9 -0
- data/spec/shared/options_class_method.rb +19 -0
- data/spec/spec_helper.rb +20 -7
- data/spec/unit/virtus/attribute/array/coerce_spec.rb +13 -0
- data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +85 -0
- data/spec/unit/virtus/attribute/boolean/define_reader_method_spec.rb +15 -0
- data/spec/unit/virtus/attribute/boolean/value_coerced_spec.rb +97 -0
- data/spec/unit/virtus/attribute/boolean_spec.rb +2 -81
- data/spec/unit/virtus/attribute/class/coerce_spec.rb +13 -0
- data/spec/unit/virtus/attribute/class_methods/accessor_spec.rb +12 -0
- data/spec/unit/virtus/attribute/class_methods/build_spec.rb +37 -0
- data/spec/unit/virtus/attribute/class_methods/coercion_method_spec.rb +9 -0
- data/spec/unit/virtus/attribute/class_methods/default_spec.rb +9 -0
- data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +31 -1
- data/spec/unit/virtus/attribute/class_methods/merge_options_spec.rb +11 -0
- data/spec/unit/virtus/attribute/class_methods/primitive_spec.rb +9 -0
- data/spec/unit/virtus/attribute/class_methods/reader_spec.rb +9 -0
- data/spec/unit/virtus/attribute/class_methods/writer_spec.rb +9 -0
- data/spec/unit/virtus/attribute/coerce_spec.rb +30 -0
- data/spec/unit/virtus/attribute/coercion_method_spec.rb +12 -0
- data/spec/unit/virtus/attribute/collection/class_methods/merge_options_spec.rb +40 -0
- data/spec/unit/virtus/attribute/collection/coerce_spec.rb +26 -0
- data/spec/unit/virtus/attribute/date/coerce_spec.rb +47 -0
- data/spec/unit/virtus/attribute/date/value_coerced_spec.rb +46 -0
- data/spec/unit/virtus/attribute/date_time/coerce_spec.rb +68 -0
- data/spec/unit/virtus/attribute/decimal/coerce_spec.rb +117 -0
- data/spec/unit/virtus/attribute/default_spec.rb +32 -0
- data/spec/unit/virtus/attribute/default_value/attribute_spec.rb +11 -0
- data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +4 -2
- data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +51 -0
- data/spec/unit/virtus/attribute/default_value/instance_methods/evaluate_spec.rb +9 -6
- data/spec/unit/virtus/attribute/default_value/value_spec.rb +11 -0
- data/spec/unit/virtus/attribute/define_accessor_methods_spec.rb +26 -0
- data/spec/unit/virtus/attribute/define_reader_method_spec.rb +24 -0
- data/spec/unit/virtus/attribute/define_writer_method_spec.rb +24 -0
- data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +17 -0
- data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +50 -0
- data/spec/unit/virtus/attribute/float/coerce_spec.rb +117 -0
- data/spec/unit/virtus/attribute/get_spec.rb +80 -0
- data/spec/unit/virtus/attribute/inspect_spec.rb +27 -0
- data/spec/unit/virtus/attribute/instance_variable_name_spec.rb +12 -0
- data/spec/unit/virtus/attribute/integer/coerce_spec.rb +105 -0
- data/spec/unit/virtus/attribute/name_spec.rb +12 -0
- data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +1 -1
- data/spec/unit/virtus/attribute/numeric/class_methods/max_spec.rb +9 -0
- data/spec/unit/virtus/attribute/numeric/class_methods/min_spec.rb +9 -0
- data/spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb +9 -7
- data/spec/unit/virtus/attribute/options_spec.rb +14 -0
- data/spec/unit/virtus/attribute/public_reader_spec.rb +24 -0
- data/spec/unit/virtus/attribute/public_writer_spec.rb +24 -0
- data/spec/unit/virtus/attribute/reader_visibility_spec.rb +24 -0
- data/spec/unit/virtus/attribute/set/coerce_spec.rb +13 -0
- data/spec/unit/virtus/attribute/set_spec.rb +49 -0
- data/spec/unit/virtus/attribute/string/coerce_spec.rb +11 -0
- data/spec/unit/virtus/attribute/time/coerce_spec.rb +67 -0
- data/spec/unit/virtus/attribute/value_coerced_spec.rb +19 -0
- data/spec/unit/virtus/attribute/writer_visibility_spec.rb +24 -0
- data/spec/unit/virtus/attribute_set/append_spec.rb +12 -0
- data/spec/unit/virtus/attribute_set/element_reference_spec.rb +4 -0
- data/spec/unit/virtus/attribute_set/element_set_spec.rb +29 -9
- data/spec/unit/virtus/attributes_accessor/inspect_spec.rb +9 -0
- data/spec/unit/virtus/class_methods/attribute_spec.rb +23 -5
- data/spec/unit/virtus/class_methods/attributes_spec.rb +3 -5
- data/spec/unit/virtus/class_methods/const_missing_spec.rb +27 -0
- data/spec/unit/virtus/class_methods/inherited_spec.rb +21 -0
- data/spec/unit/virtus/coercion/array/to_set_spec.rb +12 -0
- data/spec/unit/virtus/coercion/date/class_methods/to_date_spec.rb +10 -0
- data/spec/unit/virtus/coercion/date_time/class_methods/to_datetime_spec.rb +10 -0
- data/spec/unit/virtus/coercion/hash/class_methods/to_date_spec.rb +10 -3
- data/spec/unit/virtus/coercion/hash/class_methods/to_datetime_spec.rb +10 -3
- data/spec/unit/virtus/coercion/hash/class_methods/to_time_spec.rb +10 -3
- data/spec/unit/virtus/coercion/object/class_methods/method_missing_spec.rb +8 -8
- data/spec/unit/virtus/coercion/string/class_methods/to_boolean_spec.rb +2 -2
- data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +1 -1
- data/spec/unit/virtus/coercion/string/class_methods/to_date_spec.rb +1 -1
- data/spec/unit/virtus/coercion/string/class_methods/to_datetime_spec.rb +13 -13
- data/spec/unit/virtus/coercion/string/class_methods/to_decimal_spec.rb +25 -1
- data/spec/unit/virtus/coercion/string/class_methods/to_float_spec.rb +25 -1
- data/spec/unit/virtus/coercion/string/class_methods/to_integer_spec.rb +30 -1
- data/spec/unit/virtus/coercion/string/class_methods/to_time_spec.rb +13 -13
- data/spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb +10 -0
- data/spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb +1 -1
- data/spec/unit/virtus/instance_methods/attributes_spec.rb +77 -20
- data/spec/unit/virtus/instance_methods/element_reference_spec.rb +1 -1
- data/spec/unit/virtus/instance_methods/element_set_spec.rb +2 -2
- data/spec/unit/virtus/instance_methods/to_hash_spec.rb +23 -0
- data/spec/unit/virtus/options/accept_options_spec.rb +10 -11
- data/spec/unit/virtus/options/accepted_options_spec.rb +1 -1
- data/spec/unit/virtus/options/options_spec.rb +27 -4
- data/tasks/metrics/ci.rake +2 -1
- data/tasks/metrics/heckle.rake +207 -0
- data/tasks/spec.rake +14 -7
- data/virtus.gemspec +1 -1
- metadata +111 -97
- data/VERSION +0 -1
- data/examples/custom_coercion_spec.rb +0 -50
- data/examples/default_values_spec.rb +0 -21
- data/examples/override_attribute_methods_spec.rb +0 -40
- data/spec/integration/virtus/attributes/attribute/set_spec.rb +0 -36
- data/spec/integration/virtus/class_methods/attribute_spec.rb +0 -82
- data/spec/integration/virtus/class_methods/attributes_spec.rb +0 -22
- data/spec/integration/virtus/class_methods/const_missing_spec.rb +0 -44
- data/spec/unit/shared/attribute.rb +0 -7
- data/spec/unit/shared/attribute/accept_options.rb +0 -37
- data/spec/unit/shared/attribute/accepted_options.rb +0 -5
- data/spec/unit/shared/attribute/get.rb +0 -44
- data/spec/unit/shared/attribute/inspect.rb +0 -7
- data/spec/unit/shared/attribute/set.rb +0 -37
- data/spec/unit/virtus/attribute/array_spec.rb +0 -24
- data/spec/unit/virtus/attribute/class_spec.rb +0 -24
- data/spec/unit/virtus/attribute/date_spec.rb +0 -59
- data/spec/unit/virtus/attribute/date_time_spec.rb +0 -87
- data/spec/unit/virtus/attribute/decimal_spec.rb +0 -109
- data/spec/unit/virtus/attribute/float_spec.rb +0 -109
- data/spec/unit/virtus/attribute/hash_spec.rb +0 -11
- data/spec/unit/virtus/attribute/integer_spec.rb +0 -99
- data/spec/unit/virtus/attribute/string_spec.rb +0 -21
- data/spec/unit/virtus/attribute/time_spec.rb +0 -82
- 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
|