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,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#name' do
4
+ subject { object.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
@@ -9,7 +9,7 @@ describe Virtus::Attribute::Numeric, '.descendants' do
9
9
  Virtus::Attribute::Decimal ]
10
10
  end
11
11
 
12
- it "should return all known attribute classes" do
12
+ it 'should return all known attribute classes' do
13
13
  subject.should eql(known_descendants)
14
14
  end
15
15
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Numeric, '.max' do
4
+ let(:object) { Class.new(described_class) }
5
+ let(:method) { :max }
6
+ let(:default) { nil }
7
+
8
+ it_should_behave_like 'an options class method'
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Numeric, '.min' do
4
+ let(:object) { Class.new(described_class) }
5
+ let(:method) { :min }
6
+ let(:default) { nil }
7
+
8
+ it_should_behave_like 'an options class method'
9
+ end
@@ -4,15 +4,17 @@ describe Virtus::Attribute::Object, '.descendants' do
4
4
  subject { described_class.descendants }
5
5
 
6
6
  let(:known_descendants) do
7
- [ Virtus::Attribute::Time, Virtus::Attribute::String,
8
- Virtus::Attribute::Integer, Virtus::Attribute::Hash,
9
- Virtus::Attribute::Float, Virtus::Attribute::Decimal,
10
- Virtus::Attribute::Numeric, Virtus::Attribute::DateTime,
11
- Virtus::Attribute::Date, Virtus::Attribute::Boolean,
12
- Virtus::Attribute::Array, Virtus::Attribute::Class ]
7
+ [ Virtus::Attribute::EmbeddedValue,
8
+ Virtus::Attribute::Time, Virtus::Attribute::String,
9
+ Virtus::Attribute::Integer, Virtus::Attribute::Hash,
10
+ Virtus::Attribute::Float, Virtus::Attribute::Decimal,
11
+ Virtus::Attribute::Numeric, Virtus::Attribute::DateTime,
12
+ Virtus::Attribute::Date, Virtus::Attribute::Boolean,
13
+ Virtus::Attribute::Set, Virtus::Attribute::Array,
14
+ Virtus::Attribute::Collection, Virtus::Attribute::Class ]
13
15
  end
14
16
 
15
- it "should return all known attribute classes" do
17
+ it 'should return all known attribute classes' do
16
18
  subject.should eql(known_descendants)
17
19
  end
