wardrobe 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 (165) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +10 -0
  3. data/.gitignore +19 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +11 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +18 -0
  8. data/Guardfile +42 -0
  9. data/LICENSE +19 -0
  10. data/README.md +227 -0
  11. data/Rakefile +20 -0
  12. data/examples/new_york_times_article.rb +55 -0
  13. data/lib/wardrobe/attribute.rb +76 -0
  14. data/lib/wardrobe/attribute_store.rb +16 -0
  15. data/lib/wardrobe/block_setup.rb +124 -0
  16. data/lib/wardrobe/boolean.rb +6 -0
  17. data/lib/wardrobe/class_methods.rb +127 -0
  18. data/lib/wardrobe/getter_setter.rb +48 -0
  19. data/lib/wardrobe/instance_methods.rb +56 -0
  20. data/lib/wardrobe/module_methods.rb +51 -0
  21. data/lib/wardrobe/option.rb +30 -0
  22. data/lib/wardrobe/option_store.rb +22 -0
  23. data/lib/wardrobe/plugin.rb +39 -0
  24. data/lib/wardrobe/plugin_store.rb +28 -0
  25. data/lib/wardrobe/plugins/alias_setters.rb +35 -0
  26. data/lib/wardrobe/plugins/coercible/refinements/array.rb +63 -0
  27. data/lib/wardrobe/plugins/coercible/refinements/boolean.rb +36 -0
  28. data/lib/wardrobe/plugins/coercible/refinements/date.rb +31 -0
  29. data/lib/wardrobe/plugins/coercible/refinements/date_time.rb +29 -0
  30. data/lib/wardrobe/plugins/coercible/refinements/float.rb +23 -0
  31. data/lib/wardrobe/plugins/coercible/refinements/hash.rb +65 -0
  32. data/lib/wardrobe/plugins/coercible/refinements/integer.rb +23 -0
  33. data/lib/wardrobe/plugins/coercible/refinements/object.rb +15 -0
  34. data/lib/wardrobe/plugins/coercible/refinements/set.rb +33 -0
  35. data/lib/wardrobe/plugins/coercible/refinements/string.rb +21 -0
  36. data/lib/wardrobe/plugins/coercible/refinements/symbol.rb +21 -0
  37. data/lib/wardrobe/plugins/coercible/refinements/time.rb +30 -0
  38. data/lib/wardrobe/plugins/coercible/refinements/unsupported_error.rb +11 -0
  39. data/lib/wardrobe/plugins/coercible.rb +52 -0
  40. data/lib/wardrobe/plugins/configurable/configurable_store.rb +26 -0
  41. data/lib/wardrobe/plugins/configurable.rb +40 -0
  42. data/lib/wardrobe/plugins/default.rb +33 -0
  43. data/lib/wardrobe/plugins/dirty_tracker.rb +66 -0
  44. data/lib/wardrobe/plugins/equality.rb +19 -0
  45. data/lib/wardrobe/plugins/html_initializer.rb +38 -0
  46. data/lib/wardrobe/plugins/immutable.rb +164 -0
  47. data/lib/wardrobe/plugins/ivy_presenter.rb +42 -0
  48. data/lib/wardrobe/plugins/json_initializer.rb +41 -0
  49. data/lib/wardrobe/plugins/nil_if_empty.rb +27 -0
  50. data/lib/wardrobe/plugins/nil_if_zero.rb +19 -0
  51. data/lib/wardrobe/plugins/optional_getter.rb +21 -0
  52. data/lib/wardrobe/plugins/optional_setter.rb +24 -0
  53. data/lib/wardrobe/plugins/presenter/refinements/array.rb +15 -0
  54. data/lib/wardrobe/plugins/presenter/refinements/hash.rb +15 -0
  55. data/lib/wardrobe/plugins/presenter/refinements/object.rb +15 -0
  56. data/lib/wardrobe/plugins/presenter/refinements/time.rb +19 -0
  57. data/lib/wardrobe/plugins/presenter/refinements.rb +6 -0
  58. data/lib/wardrobe/plugins/presenter.rb +25 -0
  59. data/lib/wardrobe/plugins/validation/block_handler.rb +83 -0
  60. data/lib/wardrobe/plugins/validation/class_methods.rb +13 -0
  61. data/lib/wardrobe/plugins/validation/deep_merge.rb +27 -0
  62. data/lib/wardrobe/plugins/validation/error_store.rb +27 -0
  63. data/lib/wardrobe/plugins/validation/instance_methods.rb +39 -0
  64. data/lib/wardrobe/plugins/validation/refinements/_size.rb +30 -0
  65. data/lib/wardrobe/plugins/validation/refinements/array.rb +26 -0
  66. data/lib/wardrobe/plugins/validation/refinements/date.rb +15 -0
  67. data/lib/wardrobe/plugins/validation/refinements/hash.rb +27 -0
  68. data/lib/wardrobe/plugins/validation/refinements/integer.rb +21 -0
  69. data/lib/wardrobe/plugins/validation/refinements/nil_class.rb +19 -0
  70. data/lib/wardrobe/plugins/validation/refinements/numeric.rb +31 -0
  71. data/lib/wardrobe/plugins/validation/refinements/object.rb +35 -0
  72. data/lib/wardrobe/plugins/validation/refinements/set.rb +25 -0
  73. data/lib/wardrobe/plugins/validation/refinements/string.rb +55 -0
  74. data/lib/wardrobe/plugins/validation/refinements/symbol.rb +26 -0
  75. data/lib/wardrobe/plugins/validation/refinements.rb +13 -0
  76. data/lib/wardrobe/plugins/validation/validation.rb +63 -0
  77. data/lib/wardrobe/plugins/validation/validation_error.rb +19 -0
  78. data/lib/wardrobe/plugins/validation/validaton_runner.rb +38 -0
  79. data/lib/wardrobe/plugins/validation/validator.rb +119 -0
  80. data/lib/wardrobe/plugins/validation.rb +28 -0
  81. data/lib/wardrobe/root_config.rb +31 -0
  82. data/lib/wardrobe/store.rb +62 -0
  83. data/lib/wardrobe/stores.rb +106 -0
  84. data/lib/wardrobe/version.rb +5 -0
  85. data/lib/wardrobe.rb +34 -0
  86. data/sandbox/Gemfile +5 -0
  87. data/sandbox/Gemfile.lock +52 -0
  88. data/sandbox/bench_mutable_coercion.rb +91 -0
  89. data/sandbox/bench_test_1.rb +50 -0
  90. data/sandbox/bench_test_2.rb +48 -0
  91. data/sandbox/bench_test_3.rb +92 -0
  92. data/sandbox/cnn_article_find.rb +20 -0
  93. data/sandbox/define_method_procs.rb +139 -0
  94. data/sandbox/hanami_validations.rb +40 -0
  95. data/sandbox/middleware_bench_test.rb +97 -0
  96. data/sandbox/middleware_bench_v2_test.rb +130 -0
  97. data/test/assertions.rb +22 -0
  98. data/test/test_helper.rb +37 -0
  99. data/test/unit/atrs_config_test.rb +33 -0
  100. data/test/unit/atrs_root_module_test.rb +19 -0
  101. data/test/unit/attribute_test.rb +44 -0
  102. data/test/unit/block_runner/array_test.rb +29 -0
  103. data/test/unit/block_setup_test.rb +41 -0
  104. data/test/unit/class_methods_test.rb +92 -0
  105. data/test/unit/create_class_from_hash_test.rb +28 -0
  106. data/test/unit/define_getter_test.rb +94 -0
  107. data/test/unit/define_setter_test.rb +0 -0
  108. data/test/unit/disable_coercion_test.rb +19 -0
  109. data/test/unit/inheritance_composition_test.rb +36 -0
  110. data/test/unit/method_override_test.rb +18 -0
  111. data/test/unit/method_polution_test.rb +48 -0
  112. data/test/unit/option_test.rb +17 -0
  113. data/test/unit/plugin_test.rb +12 -0
  114. data/test/unit/plugins/alias_setters_test.rb +24 -0
  115. data/test/unit/plugins/coercible/array_test.rb +79 -0
  116. data/test/unit/plugins/coercible/boolean_test.rb +68 -0
  117. data/test/unit/plugins/coercible/custom_class_test.rb +61 -0
  118. data/test/unit/plugins/coercible/date_test.rb +38 -0
  119. data/test/unit/plugins/coercible/date_time_test.rb +44 -0
  120. data/test/unit/plugins/coercible/float_test.rb +42 -0
  121. data/test/unit/plugins/coercible/hash_test.rb +62 -0
  122. data/test/unit/plugins/coercible/integer_test.rb +42 -0
  123. data/test/unit/plugins/coercible/nested_wardrobe_test.rb +63 -0
  124. data/test/unit/plugins/coercible/set_test.rb +49 -0
  125. data/test/unit/plugins/coercible/string_test.rb +36 -0
  126. data/test/unit/plugins/coercible/symbol_test.rb +30 -0
  127. data/test/unit/plugins/coercible/time_test.rb +43 -0
  128. data/test/unit/plugins/configurable_test.rb +64 -0
  129. data/test/unit/plugins/default_value_test.rb +78 -0
  130. data/test/unit/plugins/dirty_tracker_test.rb +78 -0
  131. data/test/unit/plugins/equality_test.rb +36 -0
  132. data/test/unit/plugins/html_initializer_test.rb +19 -0
  133. data/test/unit/plugins/immutable_test.rb +149 -0
  134. data/test/unit/plugins/ivy_presenter_test.rb +57 -0
  135. data/test/unit/plugins/json_initializer_test.rb +67 -0
  136. data/test/unit/plugins/nil_if_empty_test.rb +39 -0
  137. data/test/unit/plugins/nil_if_zero_test.rb +26 -0
  138. data/test/unit/plugins/presenter_test.rb +68 -0
  139. data/test/unit/plugins/validate/inheritance_test.rb +36 -0
  140. data/test/unit/plugins/validate/nested_model_test.rb +40 -0
  141. data/test/unit/plugins/validate/predicates/each_key_each_value_test.rb +34 -0
  142. data/test/unit/plugins/validate/predicates/each_test.rb +33 -0
  143. data/test/unit/plugins/validate/predicates/empty_test.rb +37 -0
  144. data/test/unit/plugins/validate/predicates/even_test.rb +33 -0
  145. data/test/unit/plugins/validate/predicates/excluded_from_test.rb +55 -0
  146. data/test/unit/plugins/validate/predicates/filled_test.rb +49 -0
  147. data/test/unit/plugins/validate/predicates/format_test.rb +28 -0
  148. data/test/unit/plugins/validate/predicates/gt_test.rb +36 -0
  149. data/test/unit/plugins/validate/predicates/gteq_test.rb +36 -0
  150. data/test/unit/plugins/validate/predicates/included_in_test.rb +55 -0
  151. data/test/unit/plugins/validate/predicates/lt_test.rb +36 -0
  152. data/test/unit/plugins/validate/predicates/lteq_test.rb +36 -0
  153. data/test/unit/plugins/validate/predicates/max_size_test.rb +43 -0
  154. data/test/unit/plugins/validate/predicates/min_size_test.rb +43 -0
  155. data/test/unit/plugins/validate/predicates/none_test.rb +49 -0
  156. data/test/unit/plugins/validate/predicates/odd_test.rb +33 -0
  157. data/test/unit/plugins/validate/predicates/size_range_test.rb +43 -0
  158. data/test/unit/plugins/validate/predicates/size_test.rb +43 -0
  159. data/test/unit/plugins/validate/predicates/type_test.rb +77 -0
  160. data/test/unit/plugins/validate/predicates_test.rb +73 -0
  161. data/test/unit/plugins/validate/validate_bang_test.rb +30 -0
  162. data/test/unit/store_test.rb +15 -0
  163. data/test/unit/stores_test.rb +18 -0
  164. data/wardrobe.gemspec +26 -0
  165. metadata +344 -0
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+
3
+ class CustomClassTest < TestBase
4
+ class CustomClass
5
+ attr_reader :data
6
+ def initialize(input)
7
+ @data = input
8
+ end
9
+ end
10
+
11
+ class CustomClassWithCoerceMethod
12
+ attr_reader :one, :two
13
+
14
+ def initialize(one, two)
15
+ @one = one
16
+ @two = two
17
+ end
18
+
19
+ def self.coerce(input, atr)
20
+ case input
21
+ when Array then new(*input)
22
+ else
23
+ raise Wardrobe::Plugins::Coercible::Refinements::UnsupportedError
24
+ end
25
+ end
26
+ end
27
+
28
+ class WardrobeClass
29
+ include Wardrobe
30
+ attribute :string, String
31
+ attribute :custom, CustomClass
32
+ attribute :custom_coerce, CustomClassWithCoerceMethod
33
+ end
34
+
35
+ def test_coercion
36
+ object = WardrobeClass.new(
37
+ string: :foo,
38
+ custom: :bar,
39
+ custom_coerce: [1,2]
40
+ )
41
+
42
+ assert_equal 'foo', object.string
43
+ assert_equal :bar, object.custom.data
44
+ assert_equal 1, object.custom_coerce.one
45
+ assert_equal 2, object.custom_coerce.two
46
+ end
47
+
48
+ def test_error
49
+ assert_raises(ArgumentError) do
50
+ WardrobeClass.new(
51
+ custom_coerce: [1, 2, 3]
52
+ )
53
+ end
54
+
55
+ assert_raises(Wardrobe::Plugins::Coercible::Refinements::UnsupportedError) do
56
+ WardrobeClass.new(
57
+ custom_coerce: 1
58
+ )
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class DateCoercionTest < TestBase
4
+ class DateObject
5
+ include Wardrobe
6
+ attribute :string, Date
7
+ attribute :date, Date
8
+ attribute :time, Date
9
+ attribute :datetime, Date
10
+ attribute :integer, Date
11
+ attribute :float, Date
12
+ end
13
+
14
+ def test_coercion
15
+ time = Time.now.freeze
16
+ date = time.to_date.freeze
17
+ object = DateObject.new(
18
+ string: date.to_s,
19
+ date: date,
20
+ time: time,
21
+ datetime: time.to_datetime,
22
+ integer: time.to_i,
23
+ float: time.to_f
24
+ )
25
+ assert_equal date, object.string
26
+ assert_equal date, object.date
27
+ assert_equal date, object.time
28
+ assert_equal date, object.datetime
29
+ assert_equal date, object.integer
30
+ assert_equal date, object.float
31
+ end
32
+
33
+ def test_error
34
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
35
+ DateObject.new(string: [])
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class DateTimeCoercionTest < TestBase
4
+ class DateTimeObject
5
+ include Wardrobe
6
+ attribute :string, DateTime
7
+ attribute :string_utc, DateTime
8
+ attribute :string_iso8601, DateTime
9
+ attribute :time, DateTime
10
+ attribute :date, DateTime
11
+ attribute :datetime, DateTime
12
+ attribute :integer, DateTime
13
+ attribute :float, DateTime
14
+ end
15
+
16
+ def test_coercion
17
+ datetime = DateTime.now.freeze
18
+ object = DateTimeObject.new(
19
+ string: datetime.to_s,
20
+ string_utc: datetime.dup.to_time.utc.to_s,
21
+ string_iso8601: datetime.iso8601,
22
+ datetime: datetime,
23
+ time: datetime.to_time,
24
+ date: datetime.to_date,
25
+ integer: datetime.to_time.to_i,
26
+ float: datetime.to_time.to_f
27
+ )
28
+ datetime_from_int = Time.at(datetime.to_time.to_i).to_datetime
29
+ assert_equal datetime_from_int, object.string
30
+ assert_equal datetime_from_int, object.string_utc
31
+ assert_equal datetime_from_int, object.string_iso8601
32
+ assert_equal datetime, object.time
33
+ assert_equal datetime_from_int.to_date, object.date
34
+ assert_equal datetime, object.datetime
35
+ assert_equal Time.at(datetime.to_time.to_i).to_datetime, object.integer
36
+ assert_equal Time.at(datetime.to_time.to_f).to_datetime, object.float
37
+ end
38
+
39
+ def test_error
40
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
41
+ DateTimeObject.new(string: [])
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class FlaotCoercionTest < TestBase
4
+ class FloatObject
5
+ include Wardrobe
6
+ attribute :float, Float
7
+ attribute :string, Float
8
+ attribute :integer, Float
9
+ attribute :time, Float
10
+ attribute :datetime, Float
11
+ attribute :date, Float
12
+ attribute :nil, Float
13
+ end
14
+
15
+ def test_coercion
16
+ now = Time.now.freeze
17
+
18
+ object = FloatObject.new(
19
+ float: 1.01,
20
+ string: '1.02',
21
+ integer: 1,
22
+ time: now,
23
+ datetime: now.to_datetime,
24
+ date: now.to_date,
25
+ nil: nil
26
+ )
27
+
28
+ assert_equal 1.01, object.float
29
+ assert_equal 1.02, object.string
30
+ assert_equal 1.0, object.integer
31
+ assert_equal now.to_f, object.time
32
+ assert_equal now.to_f, object.datetime
33
+ assert_equal now.to_date.to_time.to_f, object.date
34
+ assert_nil object.nil
35
+ end
36
+
37
+ def test_error
38
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
39
+ FloatObject.new(float: [])
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+
3
+ class HashCoercionTest < TestBase
4
+ class Person
5
+ include Wardrobe
6
+ attribute :name, String
7
+ end
8
+
9
+ class HashObject
10
+ include Wardrobe
11
+ attribute :hash, Hash
12
+ attribute :string_symbol, Hash[String => Symbol]
13
+ attribute :integer_float, Hash[Integer => Float]
14
+ attribute :time_set, Hash[Time => Set]
15
+ attribute :person_int, Hash[Person => Integer]
16
+ attribute :string_person, Hash[String => Person]
17
+ attribute :nil, Hash
18
+ end
19
+
20
+ def setup
21
+ @now = Time.now
22
+ @later = @now + 1
23
+ @object = HashObject.new(
24
+ hash: { any: 'thing'},
25
+ string_symbol: { 1 => 'one', :two => 'two'},
26
+ integer_float: { '1' => 1, 2.0 => '2.2'},
27
+ time_set: { @now.to_i => [1,1], @later.to_s => Set.new([2,2])},
28
+ person_int: { { name: 'Test' } => '1' },
29
+ string_person: { 1 => { name: 'Test' } }
30
+ )
31
+ end
32
+
33
+ def test_coercion
34
+ assert_equal 'thing', @object.hash[:any]
35
+ assert_equal :one, @object.string_symbol['1']
36
+ assert_equal :two, @object.string_symbol['two']
37
+ assert_equal 1.0, @object.integer_float[1]
38
+ assert_equal 2.2, @object.integer_float[2]
39
+ assert_equal Set.new([1]), @object.time_set[Time.at(@now.to_i)]
40
+ assert_equal Set.new([2]), @object.time_set[Time.at(@later.to_i)]
41
+ assert_equal '1', @object.string_person.keys.first
42
+ assert_equal 1, @object.person_int.values.first
43
+ assert Person === @object.string_person.values.first
44
+ assert Person === @object.person_int.keys.first
45
+ assert_equal Hash.new, @object.nil
46
+ end
47
+
48
+ def test_modifying_hash
49
+ @object.string_symbol[3] = 'three'
50
+ assert_nil @object.string_symbol[3]
51
+ assert_equal :three, @object.string_symbol['3']
52
+ end
53
+
54
+ def test_error
55
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
56
+ HashObject.new(string_symbol: [1,2])
57
+ end
58
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
59
+ HashObject.new(integer_float: Time.now)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class IntegerCoercionTest < TestBase
4
+ class IntegerObject
5
+ include Wardrobe
6
+ attribute :integer, Integer
7
+ attribute :float, Integer
8
+ attribute :string, Integer
9
+ attribute :string_float, Integer
10
+ attribute :time, Integer
11
+ attribute :datetime, Integer
12
+ attribute :date, Integer
13
+ end
14
+
15
+ def test_coercion
16
+ now = Time.now.freeze
17
+
18
+ object = IntegerObject.new(
19
+ integer: 1,
20
+ float: 100.01,
21
+ string: '1001',
22
+ string_float: '1002.002',
23
+ time: now,
24
+ datetime: now.to_datetime,
25
+ date: now.to_date
26
+ )
27
+
28
+ assert_equal 100, object.float
29
+ assert_equal 1001, object.string
30
+ assert_equal 1002, object.string_float
31
+ assert_equal 1, object.integer
32
+ assert_equal now.to_i, object.time
33
+ assert_equal now.to_i, object.datetime
34
+ assert_equal now.to_date.to_time.to_i, object.date
35
+ end
36
+
37
+ def test_error
38
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
39
+ IntegerObject.new(integer: [])
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ class NestedWardrobeTest < TestBase
4
+
5
+ class One
6
+ include Wardrobe
7
+ attribute :name, String
8
+ end
9
+
10
+ class Two
11
+ include Wardrobe
12
+ attribute :user, One
13
+ end
14
+
15
+ class Three
16
+ include Wardrobe
17
+ attribute :group, Array[Two]
18
+ end
19
+
20
+ def test_coercion
21
+ object = Three.new(
22
+ group: [
23
+ {
24
+ user: {
25
+ name: 'Foo'
26
+ }
27
+ },
28
+ {
29
+ user: {
30
+ name: 'Bar'
31
+ }
32
+ }
33
+ ]
34
+ )
35
+
36
+ assert_equal 'Foo', object.group.first.user.name
37
+ assert_equal 'Bar', object.group.last.user.name
38
+ end
39
+
40
+ def test_nil_as_input_for_nested_wardrobe
41
+ object = Three.new(
42
+ group: nil
43
+ )
44
+
45
+ assert_equal [], object.group
46
+ end
47
+
48
+ def test_string_as_input_for_nested_wardrobe
49
+ assert_raises(ArgumentError) do
50
+ Two.new(
51
+ user: 'Foo'
52
+ )
53
+ end
54
+ end
55
+
56
+ def test_string_as_input_for_nested_wardrobe_in_array
57
+ assert_raises(Wardrobe::Plugins::Coercible::Refinements::UnsupportedError) do
58
+ Three.new(
59
+ group: 'Foo'
60
+ )
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class SetCoercionTest < TestBase
4
+ class Person
5
+ include Wardrobe
6
+ attribute :name, String
7
+ end
8
+
9
+ class SetObject
10
+ include Wardrobe
11
+ attribute :set, Set
12
+ attribute :array, Set
13
+ attribute :nil, Set
14
+ attribute :set_with_subclass, Set[Person]
15
+ attribute :array_with_subclass, Set[Person]
16
+ end
17
+
18
+ def test_coercion
19
+ object = SetObject.new(
20
+ set: Set.new([1,1,2,2]),
21
+ array: [3,3,4,4],
22
+ nil: nil,
23
+ set_with_subclass: Set.new([{name: 'Test'}]),
24
+ array_with_subclass: [{name: 'Test'}]
25
+ )
26
+ assert_equal Set.new([1,2]), object.set
27
+ assert_equal Set.new([3,4]), object.array
28
+ assert_equal Set.new, object.nil
29
+ assert Person === object.set_with_subclass.first
30
+ assert Person === object.array_with_subclass.first
31
+ end
32
+
33
+ def test_set_instance_coercion
34
+ object = SetObject.new(set_with_subclass: nil)
35
+ assert_equal Set.new, object.set_with_subclass
36
+ end
37
+
38
+ def test_error
39
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
40
+ SetObject.new(set_with_subclass: :sym)
41
+ end
42
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
43
+ SetObject.new(set: Time.now)
44
+ end
45
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
46
+ SetObject.new(array: 'string')
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class StringCoercionTest < TestBase
4
+ class StringObject
5
+ include Wardrobe
6
+ attribute :string, String
7
+ attribute :symbol, String
8
+ attribute :integer, String
9
+ attribute :float, String
10
+ attribute :nil, String
11
+ end
12
+
13
+ def test_coercion
14
+ object = StringObject.new(
15
+ string: 'string',
16
+ symbol: :a_symbol,
17
+ integer: 123,
18
+ float: 1.23,
19
+ nil: nil
20
+ )
21
+ assert_equal 'string', object.string
22
+ assert_equal 'a_symbol', object.symbol
23
+ assert_equal '123', object.integer
24
+ assert_equal '1.23', object.float
25
+ assert_nil object.nil
26
+ end
27
+
28
+ def test_error
29
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
30
+ StringObject.new(string: [1,2])
31
+ end
32
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
33
+ StringObject.new(symbol: Time.now)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ class SymbolCoercionTest < TestBase
4
+ class SymbolObject
5
+ include Wardrobe
6
+ attribute :symbol, Symbol
7
+ attribute :string, Symbol
8
+ attribute :nil, Symbol
9
+ end
10
+
11
+ def test_coercion
12
+ object = SymbolObject.new(
13
+ symbol: :a_symbol,
14
+ string: 'a_string',
15
+ nil: nil
16
+ )
17
+ assert_equal :a_symbol, object.symbol
18
+ assert_equal :a_string, object.string
19
+ assert_nil object.nil
20
+ end
21
+
22
+ def test_error
23
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
24
+ SymbolObject.new(string: [1,2])
25
+ end
26
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
27
+ SymbolObject.new(symbol: Time.now)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ class TimeCoercionTest < TestBase
4
+ class TimeObject
5
+ include Wardrobe
6
+ attribute :string, Time
7
+ attribute :string_utc, Time
8
+ attribute :string_iso8601, Time
9
+ attribute :time, Time
10
+ attribute :date, Time
11
+ attribute :datetime, Time
12
+ attribute :integer, Time
13
+ attribute :float, Time
14
+ end
15
+
16
+ def test_coercion
17
+ time = Time.now.freeze
18
+ object = TimeObject.new(
19
+ string: time.to_s,
20
+ string_utc: time.dup.utc.to_s,
21
+ string_iso8601: time.iso8601,
22
+ time: time,
23
+ date: time.to_date,
24
+ datetime: time.to_datetime,
25
+ integer: time.to_i,
26
+ float: time.to_f
27
+ )
28
+ assert_equal time.to_i, object.string.to_i
29
+ assert_equal time.to_i, object.string_utc.to_i
30
+ assert_equal time.to_i, object.string_iso8601.to_i
31
+ assert_equal time, object.time
32
+ assert_equal time.to_date.to_time, object.date
33
+ assert_equal time, object.datetime
34
+ assert_equal Time.at(time.to_i), object.integer
35
+ assert_equal Time.at(time.to_f), object.float
36
+ end
37
+
38
+ def test_error
39
+ assert_raises Wardrobe::Plugins::Coercible::Refinements::UnsupportedError do
40
+ TimeObject.new(string: [])
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ class ParamConfig
4
+ include Wardrobe
5
+ plugin :immutable
6
+ attribute :name, String
7
+ attribute :klass, Symbol
8
+ end
9
+
10
+ class ChildTestConfig
11
+ include Wardrobe
12
+ plugin :immutable
13
+ attribute :name, String
14
+ attribute :params, Array[ParamConfig]
15
+ end
16
+
17
+ class TestConfig
18
+ include Wardrobe
19
+ plugin :immutable
20
+ attribute :title, String
21
+ attribute :child, ChildTestConfig
22
+ end
23
+
24
+ class Base
25
+ include Wardrobe
26
+ plugin :configurable
27
+ configurable :config, :configure, TestConfig
28
+ configure do |config|
29
+ config.title = 'Title'
30
+ config.child.name = 'Child Title'
31
+ end
32
+ end
33
+
34
+ class Child < Base
35
+ configure do |config|
36
+ config.child.name = 'Modified Child Title'
37
+ end
38
+ end
39
+
40
+ # class Child2 < Child
41
+ # configure do |config|
42
+ # # config.set(title: 'Title in Child2')
43
+ # # config.title = 'Title in Child2'
44
+ # # config.child.name = 'Name in Child2'
45
+ # end
46
+ # end
47
+
48
+
49
+ class ConfigurableTest < TestBase
50
+ def test_store_created_in_config
51
+ assert Base.configurable_store
52
+ assert Child.configurable_store
53
+ end
54
+
55
+ def test_child_class
56
+ assert_equal 'Title', Base.config.title
57
+ assert_equal 'Child Title', Base.config.child.name
58
+ end
59
+
60
+ def test_modified_child_class
61
+ assert_equal 'Title', Child.config.title
62
+ assert_equal 'Modified Child Title', Child.config.child.name
63
+ end
64
+ end
@@ -0,0 +1,78 @@
1
+ require 'test_helper'
2
+
3
+ module DefaultMixin
4
+ include Wardrobe
5
+ plugin :default
6
+ attribute :name, String, default: 'missing name'
7
+ attribute :address, String, default: :address_default
8
+ attribute :zip_code, String, default: -> { '0' + '1' }
9
+ attribute :for_sale, Boolean, default: false
10
+ attribute :for_rent, Boolean, default: true
11
+
12
+ def address_default
13
+ 'missing address'
14
+ end
15
+ end
16
+
17
+ class House
18
+ include DefaultMixin
19
+ attribute :floors, Integer, default: 2
20
+ attribute :bedrooms, Integer, default: :bedrooms_default
21
+ attribute :bathrooms, Integer, default: ->() { 1 + 3 }
22
+ attribute :condition, Symbol, default: :new
23
+ attribute :no_default, String
24
+
25
+ def bedrooms_default
26
+ 10
27
+ end
28
+ end
29
+
30
+ class HouseWithAddressDefaultOverride < House
31
+ def address_default
32
+ 'overridden'
33
+ end
34
+ end
35
+
36
+
37
+ class DefaultValueTest < TestBase
38
+ def setup
39
+ @house = House.new
40
+ end
41
+
42
+ def test_default_literal
43
+ assert_equal 2, @house.floors
44
+ assert_equal 'missing name', @house.name
45
+ end
46
+
47
+ def test_default_boolean
48
+ assert_equal 3,House.attribute_store[:for_rent].setters.length
49
+ assert_equal 3,House.attribute_store[:for_sale].setters.length
50
+ assert_equal true, @house.for_rent
51
+ assert_equal false, @house.for_sale
52
+ @house.for_rent = false
53
+ @house.for_sale = true
54
+ assert_equal false, @house.for_rent
55
+ assert_equal true, @house.for_sale
56
+ end
57
+
58
+ def test_default_symbol
59
+ assert_equal 10, @house.bedrooms
60
+ assert_equal 'missing address', @house.address
61
+ end
62
+
63
+ def test_default_proc
64
+ assert_equal 4, @house.bathrooms
65
+ end
66
+
67
+ def test_symbol_default
68
+ assert_equal :new, @house.condition
69
+ end
70
+
71
+ def test_no_default
72
+ assert_nil @house.no_default
73
+ end
74
+
75
+ def test_default_method_override
76
+ assert_equal 'overridden', HouseWithAddressDefaultOverride.new.address
77
+ end
78
+ end