virtus 1.0.1 → 2.0.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 (99) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +19 -15
  3. data/Changelog.md +43 -2
  4. data/Gemfile +5 -5
  5. data/README.md +113 -78
  6. data/Rakefile +13 -3
  7. data/lib/virtus.rb +46 -6
  8. data/lib/virtus/attribute.rb +21 -3
  9. data/lib/virtus/attribute/accessor.rb +11 -0
  10. data/lib/virtus/attribute/builder.rb +8 -13
  11. data/lib/virtus/attribute/collection.rb +12 -3
  12. data/lib/virtus/attribute/default_value.rb +2 -0
  13. data/lib/virtus/attribute/hash.rb +3 -3
  14. data/lib/virtus/attribute/nullify_blank.rb +24 -0
  15. data/lib/virtus/attribute/strict.rb +1 -1
  16. data/lib/virtus/attribute_set.rb +2 -2
  17. data/lib/virtus/builder.rb +2 -6
  18. data/lib/virtus/class_inclusions.rb +0 -1
  19. data/lib/virtus/coercer.rb +1 -0
  20. data/lib/virtus/configuration.rb +17 -36
  21. data/lib/virtus/extensions.rb +13 -21
  22. data/lib/virtus/instance_methods.rb +3 -2
  23. data/lib/virtus/model.rb +1 -3
  24. data/lib/virtus/module_extensions.rb +8 -2
  25. data/lib/virtus/support/equalizer.rb +1 -1
  26. data/lib/virtus/support/options.rb +2 -1
  27. data/lib/virtus/support/type_lookup.rb +1 -1
  28. data/lib/virtus/version.rb +1 -1
  29. data/spec/integration/attributes_attribute_spec.rb +28 -0
  30. data/spec/integration/building_module_spec.rb +22 -0
  31. data/spec/integration/collection_member_coercion_spec.rb +34 -13
  32. data/spec/integration/custom_attributes_spec.rb +2 -2
  33. data/spec/integration/custom_collection_attributes_spec.rb +6 -6
  34. data/spec/integration/default_values_spec.rb +8 -8
  35. data/spec/integration/defining_attributes_spec.rb +25 -18
  36. data/spec/integration/embedded_value_spec.rb +5 -5
  37. data/spec/integration/extending_objects_spec.rb +5 -5
  38. data/spec/integration/hash_attributes_coercion_spec.rb +16 -12
  39. data/spec/integration/mass_assignment_with_accessors_spec.rb +5 -5
  40. data/spec/integration/overriding_virtus_spec.rb +4 -4
  41. data/spec/integration/required_attributes_spec.rb +1 -1
  42. data/spec/integration/struct_as_embedded_value_spec.rb +4 -4
  43. data/spec/integration/using_modules_spec.rb +8 -8
  44. data/spec/integration/value_object_with_custom_constructor_spec.rb +4 -4
  45. data/spec/integration/virtus/instance_level_attributes_spec.rb +1 -1
  46. data/spec/integration/virtus/value_object_spec.rb +14 -14
  47. data/spec/shared/freeze_method_behavior.rb +6 -3
  48. data/spec/shared/idempotent_method_behaviour.rb +1 -1
  49. data/spec/shared/options_class_method.rb +3 -3
  50. data/spec/spec_helper.rb +2 -18
  51. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +3 -3
  52. data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +3 -3
  53. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +64 -24
  54. data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +2 -2
  55. data/spec/unit/virtus/attribute/coerce_spec.rb +58 -10
  56. data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +2 -2
  57. data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +15 -4
  58. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +25 -4
  59. data/spec/unit/virtus/attribute/collection/value_coerced_predicate_spec.rb +31 -0
  60. data/spec/unit/virtus/attribute/comparison_spec.rb +20 -0
  61. data/spec/unit/virtus/attribute/custom_collection_spec.rb +8 -2
  62. data/spec/unit/virtus/attribute/defined_spec.rb +20 -0
  63. data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +30 -15
  64. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +25 -11
  65. data/spec/unit/virtus/attribute/get_spec.rb +2 -2
  66. data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +21 -9
  67. data/spec/unit/virtus/attribute/hash/coerce_spec.rb +9 -9
  68. data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +2 -2
  69. data/spec/unit/virtus/attribute/rename_spec.rb +6 -3
  70. data/spec/unit/virtus/attribute/required_predicate_spec.rb +2 -2
  71. data/spec/unit/virtus/attribute/set_default_value_spec.rb +43 -10
  72. data/spec/unit/virtus/attribute/set_spec.rb +1 -1
  73. data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +2 -2
  74. data/spec/unit/virtus/attribute_set/append_spec.rb +6 -6
  75. data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +12 -11
  76. data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +13 -12
  77. data/spec/unit/virtus/attribute_set/each_spec.rb +21 -16
  78. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +2 -2
  79. data/spec/unit/virtus/attribute_set/element_set_spec.rb +17 -9
  80. data/spec/unit/virtus/attribute_set/merge_spec.rb +7 -5
  81. data/spec/unit/virtus/attribute_set/reset_spec.rb +22 -11
  82. data/spec/unit/virtus/attribute_spec.rb +8 -7
  83. data/spec/unit/virtus/attributes_reader_spec.rb +1 -1
  84. data/spec/unit/virtus/attributes_writer_spec.rb +1 -1
  85. data/spec/unit/virtus/element_reader_spec.rb +1 -1
  86. data/spec/unit/virtus/freeze_spec.rb +23 -3
  87. data/spec/unit/virtus/model_spec.rb +38 -7
  88. data/spec/unit/virtus/module_spec.rb +59 -2
  89. data/spec/unit/virtus/set_default_attributes_spec.rb +10 -3
  90. data/spec/unit/virtus/value_object_spec.rb +15 -5
  91. data/virtus.gemspec +7 -5
  92. metadata +46 -44
  93. data/.ruby-version +0 -1
  94. data/Gemfile.devtools +0 -54
  95. data/config/flay.yml +0 -3
  96. data/config/flog.yml +0 -2
  97. data/config/mutant.yml +0 -15
  98. data/config/reek.yml +0 -146
  99. data/config/yardstick.yml +0 -2
