virtus 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -5
  3. data/Changelog.md +7 -1
  4. data/Gemfile +14 -5
  5. data/README.md +40 -19
  6. data/Rakefile +13 -3
  7. data/lib/virtus/configuration.rb +10 -5
  8. data/lib/virtus/version.rb +1 -1
  9. data/spec/integration/collection_member_coercion_spec.rb +34 -13
  10. data/spec/integration/hash_attributes_coercion_spec.rb +5 -5
  11. data/spec/shared/freeze_method_behavior.rb +5 -2
  12. data/spec/shared/idempotent_method_behaviour.rb +1 -1
  13. data/spec/shared/options_class_method.rb +3 -3
  14. data/spec/spec_helper.rb +3 -18
  15. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +3 -3
  16. data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +3 -3
  17. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +48 -24
  18. data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +2 -2
  19. data/spec/unit/virtus/attribute/coerce_spec.rb +9 -9
  20. data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +2 -2
  21. data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +2 -2
  22. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +5 -5
  23. data/spec/unit/virtus/attribute/custom_collection_spec.rb +8 -2
  24. data/spec/unit/virtus/attribute/defined_spec.rb +2 -2
  25. data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +30 -15
  26. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +25 -11
  27. data/spec/unit/virtus/attribute/get_spec.rb +2 -2
  28. data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +7 -7
  29. data/spec/unit/virtus/attribute/hash/coerce_spec.rb +9 -9
  30. data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +2 -2
  31. data/spec/unit/virtus/attribute/rename_spec.rb +6 -3
  32. data/spec/unit/virtus/attribute/required_predicate_spec.rb +2 -2
  33. data/spec/unit/virtus/attribute/set_default_value_spec.rb +43 -10
  34. data/spec/unit/virtus/attribute/set_spec.rb +1 -1
  35. data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +2 -2
  36. data/spec/unit/virtus/attribute_set/append_spec.rb +2 -2
  37. data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +12 -11
  38. data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +13 -12
  39. data/spec/unit/virtus/attribute_set/each_spec.rb +3 -3
  40. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +1 -1
  41. data/spec/unit/virtus/attribute_set/element_set_spec.rb +2 -2
  42. data/spec/unit/virtus/attribute_set/merge_spec.rb +2 -2
  43. data/spec/unit/virtus/attribute_set/reset_spec.rb +17 -8
  44. data/spec/unit/virtus/attribute_spec.rb +4 -4
  45. data/spec/unit/virtus/element_reader_spec.rb +1 -1
  46. data/spec/unit/virtus/freeze_spec.rb +10 -3
  47. data/spec/unit/virtus/model_spec.rb +35 -4
  48. data/spec/unit/virtus/set_default_attributes_spec.rb +10 -3
  49. data/spec/unit/virtus/value_object_spec.rb +13 -3
  50. data/virtus.gemspec +6 -4
  51. metadata +16 -8
  52. data/Gemfile.devtools +0 -71
  53. data/config/flay.yml +0 -3
  54. data/config/flog.yml +0 -2
  55. data/config/mutant.yml +0 -15
  56. data/config/reek.yml +0 -146
  57. data/config/yardstick.yml +0 -2
@@ -8,18 +8,18 @@ describe Virtus::Attribute, '.build' do
8
8
  let(:options) { {} }
9
9
 
10
10
  shared_examples_for 'a valid attribute instance' do
11
- it { should be_instance_of(Virtus::Attribute) }
11
+ it { is_expected.to be_instance_of(Virtus::Attribute) }
12
12
 
13
- it { should be_frozen }
13
+ it { is_expected.to be_frozen }
14
14
  end
15
15
 
16
16
  context 'without options' do
17
17
  it_behaves_like 'a valid attribute instance'
18
18
 
19
- it { should be_coercible }
20
- it { should be_public_reader }
21
- it { should be_public_writer }
22
- it { should_not be_lazy }
19
+ it { is_expected.to be_coercible }
20
+ it { is_expected.to be_public_reader }
21
+ it { is_expected.to be_public_writer }
22
+ it { is_expected.not_to be_lazy }
23
23
 
24
24
  it 'sets up a coercer' do
25
25
  expect(subject.options[:coerce]).to be(true)
@@ -30,7 +30,10 @@ describe Virtus::Attribute, '.build' do
30
30
  context 'when name is passed as a string' do
31
31
  let(:name) { 'something' }
32
32
 
33
- its(:name) { should be(:something) }
33
+ describe '#name' do
34
+ subject { super().name }
35
+ it { is_expected.to be(:something) }
36
+ end
34
37
  end