18
20
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#options' do
4
+ subject { object.options }
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_instance_of(Hash) }
12
+
13
+ it { should eql(options.merge(:accessor => :public)) }
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#public_reader?' do
4
+ subject { object.public_reader? }
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 'when :reader is not not specified' do
12
+ it { should be(true) }
13
+ end
14
+
15
+ { :public => true, :protected => false, :private => false }.each do |value, expected|
16
+ context "when :reader is #{value.inspect}" do
17
+ before do
18
+ options.update(:reader => value)
19
+ end
20
+
21
+ it { should be(expected) }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#public_writer?' do
4
+ subject { object.public_writer? }
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 'when :writer is not not specified' do
12
+ it { should be(true) }
13
+ end
14
+
15
+ { :public => true, :protected => false, :private => false }.each do |value, expected|
16
+ context "when :writer is #{value.inspect}" do
17
+ before do
18
+ options.update(:writer => value)
19
+ end
20
+
21
+ it { should be(expected) }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#reader_visibility' do
4
+ subject { object.reader_visibility }
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 'when not specified' do
12
+ it { should be(:public) }
13
+ end
14
+
15
+ context 'when specified' do
16
+ let(:reader) { stub('reader') }
17
+
18
+ before do
19
+ options.update(:reader => reader)
20
+ end
21
+
22
+ it { should be(reader) }
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Set, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { described_class.new(:colors) }
7
+
8
+ context 'with an Array' do
9
+ let(:value) { [ :foo, 'bar', 'bar', :foo ] }
10
+
11
+ it { should eql(Set[:foo, 'bar']) }
12
+ end
13
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#set' do
4
+ subject { object.set(instance, value) }
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
+ let(:value) { stub('value') }
12
+ let(:coerced) { stub('coerced') }
13
+
14
+ before do
15
+ object.stub(:coerce).with(value).and_return(coerced)
16
+ object.stub(:set!).with(instance, coerced).and_return(object)
17
+ end
18
+
19
+ it { should be(object) }
20
+
21
+ it 'coerces the value' do
22
+ object.should_receive(:coerce).with(value)
23
+ subject
24
+ end
25
+
26
+ it 'sets the instance variable to the coerced value' do
27
+ object.should_receive(:set!).with(instance, coerced)
28
+ subject
29
+ end
30
+ end
31
+
32
+ describe Virtus::Attribute, '#set!' do
33
+ subject { object.set!(instance, value) }
34
+
35
+ let(:object) { described_class.new(:name, options) }
36
+ let(:options) { { :primitive => primitive, :coercion_method => coercion_method } }
37
+ let(:primitive) { stub('primitive') }
38
+ let(:coercion_method) { stub('coercion_method') }
39
+ let(:instance) { Object.new }
40
+ let(:value) { stub('value') }
41
+
42
+ it { should be(object) }
43
+
44
+ it 'sets the instance variable to the value' do
45
+ instance.instance_variable_get(:@name).should be_nil
46
+ subject
47
+ instance.instance_variable_get(:@name).should be(value)
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::String, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { described_class.new(:name) }
7
+ let(:value) { 1 }
8
+ let(:coerce_value) { '1' }
9
+
10
+ it { should eql(coerce_value) }
11
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a correct time' do
4
+ it { should be_kind_of(Time) }
5
+ its(:year) { should eql(year) }
6
+ its(:month) { should eql(month) }
7
+ its(:day) { should eql(day) }
8
+ its(:hour) { should eql(hour) }
9
+ its(:min) { should eql(min) }
10
+ its(:sec) { should eql(sec) }
11
+ end
12
+
13
+ describe Virtus::Attribute::Time, '#coerce' do
14
+ subject { attribute.coerce(value) }
15
+
16
+ let(:attribute) { described_class.new(:bday) }
17
+ let(:year) { 1983 }
18
+ let(:month) { 11 }
19
+ let(:day) { 18 }
20
+ let(:hour) { 8 }
21
+ let(:min) { 16 }
22
+ let(:sec) { 32 }
23
+
24
+ context 'with a date' do
25
+ let(:hour) { 0 }
26
+ let(:min) { 0 }
27
+ let(:sec) { 0 }
28
+ let(:value) { DateTime.new(year, month, day, hour, min, sec) }
29
+
30
+ it_should_behave_like 'a correct time'
31
+ end
32
+
33
+ context 'with a date time' do
34
+ let(:value) { DateTime.new(year, month, day, hour, min, sec) }
35
+
36
+ it_should_behave_like 'a correct time'
37
+ end
38
+
39
+ context 'with a hash' do
40
+ let(:value) { { :year => year, :month => month, :day => day, :hour => hour, :min => min, :sec => sec } }
41
+
42
+ it_should_behave_like 'a correct time'
43
+ end
44
+
45
+ context 'with a string' do
46
+ context 'without hour, min and sec' do
47
+ let(:hour) { 0 }
48
+ let(:min) { 0 }
49
+ let(:sec) { 0 }
50
+ let(:value) { "November #{day}th, #{year}" }
51
+
52
+ it_should_behave_like 'a correct time'
53
+ end
54
+
55
+ context 'with hour, min and sec' do
56
+ let(:value) { "November #{day}th, #{year}, #{hour}:#{min}:#{sec}" }
57
+
58
+ it_should_behave_like 'a correct time'
59
+ end
60
+ end
61
+
62
+ context 'with a non-date value' do
63
+ let(:value) { '2999' }
64
+
65
+ it { should equal(value) }
66
+ end
67
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#value_coerced?' do
4
+ subject { object.value_coerced?(value) }
5
+
6
+ let(:object) { described_class::String.new(:name) }
7
+
8
+ context 'when the value matches the primitive' do
9
+ let(:value) { 'string' }
10
+
11
+ it { should be(true) }
12
+ end
13
+
14
+ context 'when the value does not match the primitive' do
15
+ let(:value) { 1 }
16
+
17
+ it { should be(false) }
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#writer_visibility' do
4
+ subject { object.writer_visibility }
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 'when not specified' do
12
+ it { should be(:public) }
13
+ end
14
+
15
+ context 'when specified' do
16
+ let(:writer) { stub('writer') }
17
+
18
+ before do
19
+ options.update(:writer => writer)
20
+ end
21
+
22
+ it { should be(writer) }
23
+ end
24
+ end
@@ -18,6 +18,18 @@ describe Virtus::AttributeSet, '#<<' do
18
18
  from(attributes).