@@ -16,13 +16,13 @@ describe Virtus::Attribute, '#get' do
16
16
  instance.test = value
17
17
  end
18
18
 
19
- it { should be(value) }
19
+ it { is_expected.to be(value) }
20
20
  end
21
21
 
22
22
  context 'with :lazy is set to true' do
23
23
  let(:options) { { :lazy => true, :default => value } }
24
24
 
25
- it { should eql(value) }
25
+ it { is_expected.to eql(value) }
26
26
 
27
27
  it 'sets default only on first access' do
28
28
  expect(object.get(instance)).to eql(value)
@@ -1,18 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Virtus::Attribute::Hash, '.build' do
4
- subject { described_class.build(type) }
4
+ subject { described_class.build(type, options) }
5
5
 
6
- share_examples_for 'a valid hash attribute instance' do
7
- it { should be_instance_of(Virtus::Attribute::Hash) }
6
+ let(:options) { {} }
8
7
 
9
- it { should be_frozen }
8
+ shared_examples_for 'a valid hash attribute instance' do
9
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
10
+
11
+ it { is_expected.to be_frozen }
10
12
  end
11
13
 
12
14
  context 'when type is Hash' do
13
15
  let(:type) { Hash }
14
16
 
15
- it { should be_instance_of(Virtus::Attribute::Hash) }
17
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
16
18
 
17
19
  it 'sets default key type' do
18
20
  expect(subject.type.key_type).to be(Axiom::Types::Object)
@@ -26,7 +28,7 @@ describe Virtus::Attribute::Hash, '.build' do
26
28
  context 'when type is Hash[String => Integer]' do
27
29
  let(:type) { Hash[String => Integer] }
28
30
 
29
- it { should be_instance_of(Virtus::Attribute::Hash) }
31
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
30
32
 
31
33
  it 'sets key type' do
32
34
  expect(subject.type.key_type).to be(Axiom::Types::String)
@@ -40,7 +42,7 @@ describe Virtus::Attribute::Hash, '.build' do
40
42
  context 'when type is Hash[Virtus::Attribute::Hash => Virtus::Attribute::Boolean]' do
41
43
  let(:type) { Hash[Virtus::Attribute::Hash => Virtus::Attribute::Boolean] }
42
44
 
43
- it { should be_instance_of(Virtus::Attribute::Hash) }
45
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
44
46
 
45
47
  it 'sets key type' do