35
38
 
36
39
  context 'when coercion is turned off in options' do
@@ -38,7 +41,7 @@ describe Virtus::Attribute, '.build' do
38
41
 
39
42
  it_behaves_like 'a valid attribute instance'
40
43
 
41
- it { should_not be_coercible }
44
+ it { is_expected.not_to be_coercible }
42
45
  end
43
46
 
44
47
  context 'when options specify reader visibility' do
@@ -46,8 +49,8 @@ describe Virtus::Attribute, '.build' do
46
49
 
47
50
  it_behaves_like 'a valid attribute instance'
48
51
 
49
- it { should_not be_public_reader }
50
- it { should be_public_writer }
52
+ it { is_expected.not_to be_public_reader }
53
+ it { is_expected.to be_public_writer }
51
54
  end
52
55
 
53
56
  context 'when options specify writer visibility' do
@@ -55,8 +58,8 @@ describe Virtus::Attribute, '.build' do
55
58
 
56
59
  it_behaves_like 'a valid attribute instance'
57
60
 
58
- it { should be_public_reader }
59
- it { should_not be_public_writer }
61
+ it { is_expected.to be_public_reader }
62
+ it { is_expected.not_to be_public_writer }
60
63
  end
61
64
 
62
65
  context 'when options specify lazy accessor' do
@@ -64,7 +67,7 @@ describe Virtus::Attribute, '.build' do
64
67
 
65
68
  it_behaves_like 'a valid attribute instance'
66
69
 
67
- it { should be_lazy }
70
+ it { is_expected.to be_lazy }
68
71
  end
69
72
 
70
73
  context 'when options specify strict mode' do
@@ -72,7 +75,7 @@ describe Virtus::Attribute, '.build' do
72
75
 
73
76
  it_behaves_like 'a valid attribute instance'
74
77
 
75
- it { should be_strict }
78
+ it { is_expected.to be_strict }
76
79
  end
77
80
 
78
81
  context 'when type is a string' do
@@ -80,7 +83,10 @@ describe Virtus::Attribute, '.build' do
80
83
 
81
84
  it_behaves_like 'a valid attribute instance'
82
85
 
83
- its(:type) { should be(Axiom::Types::Integer) }
86
+ describe '#type' do
87
+ subject { super().type }
88
+ it { is_expected.to be(Axiom::Types::Integer) }
89
+ end
84
90
  end
85
91
 
86
92
  context 'when type is a range' do
@@ -88,7 +94,10 @@ describe Virtus::Attribute, '.build' do
88
94
 
89
95
  it_behaves_like 'a valid attribute instance'
90
96
 
91
- its(:type) { should be(Axiom::Types.infer(Range)) }
97
+ describe '#type' do
98
+ subject { super().type }
99
+ it { is_expected.to be(Axiom::Types.infer(Range)) }
100
+ end
92
101
  end
93
102
 
94
103
  context 'when type is a symbol of an existing class constant' do
@@ -96,7 +105,10 @@ describe Virtus::Attribute, '.build' do
96
105
 
97
106
  it_behaves_like 'a valid attribute instance'
98
107
 
99
- its(:type) { should be(Axiom::Types::String) }
108
+ describe '#type' do
109
+ subject { super().type }
110
+ it { is_expected.to be(Axiom::Types::String) }
111
+ end
100
112
  end
101
113
 
102
114
  context 'when type is an axiom type' do
@@ -104,7 +116,10 @@ describe Virtus::Attribute, '.build' do
104
116
 
105
117
  it_behaves_like 'a valid attribute instance'
106
118
 
107
- its(:type) { should be(type) }
119
+ describe '#type' do
120
+ subject { super().type }
121
+ it { is_expected.to be(type) }
122
+ end
108
123
  end
109
124
 
110
125
  context 'when custom attribute class exists for a given primitive' do
@@ -115,9 +130,12 @@ describe Virtus::Attribute, '.build' do
115
130
  attribute.primitive(type)
116
131
  end
117
132
 
118
- it { should be_instance_of(attribute) }
133
+ it { is_expected.to be_instance_of(attribute) }
119
134
 
120
- its(:type) { should be(Axiom::Types::Object) }
135
+ describe '#type' do
136
+ subject { super().type }
137
+ it { is_expected.to be(Axiom::Types::Object) }
138
+ end
121
139
  end
122
140
 
123
141
  context 'when custom attribute class exists for a given array with member coercion defined' do
@@ -128,9 +146,12 @@ describe Virtus::Attribute, '.build' do
128
146
  attribute.primitive(type.class)
129
147
  end
130
148
 
