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,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Collection, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { Class.new(described_class).new(:things, :member_type => member_type) }
7
+ let(:value) { [ entry ] }
8
+ let(:entry) { mock('entry') }
9
+ let(:member_type) { Virtus::Attribute::Object }
10
+
11
+ before do
12
+ value.should_receive(:respond_to?).with(:inject).and_return(respond_to_inject)
13
+ end
14
+
15
+ context 'when coerced value responds to #inject' do
16
+ let(:respond_to_inject) { true }
17
+
18
+ specify { expect { subject }.to raise_error(NotImplementedError) }
19
+ end
20
+
21
+ context 'when coerced value does not respond to #inject' do
22
+ let(:respond_to_inject) { false }
23
+
24
+ specify { should eql(value) }
25
+ end
26
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a correct date' do
4
+ it { should be_kind_of(Date) }
5
+ its(:year) { should eql(year) }
6
+ its(:month) { should eql(month) }
7
+ its(:day) { should eql(day) }
8
+ end
9
+
10
+ describe Virtus::Attribute::Date, '#coerce' do
11
+ subject { attribute.coerce(value) }
12
+
13
+ let(:attribute) { described_class.new(:bday) }
14
+ let(:year) { 2011 }
15
+ let(:month) { 4 }
16
+ let(:day) { 7 }
17
+
18
+ context 'with a time' do
19
+ let(:value) { Time.local(year, month, day) }
20
+
21
+ it_should_behave_like 'a correct date'
22
+ end
23
+
24
+ context 'with a date time' do
25
+ let(:value) { DateTime.new(year, month, day) }
26
+
27
+ it_should_behave_like 'a correct date'
28
+ end
29
+
30
+ context 'with a hash' do
31
+ let(:value) { { :year => year, :month => month, :day => day } }
32
+
33
+ it_should_behave_like 'a correct date'
34
+ end
35
+
36
+ context 'with a string' do
37
+ let(:value) { "April #{day}th, #{year}" }
38
+
39
+ it_should_behave_like 'a correct date'
40
+ end
41
+
42
+ context 'with a non-date value' do
43
+ let(:value) { 'non-date' }
44
+
45
+ it { should equal(value) }
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Date, '#value_coerced?' do
4
+ subject { attribute.value_coerced?(value) }
5
+
6
+ let(:attribute) { described_class.new(:bday) }
7
+ let(:year) { 2011 }
8
+ let(:month) { 4 }
9
+ let(:day) { 7 }
10
+
11
+ context 'with a Date' do
12
+ let(:value) { Date.new(year, month, day) }
13
+
14
+ it { should be(true) }
15
+ end
16
+
17
+ context 'with a date time' do
18
+ let(:value) { DateTime.new(year, month, day) }
19
+
20
+ it { should be(true) }
21
+ end
22
+
23
+ context 'with a time' do
24
+ let(:value) { Time.local(year, month, day) }
25
+
26
+ it { should be(false) }
27
+ end
28
+
29
+ context 'with a hash' do
30
+ let(:value) { { :year => year, :month => month, :day => day } }
31
+
32
+ it { should be(false) }
33
+ end
34
+
35
+ context 'with a string' do
36
+ let(:value) { "April #{day}th, #{year}" }
37
+
38
+ it { should be(false) }
39
+ end
40
+
41
+ context 'with a non-date value' do
42
+ let(:value) { 'non-date' }
43
+
44
+ it { should be(false) }
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'a correct date time' do
4
+ it { should be_kind_of(DateTime) }
5
+
6
+ its(:year) { should eql(year) }
7
+ its(:month) { should eql(month) }
8
+ its(:day) { should eql(day) }
9
+ its(:hour) { should eql(hour) }
10
+ its(:min) { should eql(min) }
11
+ its(:sec) { should eql(sec) }
12
+ end
13
+
14
+ describe Virtus::Attribute::DateTime, '#coerce' do
15
+ subject { attribute.coerce(value) }
16
+
17
+ let(:attribute) { described_class.new(:bday) }
18
+ let(:year) { 2011 }
19
+ let(:month) { 4 }
20
+ let(:day) { 7 }
21
+ let(:hour) { 1 }
22
+ let(:min) { 26 }
23
+ let(:sec) { 49 }
24
+
25
+ context 'with a date' do
26
+ let(:hour) { 0 }
27
+ let(:min) { 0 }
28
+ let(:sec) { 0 }
29
+ let(:value) { Date.new(year, month, day) }
30
+
31
+ it_should_behave_like 'a correct date time'
32
+ end
33
+
34
+ context 'with a time' do
35
+ let(:value) { Time.local(year, month, day, hour, min, sec) }
36
+
37
+ it_should_behave_like 'a correct date time'
38
+ end
39
+
40
+ context 'with a hash' do
41
+ let(:value) { { :year => year, :month => month, :day => day, :hour => hour, :min => min, :sec => sec } }
42
+
43
+ it_should_behave_like 'a correct date time'
44
+ end
45
+
46
+ context 'with a string' do
47
+ context 'without hour, min and sec' do
48
+ let(:hour) { 0 }
49
+ let(:min) { 0 }
50
+ let(:sec) { 0 }
51
+ let(:value) { "April #{day}th, #{year}" }
52
+
53
+ it_should_behave_like 'a correct date time'
54
+ end
55
+
56
+ context 'with hour, min and sec' do
57
+ let(:value) { "April #{day}th, #{year}, #{hour}:#{min}:#{sec}" }
58
+
59
+ it_should_behave_like 'a correct date time'
60
+ end
61
+ end
62
+
63
+ context 'with a on-date value' do
64
+ let(:value) { 'non-date' }
65
+
66
+ it { should equal(value) }
67
+ end
68
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::Decimal, '#coerce' do
4
+ subject { attribute.coerce(value) }
5
+
6
+ let(:attribute) { described_class.new(:price) }
7
+
8
+ context 'with 24.0 big decimal' do
9
+ let(:value) { BigDecimal('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(BigDecimal('0.0')) }
18
+ end
19
+
20
+ context 'with a positive string integer' do
21
+ let(:value) { '24' }
22
+
23
+ it { should eql(BigDecimal('24.0')) }
24
+ end
25
+
26
+ context 'with a negative string integer' do
27
+ let(:value) { '-24' }
28
+
29
+ it { should eql(BigDecimal('-24.0')) }
30
+ end
31
+
32
+ context 'with a zero string float' do
33
+ let(:value) { '0.0' }
34
+
35
+ it { should eql(BigDecimal('0.0')) }
36
+ end
37
+
38
+ context 'with a positive string float' do
39
+ let(:value) { '24.35' }
40
+
41
+ it { should eql(BigDecimal('24.35')) }
42
+ end
43
+
44
+ context 'with a negative string float' do
45
+ let(:value) { '-24.35' }
46
+
47
+ it { should eql(BigDecimal('-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(BigDecimal('0.0')) }
54
+ end
55
+
56
+ context 'with a positive string float, with no leading digits' do
57
+ let(:value) { '0.41' }
58
+
59
+ it { should eql(BigDecimal('0.41')) }
60
+ end
61
+
62
+ context 'with a zero integer' do
63
+ let(:value) { 0 }
64
+
65
+ it { should eql(BigDecimal('0.0')) }
66
+ end
67
+
68
+ context 'with a positive integer' do
69
+ let(:value) { 24 }
70
+
71
+ it { should eql(BigDecimal('24.0')) }
72
+ end
73
+
74
+ context 'with a negative integer' do
75
+ let(:value) { -24 }
76
+
77
+ it { should eql(BigDecimal('-24.0')) }
78
+ end
79
+
80
+ context 'with a positive bignum' do
81
+ let(:value) { 1311936052 }
82
+
83
+ it { should eql(BigDecimal('1311936052.0')) }
84
+ end
85
+
86
+ context 'with a negative bignum' do
87
+ let(:value) { -1311936052 }
88
+
89
+ it { should eql(BigDecimal('-1311936052.0')) }
90
+ end
91
+
92
+ context 'with a zero float' do
93
+ let(:value) { 0.0 }
94
+
95
+ it { should eql(BigDecimal('0.0')) }
96
+ end
97
+
98
+ context 'with a positive float' do
99
+ let(:value) { 24.35 }
100
+
101
+ it { should eql(BigDecimal('24.35')) }
102
+ end
103
+
104
+ context 'with a negative float' do
105
+ let(:value) { -24.35 }
106
+
107
+ it { should eql(BigDecimal('-24.35')) }
108
+ end
109
+
110
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |non_num_value|
111
+ context 'with a 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,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute, '#default' do
4
+ subject { object.default }
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 the default is not specified' do
12
+ it { should be_instance_of(Virtus::Attribute::DefaultValue) }
13
+
14
+ its(:attribute) { should be(object) }
15
+
16
+ its(:value) { should be_nil }
17
+ end
18
+
19
+ context 'when the default is specified' do
20
+ let(:default) { stub('default') }
21
+
22
+ before do
23
+ options.update(:default => default)
24
+ end
25
+
26
+ it { should be_instance_of(Virtus::Attribute::DefaultValue) }
27
+
28
+ its(:attribute) { should be(object) }
29
+
30
+ its(:value) { should be(default) }
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::DefaultValue, '#attribute' do
4
+ subject { object.attribute }
5
+
6
+ let(:object) { described_class.new(attribute, value) }
7
+ let(:attribute) { mock('attribute') }
8
+ let(:value) { mock('value') }
9
+
10
+ it { should be(attribute) }
11
+ end
@@ -5,15 +5,17 @@ describe Virtus::Attribute::DefaultValue, '.new' do
5
5
 
6
6
  let(:attribute) { Virtus::Attribute::String.new(:attribute) }
7
7
 
8
- context 'with a duplicable value' do
8
+ context 'with a cloneable value' do
9
9
  let(:value) { 'something' }
10
+
10
11
  its(:value) { should equal(value) }
11
12
  end
12
13
 
13
- context 'with a non-duplicable value' do
14
+ context 'with a non-cloneable value' do
14
15
  [ nil, true, false, 1, :symbol ].each do |value|
15
16
  context "with #{value.inspect}" do
16
17
  let(:value) { value }
18
+
17
19
  its(:value) { should equal(value) }
18
20
  end
19
21
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Virtus::Attribute::DefaultValue, '#evaluate' do
4
+ subject { object.evaluate(instance) }
5
+
6
+ let(:object) { described_class.new(attribute, value) }
7
+ let(:attribute) { mock('attribute') }
8
+ let(:value) { mock('value') }
9
+ let(:instance) { mock('instance') }
10
+
11
+ context 'when the value is callable' do
12
+ let(:response) { stub('response') }
13
+
14
+ before do
15
+ value.stub(:call => response)
16
+ end
17
+
18
+ it { should be(response) }
19
+
20
+ it 'calls the value with the instance and attribute' do
21
+ value.should_receive(:call).with(instance, attribute)
22
+ subject
23
+ end
24
+ end
25
+
26
+ context 'when the value is cloneable' do
27
+ let(:clone) { stub('clone') }
28
+
29
+ before do
30
+ value.stub(:clone => clone)
31
+ end
32
+
33
+ it { should be(clone) }
34
+
35
+ it 'clones the value' do
36
+ value.should_receive(:clone).with(no_args)
37
+ subject
38
+ end
39
+ end
40
+
41
+ # smallest number that is Bignum across major ruby impls
42
+ bignum = 0x7fffffffffffffff + 1
43
+
44
+ [ nil, true, false, 0, 0.0, bignum, :symbol ].each do |value|
45
+ context "when the value is #{value.inspect} (#{value.class})" do
46
+ let(:value) { value }
47
+
48
+ it { should be(value) }
49
+ end
50
+ end
51
+ end
@@ -3,25 +3,28 @@ require 'spec_helper'
3
3
  describe Virtus::Attribute::DefaultValue, '#evaluate' do
4
4
  subject { object.evaluate(instance) }
5
5
 
6
- let(:object) { described_class.new(attribute, value) }
6
+ let(:object) { described_class.new(attribute, value) }
7
7
  let(:attribute) { Virtus::Attribute::String.new(:title) }
8
- let(:instance) { Class.new }
8
+ let(:instance) { Class.new }
9
9
 
10
10
  context 'with a non-callable value' do
11
- context 'with a non-duplicable value' do
11
+ context 'with a non-cloneable value' do
12
12
  let(:value) { nil }
13
+
13
14
  it { should eql(value) }
14
15
  end
15
16
 
16
- context 'with a duplicable value' do
17
+ context 'with a cloneable value' do
17
18
  let(:value) { 'something' }
18
- it { should eql(value) }
19
- it { should_not equal(value)}
19
+
20
+ it { should eql(value) }
21
+ it { should_not equal(value) }
20
22
  end
21
23
  end
22
24
 
23
25
  context 'with a callable value' do
24
26
  let(:value) { lambda { |instance, attribute| attribute.name } }
27
+
25
28
  it { should be(:title) }
26
29
  end
27
30
  end