46
48
  expect(subject.type.key_type).to be(Axiom::Types::Hash)
@@ -55,7 +57,7 @@ describe Virtus::Attribute::Hash, '.build' do
55
57
  let(:type) { Hash[key_type => Integer] }
56
58
  let(:key_type) { Struct.new(:id) }
57
59
 
58
- it { should be_instance_of(Virtus::Attribute::Hash) }
60
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
59
61
 
60
62
  it 'sets key type' do
61
63
  expect(subject.type.key_type).to be(key_type)
@@ -70,7 +72,7 @@ describe Virtus::Attribute::Hash, '.build' do
70
72
  let(:type) { Hash[String => value_type] }
71
73
  let(:value_type) { Struct.new(:id) }
72
74
 
73
- it { should be_instance_of(Virtus::Attribute::Hash) }
75
+ it { is_expected.to be_instance_of(Virtus::Attribute::Hash) }
74
76
 
75
77
  it 'sets key type' do
76
78
  expect(subject.type.key_type).to be(Axiom::Types::String)
@@ -91,4 +93,14 @@ describe Virtus::Attribute::Hash, '.build' do
91
93
  )
92
94
  end
93
95
  end
96
+
97
+ context 'when strict mode is used' do
98
+ let(:type) { Hash[String => Integer] }
99
+ let(:options) { { :strict => true } }
100
+
101
+ it 'sets the strict mode for key/value types' do
102
+ expect(subject.key_type).to be_strict
103
+ expect(subject.value_type).to be_strict
104
+ end
105
+ end
94
106
  end
@@ -17,14 +17,14 @@ describe Virtus::Attribute::Hash, '#coerce' do
17
17
  let(:input) { Class.new { def to_hash; { :hello => 'World' }; end }.new }
18
18
  let(:object) { described_class.build(Hash) }
19
19
 
20
- it { should eq(:hello => 'World') }
20
+ it { is_expected.to eq(:hello => 'World') }
21
21
  end
22
22
 
23
23
  context 'when input is not coercible to hash' do
24
24
  let(:input) { 'not really a hash' }
25
25
  let(:object) { described_class.build(Hash) }
26
26
 
27
- it { should be(input) }
27
+ it { is_expected.to be(input) }
28
28
  end
29
29
 
30
30
  context 'when input is a hash' do
@@ -39,15 +39,15 @@ describe Virtus::Attribute::Hash, '#coerce' do
39
39
  let(:input) { Hash[1 => '1', 2 => '2'] }
40
40
 
41
41
  it 'uses coercer to coerce key and value' do
42
- stub(coercer).call(input) { input }
42
+ mock(coercer).call(input) { input }
43
43
 
44
- stub(key_type).finalize { key_type }
45
- stub(key_type).coerce(1) { '1' }
46
- stub(key_type).coerce(2) { '2' }
44
+ mock(key_type).finalize { key_type }
45
+ mock(key_type).coerce(1) { '1' }
46
+ mock(key_type).coerce(2) { '2' }
47
47
 
48
- stub(value_type).finalize { value_type }
49
- stub(value_type).coerce('1') { 1 }
50
- stub(value_type).coerce('2') { 2 }
48
+ mock(value_type).finalize { value_type }
49
+ mock(value_type).coerce('1') { 1 }
50
+ mock(value_type).coerce('2') { 2 }
51
51
 
52
52
  expect(subject).to eq(Hash['1' => 1, '2' => 2])
53
53
 
@@ -9,12 +9,12 @@ describe Virtus::Attribute, '#lazy?' do
9
9
  context 'when :lazy is set to true' do
10
10
  let(:lazy) { true }
11
11
 
12
- it { should be(true) }
12
+ it { is_expected.to be(true) }
13
13
  end
14
14
 
15
15
  context 'when :lazy is set to false' do
16
16
  let(:lazy) { false }
17
17
 
18
- it { should be(false) }
18
+ it { is_expected.to be(false) }
19
19
  end
20
20
  end
@@ -6,8 +6,11 @@ describe Virtus::Attribute, '#rename' do
6
6
  let(:object) { described_class.build(String, :name => :foo, :strict => true) }
7
7
  let(:other) { described_class.build(String, :name => :bar, :strict => true) }
8
8
 