131
- it { should be_instance_of(attribute) }
149
+ it { is_expected.to be_instance_of(attribute) }
132
150
 
133
- its(:type) { should be < Axiom::Types::Collection }
151
+ describe '#type' do
152
+ subject { super().type }
153
+ it { is_expected.to be < Axiom::Types::Collection }
154
+ end
134
155
  end
135
156
 
136
157
  context 'when custom collection-like attribute class exists for a given enumerable primitive' do
@@ -141,8 +162,11 @@ describe Virtus::Attribute, '.build' do
141
162
  attribute.primitive(type)
142
163
  end
143
164
 
144
- it { should be_instance_of(attribute) }
165
+ it { is_expected.to be_instance_of(attribute) }
145
166
 
146
- its(:type) { should be < Axiom::Types::Collection }
167
+ describe '#type' do
168
+ subject { super().type }
169
+ it { is_expected.to be < Axiom::Types::Collection }
170
+ end
147
171
  end
148
172
  end
@@ -19,7 +19,7 @@ describe Virtus::Attribute, '.coerce' do
19
19
  described_class.coerce(true)
20
20
  end
21
21
 
22
- it { should be(true) }
22
+ it { is_expected.to be(true) }
23
23
  end
24
24
 
25
25
  context 'when it is set to false' do
@@ -27,6 +27,6 @@ describe Virtus::Attribute, '.coerce' do
27
27
  described_class.coerce(false)
28
28
  end
29
29
 
30
- it { should be(false) }
30
+ it { is_expected.to be(false) }
31
31
  end
32
32
  end
@@ -18,7 +18,7 @@ describe Virtus::Attribute, '#coerce' do
18
18
  let(:strict) { false }
19
19
 
20
20
  it 'uses coercer to coerce the input value' do
21
- stub(coercer).call(input) { output }
21
+ mock(coercer).call(input) { output }
22
22
 
23
23
  expect(subject).to be(output)
24
24
 
@@ -30,8 +30,8 @@ describe Virtus::Attribute, '#coerce' do
30
30
  let(:strict) { true }
31
31
 
32
32
  it 'uses coercer to coerce the input value' do
33
- stub(coercer).call(input) { output }
34
- stub(coercer).success?(String, output) { true }
33
+ mock(coercer).call(input) { output }
34
+ mock(coercer).success?(String, output) { true }
35
35
 
36
36
  expect(subject).to be(output)
37
37
 
@@ -44,8 +44,8 @@ describe Virtus::Attribute, '#coerce' do
44
44
  let(:input) { nil }
45
45
 
46
46
  it 'returns nil' do
47
- stub(coercer).call(input) { input }
48
- stub(coercer).success?(String, input) { false }
47
+ mock(coercer).call(input) { input }
48
+ mock(coercer).success?(String, input) { false }
49
49
 
50
50
  expect(subject).to be(nil)
51
51
 
@@ -58,8 +58,8 @@ describe Virtus::Attribute, '#coerce' do
58
58
  let(:input) { nil }
59
59
 
60
60
  it 'returns raises error' do
61
- stub(coercer).call(input) { input }
62
- stub(coercer).success?(String, input) { false }
61
+ mock(coercer).call(input) { input }
62
+ mock(coercer).success?(String, input) { false }
63
63
 
64
64
  expect { subject }.to raise_error(Virtus::CoercionError)
65
65
 
@@ -69,8 +69,8 @@ describe Virtus::Attribute, '#coerce' do
69
69
  end
70
70
 
71
71
  it 'raises error when input was not coerced' do
72
- stub(coercer).call(input) { input }
73
- stub(coercer).success?(String, input) { false }
72
+ mock(coercer).call(input) { input }
73
+ mock(coercer).success?(String, input) { false }
74
74
 
75
75
  expect { subject }.to raise_error(Virtus::CoercionError)
76
76
 
@@ -9,12 +9,12 @@ describe Virtus::Attribute, '#coercible?' do
9
9
  context 'when :coerce is set to true' do
10
10
  let(:coerce) { true }
11
11
 
12
- it { should be(true) }
12
+ it { is_expected.to be(true) }
13
13
  end
14
14
 
15
15
  context 'when :coerce is set to false' do
16
16
  let(:coerce) { false }
17
17
 
18
- it { should be(false) }
18
+ it { is_expected.to be(false) }
19
19
  end
20
20
  end
@@ -6,9 +6,9 @@ describe Virtus::Attribute, '.build' do
6
6
  let(:options) { {} }
7
7
 
8
8
  shared_examples_for 'a valid collection attribute instance' do
