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,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module NilIfEmpty
6
+ extend Wardrobe::Plugin
7
+
8
+ Wardrobe.register_setter(
9
+ name: :nil_if_empty,
10
+ priority: 20,
11
+ use_if: ->(atr) { atr.options[:nil_if_empty] },
12
+ setter: lambda do |value, atr, _instance|
13
+ return value unless atr.options[:nil_if_empty]
14
+ case value
15
+ when String, Array, Hash
16
+ value unless value.empty?
17
+ else
18
+ value
19
+ end
20
+ end
21
+ )
22
+
23
+ option :nil_if_empty, Boolean, setter: :nil_if_empty
24
+ end
25
+ end
26
+ register_plugin(:nil_if_empty, Plugins::NilIfEmpty)
27
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ register_setter(
5
+ name: :nil_if_zero,
6
+ priority: 10,
7
+ use_if: ->(atr) { atr.options[:nil_if_zero] },
8
+ setter: lambda do |value, _atr, _instance|
9
+ value == 0 ? nil : value
10
+ end
11
+ )
12
+ module Plugins
13
+ module NilIfZero
14
+ extend Wardrobe::Plugin
15
+ option :nil_if_zero, Boolean, setter: :nil_if_zero
16
+ end
17
+ end
18
+ register_plugin(:nil_if_zero, Plugins::NilIfZero)
19
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module OptionalGetter
6
+ extend Wardrobe::Plugin
7
+
8
+ Wardrobe.register_getter(
9
+ name: :optional_getter,
10
+ priority: -100,
11
+ use_if: ->(atr) { atr.options[:getter] == false },
12
+ getter: lambda do |_value, atr, instance|
13
+ raise NoMethodError, "undefined method `#{atr.name}' for #{instance}"
14
+ end
15
+ )
16
+
17
+ option :getter, Boolean, default: true, getter: :optional_getter
18
+ end
19
+ end
20
+ register_plugin(:optional_getter, Plugins::OptionalGetter)
21
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module OptionalSetter
6
+ extend Wardrobe::Plugin
7
+
8
+ option :setter, Boolean, default: true
9
+
10
+ module InstanceMethods
11
+ def _attribute_init(atr, hash, name)
12
+ super unless atr.respond_to?(:setter) && atr.setter == false
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def define_setter(atr)
18
+ super unless atr.respond_to?(:setter) && atr.setter == false
19
+ end
20
+ end
21
+ end
22
+ end
23
+ register_plugin(:optional_setter, Plugins::OptionalSetter)
24
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Presenter
6
+ module Refinements
7
+ refine Array do
8
+ def _present(*_args)
9
+ map(&:_present)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Presenter
6
+ module Refinements
7
+ refine Hash do
8
+ def _present(*_args)
9
+ transform_values(&:_present)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Presenter
6
+ module Refinements
7
+ refine Object do
8
+ def _present(*_args)
9
+ self
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Presenter
6
+ module Refinements
7
+ refine Time do
8
+ def _present(**options)
9
+ if options[:time_formatter]
10
+ options[:time_formatter].call(self)
11
+ else
12
+ to_s
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'refinements/array'
4
+ require_relative 'refinements/hash'
5
+ require_relative 'refinements/time'
6
+ require_relative 'refinements/object'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'presenter/refinements'
4
+ module Wardrobe
5
+ module Plugins
6
+ module Presenter
7
+ extend Wardrobe::Plugin
8
+
9
+ module InstanceMethods
10
+ using Refinements
11
+ def _present(attributes: nil, **args)
12
+ options = self.class.plugin_store[:presenter][:options].merge(args)
13
+ result = {}
14
+ _attribute_store.store.each do |key, atr|
15
+ if attributes.nil? || (attributes && attributes.key?(key))
16
+ result[key] = send(atr.name)._present(attributes: (attributes[key] if attributes), **options)
17
+ end
18
+ end
19
+ result
20
+ end
21
+ end
22
+ end
23
+ end
24
+ register_plugin(:presenter, Plugins::Presenter)
25
+ end
@@ -0,0 +1,83 @@
1
+ module Wardrobe
2
+ module Plugins
3
+ module Validation
4
+ METHODS_WITHOUT_ARGUMENTS = [
5
+ :empty?,
6
+ :filled?,
7
+ :odd?,
8
+ :even?
9
+ ]
10
+
11
+ METHODS_WITH_ARGUMENTS = [
12
+ :format?,
13
+ :size?,
14
+ :min_size?,
15
+ :max_size?,
16
+ :included_in?,
17
+ :excluded_from?,
18
+ :gt?,
19
+ :lt?,
20
+ :lteq?,
21
+ :gteq?
22
+ ]
23
+
24
+ METHODS_WITH_BLOCK = [
25
+ :each?,
26
+ :each_key?,
27
+ :each_value?
28
+ ]
29
+
30
+ TYPE_METHODS = {
31
+ str?: String,
32
+ sym?: Symbol,
33
+ int?: Integer,
34
+ float?: Float,
35
+ bool?: Boolean,
36
+ date?: Date,
37
+ time?: Time,
38
+ date_time?: DateTime,
39
+ array?: Array,
40
+ hash?: Hash
41
+ }
42
+
43
+ class BlockHandler
44
+ attr_reader :result
45
+
46
+ def initialize(&blk)
47
+ @result = instance_exec(&blk)
48
+ end
49
+
50
+ private
51
+
52
+ def optional(&blk)
53
+ Validation.new(:_optional_, instance_exec(&blk))
54
+ end
55
+
56
+ TYPE_METHODS.each do |name, klass|
57
+ define_method(name) do
58
+ Validation.new(:type?, klass)
59
+ end
60
+ end
61
+
62
+ METHODS_WITHOUT_ARGUMENTS.each do |name|
63
+ define_method(name) do
64
+ Validation.new(name.to_sym, nil)
65
+ end
66
+ end
67
+
68
+ METHODS_WITH_ARGUMENTS.each do |name|
69
+ define_method(name) do |value|
70
+ Validation.new(name.to_sym, value)
71
+ end
72
+ end
73
+
74
+ METHODS_WITH_BLOCK.each do |name|
75
+ define_method(name) do |&blk|
76
+ raise 'Error. No block given' unless blk
77
+ Validation.new(name.to_sym, instance_exec(&blk))
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module ClassMethods
7
+ def validates(&blk)
8
+ { validates: BlockHandler.new(&blk).result }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+
7
+ module DeepMerge
8
+ refine Array do
9
+ def deep_merge!(other)
10
+ self.push(*other)
11
+ end
12
+ end
13
+ refine Hash do
14
+ def deep_merge!(other)
15
+ other.each do |key, value|
16
+ if has_key?(key)
17
+ self[key].deep_merge!(value)
18
+ else
19
+ self[key] = value
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ class ErrorStore
7
+ attr_reader :store
8
+
9
+ using DeepMerge
10
+ def initialize
11
+ @store = Hash.new { |hash, key| hash[key] = Array.new }
12
+ end
13
+
14
+ def add(atr, *errors)
15
+ errors.each do |error|
16
+ if error.is_a? String
17
+ @store[atr.name] << error
18
+ else
19
+ @store[atr.name].unshift({}) unless @store[atr.name].first.is_a?(Hash)
20
+ @store[atr.name].first.deep_merge!(error)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module InstanceMethods
7
+ def _validate
8
+ unless _validated?
9
+ @_validator = ValidationRunner.validate(self)
10
+ @_validated = true
11
+ end
12
+ self
13
+ end
14
+
15
+ def _validate!
16
+ _validate unless _validated?
17
+ raise ValidationError.new(@_validator.errors) unless _valid?
18
+ self
19
+ end
20
+
21
+ def _valid?
22
+ _validate unless _validated?
23
+ @_validator.errors.empty?
24
+ end
25
+
26
+ def _validation_errors
27
+ _validate unless _validated?
28
+ @_validator.errors
29
+ end
30
+
31
+ private
32
+
33
+ def _validated?
34
+ @_validated ||= false
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ module Size
8
+ def size?(predicate_value)
9
+ return if predicate_value === size
10
+ if predicate_value.is_a?(Range)
11
+ "size must be within #{predicate_value.min} - #{predicate_value.max}"
12
+ else
13
+ "size must be #{predicate_value}"
14
+ end
15
+ end
16
+
17
+ def min_size?(predicate_value)
18
+ return if predicate_value <= size
19
+ "size cannot be less than #{predicate_value}"
20
+ end
21
+
22
+ def max_size?(predicate_value)
23
+ return if predicate_value >= size
24
+ "size cannot be greater than #{predicate_value}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine ::Array do
8
+
9
+ alias_method :original_empty?, :empty?
10
+
11
+ def empty?
12
+ return if original_empty?
13
+ 'must be empty'
14
+ end
15
+
16
+ include Size
17
+
18
+ def filled?
19
+ return unless original_empty?
20
+ 'must be filled'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine ::Date do
8
+ def _inspect
9
+ to_s
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine ::Hash do
8
+ include Size
9
+
10
+ alias_method :original_empty?, :empty?
11
+
12
+ def empty?
13
+ return if original_empty?
14
+ 'must be empty'
15
+ end
16
+
17
+ alias_method :old_each_key, :each_key
18
+
19
+ def filled?
20
+ return unless original_empty?
21
+ 'must be filled'
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine Integer do
8
+ def odd?
9
+ return if super
10
+ 'must be odd'
11
+ end
12
+
13
+ def even?
14
+ return if super
15
+ 'must be even'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine NilClass do
8
+ def filled?
9
+ 'must be filled'
10
+ end
11
+
12
+ def empty?
13
+ # Nil is valid as empty
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine Numeric do
8
+ def gt?(num)
9
+ return if self > num
10
+ "must be greater than #{num}"
11
+ end
12
+
13
+ def lt?(num)
14
+ return if self < num
15
+ "must be less than #{num}"
16
+ end
17
+
18
+ def lteq?(num)
19
+ return if self <= num
20
+ "must be less than or equal to #{num}"
21
+ end
22
+
23
+ def gteq?(num)
24
+ return if self >= num
25
+ "must be greater than or equal to #{num}"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine Object do
8
+ def _inspect
9
+ inspect
10
+ end
11
+
12
+ def included_in?(list)
13
+ return if list.include?(self)
14
+ "must be one of: #{list.map(&:_inspect).join(', ')}"
15
+ end
16
+
17
+ def excluded_from?(list)
18
+ return unless list.include?(self)
19
+ "must not be one of: #{list.map(&:_inspect).join(', ')}"
20
+ end
21
+
22
+ def type?(predicate)
23
+ return if self.is_a?(predicate)
24
+ if predicate == Wardrobe::Boolean
25
+ return if self.is_a?(TrueClass) || self.is_a?(FalseClass)
26
+ "must be a TrueClass or FalseClass"
27
+ else
28
+ "must be a #{predicate}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine Set do
8
+ alias_method :original_empty?, :empty?
9
+
10
+ include Size
11
+
12
+ def empty?
13
+ return if original_empty?
14
+ 'must be empty'
15
+ end
16
+
17
+ def filled?
18
+ return unless original_empty?
19
+ 'must be filled'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wardrobe
4
+ module Plugins
5
+ module Validation
6
+ module Refinements
7
+ refine String do
8
+ include Size
9
+
10
+ alias_method :original_empty?, :empty?
11
+
12
+ def empty?
13
+ return if original_empty?
14
+ 'must be empty'
15
+ end
16
+
17
+ def filled?
18
+ return unless self.strip == ''
19
+ 'must be filled'
20
+ end
21
+
22
+ def format?(regex)
23
+ return if regex.match(self)
24
+ "must match #{regex.inspect}"
25
+ end
26
+
27
+ # def in(array)
28
+ # return unless array.include?(self)
29
+ # "\"#{self}\" is not included in '#{array.inspect}'"
30
+ # end
31
+ #
32
+ # alias_method :original_size, :size
33
+ #
34
+ # def size(range)
35
+ # unless range === original_size
36
+ # "\"#{self}\" violates length in range #{range}"
37
+ # end
38
+ # end
39
+ #
40
+ # def max_size(int)
41
+ # unless original_size <= int
42
+ # "\"#{self}\" has two many characters. Maximum #{int}"
43
+ # end
44
+ # end
45
+ #
46
+ # def min_size(int)
47
+ # unless original_size >= int
48
+ # "length cannot be less than #{int}"
49
+ # end
50
+ # end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end