9
- its(:name) { should be(:bar) }
9
+ describe '#name' do
10
+ subject { super().name }
11
+ it { is_expected.to be(:bar) }
12
+ end
10
13
 
11
- it { should_not be(object) }
12
- it { should be_strict }
14
+ it { is_expected.not_to be(object) }
15
+ it { is_expected.to be_strict }
13
16
  end
@@ -8,12 +8,12 @@ describe Virtus::Attribute, '#required?' do
8
8
  context 'when required option is true' do
9
9
  let(:required) { true }
10
10
 
11
- it { should be(true) }
11
+ it { is_expected.to be(true) }
12
12
  end
13
13
 
14
14
  context 'when required option is false' do
15
15
  let(:required) { false }
16
16
 
17
- it { should be(false) }
17
+ it { is_expected.to be(false) }
18
18
  end
19
19
  end
@@ -15,8 +15,15 @@ describe Virtus::Attribute, '#set_default_value' do
15
15
 
16
16
  let(:default) { nil }
17
17
 
18
- its(:test) { should be(nil) }
19
- its(:instance_variables) { should include(:'@test') }
18
+ describe '#test' do
19
+ subject { super().test }
20
+ it { is_expected.to be(nil) }
21
+ end
22
+
23
+ describe '#instance_variables' do
24
+ subject { super().instance_variables }
25
+ it { is_expected.to include(:'@test') }
26
+ end
20
27
  end
21
28
 
22
29
  context 'with a non-clonable object' do
@@ -25,8 +32,15 @@ describe Virtus::Attribute, '#set_default_value' do
25
32
  let(:object) { described_class.build('Boolean', options.merge(:name => name, :default => default)) }
26
33
  let(:default) { true }
27
34
 
28
- its(:test) { should be(true) }
29
- its(:instance_variables) { should include(:'@test') }
35
+ describe '#test' do
36
+ subject { super().test }
37
+ it { is_expected.to be(true) }
38
+ end
39
+
40
+ describe '#instance_variables' do
41
+ subject { super().instance_variables }
42
+ it { is_expected.to include(:'@test') }
43
+ end
30
44
  end
31
45
 
32
46
  context 'with a clonable' do
@@ -34,8 +48,15 @@ describe Virtus::Attribute, '#set_default_value' do
34
48
 
35
49
  let(:default) { [] }
36
50
 
37
- its(:test) { should eq(default) }
38
- its(:test) { should_not be(default) }
51
+ describe '#test' do
52
+ subject { super().test }
53
+ it { is_expected.to eq(default) }
54
+ end
55
+
56
+ describe '#test' do
57
+ subject { super().test }
58
+ it { is_expected.not_to be(default) }
59
+ end
39
60
  end
40
61
 
41
62
  context 'with a callable' do
@@ -43,7 +64,10 @@ describe Virtus::Attribute, '#set_default_value' do
43
64
 
44
65
  let(:default) { lambda { |model, attribute| "#{model.name}-#{attribute.name}" } }
45
66
 
46
- its(:test) { should eq('model-test') }
67
+ describe '#test' do
68
+ subject { super().test }
69
+ it { is_expected.to eq('model-test') }
70
+ end
47
71
  end
48
72
 
49
73
  context 'with a symbol' do
@@ -55,20 +79,29 @@ describe Virtus::Attribute, '#set_default_value' do
55
79
  context 'when method is public' do
56
80
  let(:model) { Class.new { attr_reader :test; def set_test; @test = 'hello world'; end } }
57
81
 
58
- its(:test) { should eq('hello world') }
82
+ describe '#test' do
83
+ subject { super().test }
84
+ it { is_expected.to eq('hello world') }
85
+ end
59
86
  end
60
87
 
61
88
  context 'when method is private' do
62
89
  let(:model) { Class.new { attr_reader :test; private; def set_test; @test = 'hello world'; end } }
63
90
 
64
- its(:test) { should eq('hello world') }
91
+ describe '#test' do
92
+ subject { super().test }
93
+ it { is_expected.to eq('hello world') }
94
+ end
65
95
  end
66
96
  end
67
97
 
68
98
  context 'when it is not a method name' do
69
99
  let(:default) { :hello_world }
70
100
 
71
- its(:test) { should eq('hello_world') }
101
+ describe '#test' do
102
+ subject { super().test }
103
+ it { is_expected.to eq('hello_world') }
104
+ end
72
105
  end