9
- it { should be_instance_of(Virtus::Attribute::Collection) }
9
+ it { is_expected.to be_instance_of(Virtus::Attribute::Collection) }
10
10
 
11
- it { should be_frozen }
11
+ it { is_expected.to be_frozen }
12
12
  end
13
13
 
14
14
  context 'when type is Array' do
@@ -16,10 +16,10 @@ describe Virtus::Attribute::Collection, '#coerce' do
16
16
  }
17
17
 
18
18
  it 'uses coercer to coerce members' do
19
- stub(coercer).call(input) { input }
20
- stub(member_type).finalize { member_type }
21
- stub(member_type).coerce('1') { 1 }
22
- stub(member_type).coerce('2') { 2 }
19
+ mock(coercer).call(input) { input }
20
+ mock(member_type).finalize { member_type }
21
+ mock(member_type).coerce('1') { 1 }
22
+ mock(member_type).coerce('2') { 2 }
23
23
 
24
24
  expect(subject).to eq([1, 2])
25
25
 
@@ -66,7 +66,7 @@ describe Virtus::Attribute::Collection, '#coerce' do
66
66
  }
67
67
 
68
68
  it 'returns nil' do
69
- stub(coercer).call(input) { input }
69
+ mock(coercer).call(input) { input }
70
70
 
71
71
  expect(subject).to be(input)
72
72
  end
@@ -12,12 +12,18 @@ describe Virtus::Attribute::Collection, 'custom subclass' do
12
12
  context 'when primitive is set on the attribute subclass' do
13
13
  let(:attribute_class) { Class.new(described_class).primitive(primitive) }
14
14
 
15
- its(:primitive) { should be(primitive) }
15
+ describe '#primitive' do
16
+ subject { super().primitive }
17
+ it { is_expected.to be(primitive) }
18
+ end
16
19
  end
17
20
 
18
21
  context 'when primitive is not set on the attribute subclass' do
19
22
  let(:attribute_class) { Class.new(described_class) }
20
23
 
21
- its(:primitive) { should be(primitive) }
24
+ describe '#primitive' do
25
+ subject { super().primitive }
26
+ it { is_expected.to be(primitive) }
27
+ end
22
28
  end
23
29
  end
@@ -10,11 +10,11 @@ describe Virtus::Attribute, '#defined?' do
10
10
  let(:instance) { model.new }
11
11
 
12
12
  context 'when the attribute value has not been defined' do
13
- it { should be(false) }
13
+ it { is_expected.to be(false) }
14
14
  end
15
15
 
16
16
  context 'when the attribute value has been defined' do
17
17
  before { instance.test = nil }
18
- it { should be(true) }
18
+ it { is_expected.to be(true) }
19
19
  end
20
20
  end
@@ -6,50 +6,65 @@ describe Virtus::Attribute::EmbeddedValue, '.build' do
6
6
  context 'when type is a Virtus.model' do
7
7
  let(:type) { Class.new { include Virtus.model } }
8
8
 
9
- it { should be_frozen }
9
+ it { is_expected.to be_frozen }
10
10
 
11
- it { should be_instance_of(Virtus::Attribute::EmbeddedValue) }
11
+ it { is_expected.to be_instance_of(Virtus::Attribute::EmbeddedValue) }
12
12
 
13
- its(:coercer) { should be_instance_of(described_class::FromOpenStruct) }
13
+ describe '#coercer' do
14
+ subject { super().coercer }
15
+ it { is_expected.to be_instance_of(described_class::FromOpenStruct) }
16
+ end
14
17
  end
15
18
 
16
19
  context 'when type includes Virtus' do
17
20
  let(:type) { Class.new { include Virtus } }
18
21
 
19
- it { should be_frozen }
22
+ it { is_expected.to be_frozen }
20
23
 
21
- it { should be_instance_of(Virtus::Attribute::EmbeddedValue) }
24
+ it { is_expected.to be_instance_of(Virtus::Attribute::EmbeddedValue) }
22
25
 
23
- its(:coercer) { should be_instance_of(described_class::FromOpenStruct) }
26
+ describe '#coercer' do
27
+ subject { super().coercer }
28
+ it { is_expected.to be_instance_of(described_class::FromOpenStruct) }
29
+ end
24
30
  end
25
31
 
26
32
  context 'when type is an OpenStruct subclass' do
27
33
  let(:type) { Class.new(OpenStruct) }
28
34
 
29
- it { should be_frozen }
35
+ it { is_expected.to be_frozen }
30
36
 
31
- it { should be_instance_of(Virtus::Attribute::EmbeddedValue) }
37
+ it { is_expected.to be_instance_of(Virtus::Attribute::EmbeddedValue) }
32
38
 