19
19
  to([ attribute ])
20
20
  end
21
+
22
+ it 'indexes the new attribute under its #name property' do
23
+ expect { subject }.to change { object[name] }.
24
+ from(nil).
25
+ to(attribute)
26
+ end
27
+
28
+ it 'indexes the new attribute under the string version of its #name property' do
29
+ expect { subject }.to change { object[name.to_s] }.
30
+ from(nil).
31
+ to(attribute)
32
+ end
21
33
  end
22
34
 
23
35
  context 'with a duplicate attribute' do
@@ -10,4 +10,8 @@ describe Virtus::AttributeSet, '#[]' do
10
10
  let(:object) { described_class.new(parent, attributes) }
11
11
 
12
12
  it { should equal(attribute) }
13
+
14
+ it 'allows indexed access to attributes by the string representation of their name' do
15
+ object[name.to_s].should equal(attribute)
16
+ end
13
17
  end
@@ -9,27 +9,47 @@ describe Virtus::AttributeSet, '#[]=' do
9
9
  let(:name) { :name }
10
10
 
11
11
  context 'with a new attribute' do
12
- let(:attribute) { mock('Attribute', :name => name) }
12
+ let(:attribute) { mock('attribute', :name => name) }
13
13
 
14
14
  it { should equal(attribute) }
15
15
 
16
16
  it 'adds an attribute' do
17
- expect { subject }.to change { object.to_a }.
18
- from(attributes).
19
- to([ attribute ])
17
+ expect { subject }.to change { object.to_a }.from(attributes).to([ attribute ])
18
+ end
19
+
20
+ it 'allows #[] to access the attribute with a symbol' do
21
+ expect { subject }.to change { object['name'] }.from(nil).to(attribute)
22
+ end
23
+
24
+ it 'allows #[] to access the attribute with a string' do
25
+ expect { subject }.to change { object[:name] }.from(nil).to(attribute)
26
+ end
27
+
28
+ it 'allows #reset to track overridden attributes' do
29
+ expect { subject }.to change { object.reset.to_a }.from(attributes).to([ attribute ])
20
30
  end
21
31
  end
22
32
 
23
33
  context 'with a duplicate attribute' do
24
- let(:attributes) { [ mock('Attribute', :name => name) ] }
25
- let(:attribute) { mock('Duplicate', :name => name) }
34
+ let(:attributes) { [ mock('original', :name => name) ] }
35
+ let(:attribute) { mock('attribute', :name => name) }
26
36
 
27
37
  it { should equal(attribute) }
28
38
 
29
39
  it 'replaces the original attribute' do
30
- expect { subject }.to change { object.to_a }.
31
- from(attributes).
32
- to([ attribute ])
40
+ expect { subject }.to change { object.to_a }.from(attributes).to([ attribute ])
41
+ end
42
+
43
+ it 'allows #[] to access the attribute with a symbol' do
44
+ expect { subject }.to change { object['name'] }.from(nil).to(attribute)
45
+ end
46
+
47
+ it 'allows #[] to access the attribute with a string' do
48
+ expect { subject }.to change { object[:name] }.from(nil).to(attribute)
49
+ end
50
+
51
+ it 'allows #reset to track overridden attributes' do
52
+ expect { subject }.to change { object.reset.to_a }.from(attributes).to([ attribute ])
33
53
  end
34
54
  end
35
55
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::AttributesAccessor, '#inspect' do
4
+ subject { object.inspect }
5
+
6
+ let(:object) { described_class.new('Test') }
7
+
8
+ it { should eql('Test::AttributesAccessor') }
9
+ end