73
106
  end
74
107
  end
@@ -11,7 +11,7 @@ describe Virtus::Attribute, '#set' do
11
11
  let(:value) { 'Jane Doe' }
12
12
  let(:options) { {} }
13
13
 
14
- it { should be(value) }
14
+ it { is_expected.to be(value) }
15
15
 
16
16
  context 'without coercion' do
17
17
  specify do
@@ -8,12 +8,12 @@ describe Virtus::Attribute, '#value_coerced?' do
8
8
  context 'when input is coerced' do
9
9
  let(:input) { '1' }
10
10
 
11
- it { should be(true) }
11
+ it { is_expected.to be(true) }
12
12
  end
13
13
 
14
14
  context 'when input is not coerced' do
15
15
  let(:input) { 1 }
16
16
 
17
- it { should be(false) }
17
+ it { is_expected.to be(false) }
18
18
  end
19
19
  end
@@ -11,7 +11,7 @@ describe Virtus::AttributeSet, '#<<' do
11
11
  context 'with a new attribute' do
12
12
  let(:attribute) { Virtus::Attribute.build(String, :name => name) }
13
13
 
14
- it { should equal(object) }
14
+ it { is_expected.to equal(object) }
15
15
 
16
16
  it 'adds an attribute' do
17
17
  expect { subject }.to change { object.to_a }.
@@ -36,12 +36,12 @@ describe Virtus::AttributeSet, '#<<' do
36
36
  let(:attributes) { [Virtus::Attribute.build(String, :name => name)] }
37
37
  let(:attribute) { Virtus::Attribute.build(String, :name => name) }
38
38
 
39
- it { should equal(object) }
39
+ it { is_expected.to equal(object) }
40
40
 
41
- it 'replaces the original attribute' do
42
- expect { subject }.to change { object.to_a }.
43
- from(attributes).
44
- to([ attribute ])
41
+ it "replaces the original attribute object" do
42
+ expect { subject }.to change { object.to_a.map(&:__id__) }.
43
+ from(attributes.map(&:__id__)).
44
+ to([attribute.__id__])
45
45
  end
46
46
  end
47
47
  end
@@ -1,35 +1,36 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Virtus::AttributeSet, '#define_reader_method' do
4
- subject { described_class.new }
4
+ subject(:attribute_set) { described_class.new }
5
5
 
6
6
  let(:attribute) { Virtus::Attribute.build(String, :name => method_name) }
7
-
8
- if RUBY_VERSION < '1.9'
9
- let(:method_name) { 'foo_bar' }
10
- else
11
- let(:method_name) { :foo_bar }
12
- end
7
+ let(:method_name) { :foo_bar }
13
8
 
14
9
  before do
15
- subject.define_reader_method(attribute, method_name, visibility)
10
+ attribute_set.define_reader_method(attribute, method_name, visibility)
16
11
  end
17
12
 
18
13
  context "with public visibility" do
19
14
  let(:visibility) { :public }
20
15
 
21
- its(:public_instance_methods) { should include(method_name) }
16
+ it "defines public writer" do
17
+ expect(attribute_set.public_instance_methods).to include(method_name)
18
+ end
22
19
  end
23
20
 
24
21
  context "with private visibility" do
25
22
  let(:visibility) { :private }
26
23
 
27
- its(:private_instance_methods) { should include(method_name) }
24
+ it "defines public writer" do
25
+ expect(attribute_set.private_instance_methods).to include(method_name)
26
+ end
28
27
  end
29
28
 
30
29
  context "with protected visibility" do
31
30
  let(:visibility) { :protected }
32
31
 
33
- its(:protected_instance_methods) { should include(method_name) }
32
+ it "defines protected writer" do
33
+ expect(attribute_set.protected_instance_methods).to include(method_name)
34
+ end
34
35
  end
35
36
  end
@@ -1,35 +1,36 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Virtus::AttributeSet, '#define_writer_method' do
4
- subject { described_class.new }
4
+ subject(:attribute_set) { described_class.new }
5
5
 
6
- let(:attribute) { Virtus::Attribute.build(String, :name => :foo_bar) }
7
-
8
- if RUBY_VERSION < '1.9'
9
- let(:method_name) { 'foo_bar=' }
10
- else
11
- let(:method_name) { :foo_bar= }
12
- end
6
+ let(:attribute) { Virtus::Attribute.build(String, :name => method_name) }
7
+ let(:method_name) { :foo_bar }
13
8
 