33
- its(:coercer) { should be_instance_of(described_class::FromOpenStruct) }
39
+ describe '#coercer' do
40
+ subject { super().coercer }
41
+ it { is_expected.to be_instance_of(described_class::FromOpenStruct) }
42
+ end
34
43
  end
35
44
 
36
45
  context 'when type is OpenStruct' do
37
46
  let(:type) { OpenStruct }
38
47
 
39
- it { should be_frozen }
48
+ it { is_expected.to be_frozen }
40
49
 
41
- it { should be_instance_of(Virtus::Attribute::EmbeddedValue) }
50
+ it { is_expected.to be_instance_of(Virtus::Attribute::EmbeddedValue) }
42
51
 
43
- its(:coercer) { should be_instance_of(described_class::FromOpenStruct) }
52
+ describe '#coercer' do
53
+ subject { super().coercer }
54
+ it { is_expected.to be_instance_of(described_class::FromOpenStruct) }
55
+ end
44
56
  end
45
57
 
46
58
  context 'when type is Struct' do
47
59
  let(:type) { Struct.new(:test) }
48
60
 
49
- it { should be_frozen }
61
+ it { is_expected.to be_frozen }
50
62
 
51
- it { should be_instance_of(Virtus::Attribute::EmbeddedValue) }
63
+ it { is_expected.to be_instance_of(Virtus::Attribute::EmbeddedValue) }
52
64
 
53
- its(:coercer) { should be_instance_of(described_class::FromStruct) }
65
+ describe '#coercer' do
66
+ subject { super().coercer }
67
+ it { is_expected.to be_instance_of(described_class::FromStruct) }
68
+ end
54
69
  end
55
70
  end
@@ -12,22 +12,29 @@ describe Virtus::Attribute::EmbeddedValue, '#coerce' do
12
12
  context 'when input is an attribute hash' do
13
13
  let(:input) { Hash[name: 'Piotr', age: 30] }
14
14
 
15
- it { should be_instance_of(model) }
15
+ it { is_expected.to be_instance_of(model) }
16
16
 
17
- its(:name) { should eql('Piotr') }
18
- its(:age) { should eql(30) }
17
+ describe '#name' do
18
+ subject { super().name }
19
+ it { is_expected.to eql('Piotr') }
20
+ end
21
+
22
+ describe '#age' do
23
+ subject { super().age }
24
+ it { is_expected.to eql(30) }
25
+ end
19
26
  end
20
27
 
21
28
  context 'when input is nil' do
22
29
  let(:input) { nil }
23
30
 
24
- it { should be(nil) }
31
+ it { is_expected.to be(nil) }
25
32
  end
26
33
 
27
34
  context 'when input is a model instance' do
28
35
  let(:input) { OpenStruct.new }
29
36
 
30
- it { should be(input) }
37
+ it { is_expected.to be(input) }
31
38
  end
32
39
  end
33
40
 
@@ -37,22 +44,29 @@ describe Virtus::Attribute::EmbeddedValue, '#coerce' do
37
44
  context 'when input is an attribute hash' do
38
45
  let(:input) { ['Piotr', 30] }
39
46
 
40
- it { should be_instance_of(model) }
47
+ it { is_expected.to be_instance_of(model) }
41
48
 
42
- its(:name) { should eql('Piotr') }
43
- its(:age) { should eql(30) }
49
+ describe '#name' do
50
+ subject { super().name }
51
+ it { is_expected.to eql('Piotr') }
52
+ end
53
+
54
+ describe '#age' do
55
+ subject { super().age }
56
+ it { is_expected.to eql(30) }
57
+ end
44
58
  end
45
59
 
46
60
  context 'when input is nil' do
47
61
  let(:input) { nil }
48
62
 
49
- it { should be(nil) }
63
+ it { is_expected.to be(nil) }
50
64
  end
51
65
 
52
66
  context 'when input is a model instance' do
53
67
  let(:input) { model.new('Piotr', 30) }
54
68
 
55
- it { should be(input) }
69
+ it { is_expected.to be(input) }
56
70
  end
57
71
  end
58
72
 
@@ -63,7 +77,7 @@ describe Virtus::Attribute::EmbeddedValue, '#coerce' do
63
77
  context 'when input is coercible' do
64
78
  let(:input) { ['Piotr'] }
65
79
 
66
- it { should eql(model.new('Piotr')) }
80
+ it { is_expected.to eql(model.new('Piotr')) }
67
81
  end
68
82
 
69
83
  context 'when input is not coercible' do