14
9
  before do
15
- subject.define_reader_method(attribute, method_name, visibility)
10
+ attribute_set.define_writer_method(attribute, method_name, visibility)
16
11
  end
17
12
 
18
13
  context "with public visibility" do
19
14
  let(:visibility) { :public }
20
15
 
21
- its(:public_instance_methods) { should include(method_name) }
16
+ it "defines public writer" do
17
+ expect(attribute_set.public_instance_methods).to include(method_name)
18
+ end
22
19
  end
23
20
 
24
21
  context "with private visibility" do
25
22
  let(:visibility) { :private }
26
23
 
27
- its(:private_instance_methods) { should include(method_name) }
24
+ it "defines private writer" do
25
+ expect(attribute_set.private_instance_methods).to include(method_name)
26
+ end
28
27
  end
29
28
 
30
29
  context "with protected visibility" do
31
30
  let(:visibility) { :protected }
32
31
 
33
- its(:protected_instance_methods) { should include(method_name) }
32
+ it "defines protected writer" do
33
+ expect(attribute_set.protected_instance_methods).to include(method_name)
34
+ end
34
35
  end
35
36
  end
@@ -1,28 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Virtus::AttributeSet, '#each' do
4
- let(:name) { :name }
4
+ subject(:attribute_set) { described_class.new(parent, attributes) }
5
+
6
+ let(:name) { :name }
5
7
  let(:attribute) { Virtus::Attribute.build(String, :name => :name) }
6
- let(:attributes) { [ attribute ] }
7
- let(:parent) { described_class.new }
8
- let(:object) { described_class.new(parent, attributes) }
9
- let(:yields) { Set[] }
8
+ let(:attributes) { [ attribute ] }
9
+ let(:parent) { described_class.new }
10
+ let(:yields) { Set[] }
10
11
 
11
12
  context 'with no block' do
12
- subject { object.each }
13
-
14
- it { should be_instance_of(to_enum.class) }
13
+ it 'returns an enumerator when block is not provided' do
14
+ expect(attribute_set.each).to be_kind_of(Enumerator)
15
+ end
15
16
 
16
17
  it 'yields the expected attributes' do
17
- subject.to_a.should eql(object.to_a)
18
+ result = []
19
+ attribute_set.each { |attribute| result << attribute }
20
+ expect(result).to eql(attributes)
18
21
  end
19
22
  end
20
23
 
21
24
  context 'with a block' do
22
- subject { object.each { |attribute| yields << attribute } }
25
+ subject { attribute_set.each { |attribute| yields << attribute } }
23
26
 
24
27
  context 'when the parent has no attributes' do
25
- it { should equal(object) }
28
+ it { is_expected.to equal(attribute_set) }
26
29
 
27
30
  it 'yields the expected attributes' do
28
31
  expect { subject }.to change { yields.dup }.
@@ -35,12 +38,14 @@ describe Virtus::AttributeSet, '#each' do
35
38
  let(:parent_attribute) { Virtus::Attribute.build(String, :name => :parent_name) }
36
39
  let(:parent) { described_class.new([ parent_attribute ]) }
37
40
 
38
- it { should equal(object) }
41
+ it { is_expected.to equal(attribute_set) }
39
42
 
40
43
  it 'yields the expected attributes' do
41
- expect { subject }.to change { yields.dup }.
42
- from(Set[]).
43
- to(Set[ attribute, parent_attribute ])
44
+ result = []
45
+
46
+ attribute_set.each { |attribute| result << attribute }
47
+
48
+ expect(result).to eql([parent_attribute, attribute])
44
49
  end
45
50
  end
46
51
 
@@ -48,7 +53,7 @@ describe Virtus::AttributeSet, '#each' do
48
53
  let(:parent_attribute) { Virtus::Attribute.build(String, :name => name) }
49
54
  let(:parent) { described_class.new([ parent_attribute ]) }
50
55
 
51
- it { should equal(object) }
56
+ it { is_expected.to equal(attribute_set) }
52
57
 
53
58
  it 'yields the expected attributes' do
54
59
  expect { subject }.to change { yields.dup }.