schemacop 2.4.5 → 3.0.0.rc2

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +25 -1
  4. data/.travis.yml +3 -1
  5. data/CHANGELOG.md +32 -1
  6. data/README.md +53 -710
  7. data/README_V2.md +775 -0
  8. data/README_V3.md +1195 -0
  9. data/Rakefile +8 -12
  10. data/VERSION +1 -1
  11. data/lib/schemacop.rb +35 -36
  12. data/lib/schemacop/base_schema.rb +37 -0
  13. data/lib/schemacop/railtie.rb +10 -0
  14. data/lib/schemacop/schema.rb +1 -60
  15. data/lib/schemacop/schema2.rb +22 -0
  16. data/lib/schemacop/schema3.rb +21 -0
  17. data/lib/schemacop/scoped_env.rb +25 -13
  18. data/lib/schemacop/v2.rb +26 -0
  19. data/lib/schemacop/{caster.rb → v2/caster.rb} +16 -2
  20. data/lib/schemacop/{collector.rb → v2/collector.rb} +5 -2
  21. data/lib/schemacop/{dupper.rb → v2/dupper.rb} +1 -1
  22. data/lib/schemacop/{field_node.rb → v2/field_node.rb} +4 -3
  23. data/lib/schemacop/v2/node.rb +142 -0
  24. data/lib/schemacop/{node_resolver.rb → v2/node_resolver.rb} +1 -1
  25. data/lib/schemacop/v2/node_supporting_field.rb +70 -0
  26. data/lib/schemacop/{node_supporting_type.rb → v2/node_supporting_type.rb} +14 -11
  27. data/lib/schemacop/{node_with_block.rb → v2/node_with_block.rb} +3 -2
  28. data/lib/schemacop/v2/root_node.rb +6 -0
  29. data/lib/schemacop/v2/validator/array_validator.rb +32 -0
  30. data/lib/schemacop/{validator → v2/validator}/boolean_validator.rb +1 -1
  31. data/lib/schemacop/v2/validator/float_validator.rb +7 -0
  32. data/lib/schemacop/v2/validator/hash_validator.rb +37 -0
  33. data/lib/schemacop/v2/validator/integer_validator.rb +7 -0
  34. data/lib/schemacop/{validator → v2/validator}/nil_validator.rb +1 -1
  35. data/lib/schemacop/v2/validator/number_validator.rb +21 -0
  36. data/lib/schemacop/v2/validator/object_validator.rb +29 -0
  37. data/lib/schemacop/v2/validator/string_validator.rb +39 -0
  38. data/lib/schemacop/{validator → v2/validator}/symbol_validator.rb +1 -1
  39. data/lib/schemacop/v3.rb +45 -0
  40. data/lib/schemacop/v3/all_of_node.rb +27 -0
  41. data/lib/schemacop/v3/any_of_node.rb +28 -0
  42. data/lib/schemacop/v3/array_node.rb +218 -0
  43. data/lib/schemacop/v3/boolean_node.rb +16 -0
  44. data/lib/schemacop/v3/combination_node.rb +45 -0
  45. data/lib/schemacop/v3/context.rb +17 -0
  46. data/lib/schemacop/v3/dsl_scope.rb +46 -0
  47. data/lib/schemacop/v3/global_context.rb +114 -0
  48. data/lib/schemacop/v3/hash_node.rb +256 -0
  49. data/lib/schemacop/v3/integer_node.rb +13 -0
  50. data/lib/schemacop/v3/is_not_node.rb +32 -0
  51. data/lib/schemacop/v3/node.rb +215 -0
  52. data/lib/schemacop/v3/node_registry.rb +49 -0
  53. data/lib/schemacop/v3/number_node.rb +18 -0
  54. data/lib/schemacop/v3/numeric_node.rb +76 -0
  55. data/lib/schemacop/v3/object_node.rb +40 -0
  56. data/lib/schemacop/v3/one_of_node.rb +28 -0
  57. data/lib/schemacop/v3/reference_node.rb +49 -0
  58. data/lib/schemacop/v3/result.rb +58 -0
  59. data/lib/schemacop/v3/string_node.rb +124 -0
  60. data/lib/schemacop/v3/symbol_node.rb +13 -0
  61. data/schemacop.gemspec +24 -27
  62. data/test/lib/test_helper.rb +152 -0
  63. data/test/schemas/nested/group.rb +6 -0
  64. data/test/schemas/user.rb +7 -0
  65. data/test/unit/schemacop/v2/casting_test.rb +120 -0
  66. data/test/unit/schemacop/v2/collector_test.rb +47 -0
  67. data/test/unit/schemacop/v2/custom_check_test.rb +95 -0
  68. data/test/unit/schemacop/v2/custom_if_test.rb +97 -0
  69. data/test/unit/schemacop/v2/defaults_test.rb +95 -0
  70. data/test/unit/schemacop/v2/empty_test.rb +16 -0
  71. data/test/unit/schemacop/v2/nil_dis_allow_test.rb +43 -0
  72. data/test/unit/schemacop/v2/node_resolver_test.rb +28 -0
  73. data/test/unit/schemacop/v2/short_forms_test.rb +351 -0
  74. data/test/unit/schemacop/v2/types_test.rb +88 -0
  75. data/test/unit/schemacop/v2/validator_array_test.rb +99 -0
  76. data/test/unit/schemacop/v2/validator_boolean_test.rb +17 -0
  77. data/test/unit/schemacop/v2/validator_float_test.rb +59 -0
  78. data/test/unit/schemacop/v2/validator_hash_test.rb +95 -0
  79. data/test/unit/schemacop/v2/validator_integer_test.rb +48 -0
  80. data/test/unit/schemacop/v2/validator_nil_test.rb +15 -0
  81. data/test/unit/schemacop/v2/validator_number_test.rb +62 -0
  82. data/test/unit/schemacop/v2/validator_object_test.rb +141 -0
  83. data/test/unit/schemacop/v2/validator_string_test.rb +78 -0
  84. data/test/unit/schemacop/v2/validator_symbol_test.rb +18 -0
  85. data/test/unit/schemacop/v3/all_of_node_test.rb +198 -0
  86. data/test/unit/schemacop/v3/any_of_node_test.rb +218 -0
  87. data/test/unit/schemacop/v3/array_node_test.rb +815 -0
  88. data/test/unit/schemacop/v3/boolean_node_test.rb +126 -0
  89. data/test/unit/schemacop/v3/global_context_test.rb +164 -0
  90. data/test/unit/schemacop/v3/hash_node_test.rb +884 -0
  91. data/test/unit/schemacop/v3/integer_node_test.rb +323 -0
  92. data/test/unit/schemacop/v3/is_not_node_test.rb +173 -0
  93. data/test/unit/schemacop/v3/node_test.rb +148 -0
  94. data/test/unit/schemacop/v3/number_node_test.rb +292 -0
  95. data/test/unit/schemacop/v3/object_node_test.rb +170 -0
  96. data/test/unit/schemacop/v3/one_of_node_test.rb +187 -0
  97. data/test/unit/schemacop/v3/reference_node_test.rb +351 -0
  98. data/test/unit/schemacop/v3/string_node_test.rb +334 -0
  99. data/test/unit/schemacop/v3/symbol_node_test.rb +75 -0
  100. metadata +152 -145
  101. data/doc/Schemacop.html +0 -146
  102. data/doc/Schemacop/ArrayValidator.html +0 -329
  103. data/doc/Schemacop/BooleanValidator.html +0 -145
  104. data/doc/Schemacop/Caster.html +0 -379
  105. data/doc/Schemacop/Collector.html +0 -787
  106. data/doc/Schemacop/Dupper.html +0 -214
  107. data/doc/Schemacop/Exceptions.html +0 -115
  108. data/doc/Schemacop/Exceptions/InvalidSchemaError.html +0 -124
  109. data/doc/Schemacop/Exceptions/ValidationError.html +0 -124
  110. data/doc/Schemacop/FieldNode.html +0 -421
  111. data/doc/Schemacop/FloatValidator.html +0 -158
  112. data/doc/Schemacop/HashValidator.html +0 -293
  113. data/doc/Schemacop/IntegerValidator.html +0 -158
  114. data/doc/Schemacop/NilValidator.html +0 -145
  115. data/doc/Schemacop/Node.html +0 -1438
  116. data/doc/Schemacop/NodeResolver.html +0 -258
  117. data/doc/Schemacop/NodeSupportingField.html +0 -590
  118. data/doc/Schemacop/NodeSupportingType.html +0 -612
  119. data/doc/Schemacop/NodeWithBlock.html +0 -289
  120. data/doc/Schemacop/NumberValidator.html +0 -232
  121. data/doc/Schemacop/ObjectValidator.html +0 -298
  122. data/doc/Schemacop/RootNode.html +0 -171
  123. data/doc/Schemacop/Schema.html +0 -699
  124. data/doc/Schemacop/StringValidator.html +0 -295
  125. data/doc/Schemacop/SymbolValidator.html +0 -145
  126. data/doc/ScopedEnv.html +0 -351
  127. data/doc/_index.html +0 -379
  128. data/doc/class_list.html +0 -51
  129. data/doc/css/common.css +0 -1
  130. data/doc/css/full_list.css +0 -58
  131. data/doc/css/style.css +0 -496
  132. data/doc/file.README.html +0 -833
  133. data/doc/file_list.html +0 -56
  134. data/doc/frames.html +0 -17
  135. data/doc/index.html +0 -833
  136. data/doc/inheritance.graphml +0 -524
  137. data/doc/inheritance.pdf +0 -825
  138. data/doc/js/app.js +0 -303
  139. data/doc/js/full_list.js +0 -216
  140. data/doc/js/jquery.js +0 -4
  141. data/doc/method_list.html +0 -587
  142. data/doc/top-level-namespace.html +0 -112
  143. data/lib/schemacop/node.rb +0 -139
  144. data/lib/schemacop/node_supporting_field.rb +0 -58
  145. data/lib/schemacop/root_node.rb +0 -4
  146. data/lib/schemacop/validator/array_validator.rb +0 -30
  147. data/lib/schemacop/validator/float_validator.rb +0 -5
  148. data/lib/schemacop/validator/hash_validator.rb +0 -35
  149. data/lib/schemacop/validator/integer_validator.rb +0 -5
  150. data/lib/schemacop/validator/number_validator.rb +0 -19
  151. data/lib/schemacop/validator/object_validator.rb +0 -27
  152. data/lib/schemacop/validator/string_validator.rb +0 -37
  153. data/test/casting_test.rb +0 -90
  154. data/test/collector_test.rb +0 -45
  155. data/test/custom_check_test.rb +0 -93
  156. data/test/custom_if_test.rb +0 -95
  157. data/test/defaults_test.rb +0 -93
  158. data/test/empty_test.rb +0 -14
  159. data/test/nil_dis_allow_test.rb +0 -41
  160. data/test/node_resolver_test.rb +0 -26
  161. data/test/short_forms_test.rb +0 -349
  162. data/test/test_helper.rb +0 -13
  163. data/test/types_test.rb +0 -84
  164. data/test/validator_array_test.rb +0 -97
  165. data/test/validator_boolean_test.rb +0 -15
  166. data/test/validator_float_test.rb +0 -57
  167. data/test/validator_hash_test.rb +0 -93
  168. data/test/validator_integer_test.rb +0 -46
  169. data/test/validator_nil_test.rb +0 -13
  170. data/test/validator_number_test.rb +0 -60
  171. data/test/validator_object_test.rb +0 -139
  172. data/test/validator_string_test.rb +0 -76
  173. data/test/validator_symbol_test.rb +0 -16
@@ -1,112 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>
7
- Top Level Namespace
8
-
9
- &mdash; Documentation by YARD 0.9.20
10
-
11
- </title>
12
-
13
- <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
-
15
- <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
-
17
- <script type="text/javascript" charset="utf-8">
18
- pathId = "";
19
- relpath = '';
20
- </script>
21
-
22
-
23
- <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
-
25
- <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
-
27
-
28
- </head>
29
- <body>
30
- <div class="nav_wrap">
31
- <iframe id="nav" src="class_list.html?1"></iframe>
32
- <div id="resizer"></div>
33
- </div>
34
-
35
- <div id="main" tabindex="-1">
36
- <div id="header">
37
- <div id="menu">
38
-
39
- <a href="_index.html">Index</a> &raquo;
40
-
41
-
42
- <span class="title">Top Level Namespace</span>
43
-
44
- </div>
45
-
46
- <div id="search">
47
-
48
- <a class="full_list_link" id="class_list_link"
49
- href="class_list.html">
50
-
51
- <svg width="24" height="24">
52
- <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
- <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
- <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
- </svg>
56
- </a>
57
-
58
- </div>
59
- <div class="clear"></div>
60
- </div>
61
-
62
- <div id="content"><h1>Top Level Namespace
63
-
64
-
65
-
66
- </h1>
67
- <div class="box_info">
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
- </div>
80
-
81
- <h2>Defined Under Namespace</h2>
82
- <p class="children">
83
-
84
-
85
- <strong class="modules">Modules:</strong> <span class='object_link'><a href="Schemacop.html" title="Schemacop (module)">Schemacop</a></span>
86
-
87
-
88
-
89
- <strong class="classes">Classes:</strong> <span class='object_link'><a href="ScopedEnv.html" title="ScopedEnv (class)">ScopedEnv</a></span>
90
-
91
-
92
- </p>
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
- </div>
103
-
104
- <div id="footer">
105
- Generated on Wed May 13 10:52:04 2020 by
106
- <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
- 0.9.20 (ruby-2.6.2).
108
- </div>
109
-
110
- </div>
111
- </body>
112
- </html>
@@ -1,139 +0,0 @@
1
- module Schemacop
2
- class Node
3
- attr_reader :options
4
-
5
- class_attribute :allowed_options
6
- self.allowed_options = {}.freeze
7
-
8
- class_attribute :symbols
9
- self.symbols = [].freeze
10
-
11
- class_attribute :klasses
12
- self.klasses = [].freeze
13
-
14
- def self.option(key, default: nil)
15
- self.allowed_options = allowed_options.merge(key => default)
16
- end
17
-
18
- option :if
19
- option :check
20
- option :cast
21
- option :default
22
-
23
- def type_label
24
- str = (symbols.first || 'unknown').to_s
25
- str += '*' if option?(:if)
26
- return str
27
- end
28
-
29
- def self.symbol(symbol)
30
- self.symbols += [symbol]
31
- end
32
-
33
- def self.clear_symbols
34
- self.symbols = [].freeze
35
- end
36
-
37
- def self.klass(klass)
38
- self.klasses += [klass]
39
- end
40
-
41
- def self.clear_klasses
42
- self.klasses = [].freeze
43
- end
44
-
45
- def self.register(symbols: [], klasses: [], clear: true, before: nil)
46
- NodeResolver.register(self, before: before)
47
- symbols = [*symbols]
48
- klasses = [*klasses]
49
- if clear
50
- clear_symbols
51
- clear_klasses
52
- end
53
- symbols.each { |s| symbol s }
54
- klasses.each { |k| klass k }
55
- end
56
-
57
- def self.type_matches?(type)
58
- symbol_matches?(type) || class_matches?(type)
59
- end
60
-
61
- def self.symbol_matches?(type)
62
- return false unless type.is_a?(Symbol)
63
- symbols.include?(type)
64
- end
65
-
66
- def self.class_matches?(type)
67
- return false unless type.is_a?(Class)
68
- klasses.each do |klass|
69
- return true if type <= klass
70
- end
71
- return false
72
- end
73
-
74
- def self.build(options, &block)
75
- new(options, &block)
76
- end
77
-
78
- def initialize(options = {})
79
- # Check and save given options
80
- @options = self.class.allowed_options.merge(options)
81
- if (obsolete_opts = @options.keys - self.class.allowed_options.keys).any?
82
- fail Exceptions::InvalidSchemaError,
83
- "Unrecognized option(s) #{obsolete_opts.inspect} for #{self.class.inspect}, allowed options: #{self.class.allowed_options.keys.inspect}."
84
- end
85
-
86
- if option?(:cast) && self.class.klasses.size > 1
87
- fail Exceptions::InvalidSchemaError,
88
- "Casting is only allowed for single-value datatypes, but type #{self.class.inspect} has classes "\
89
- "#{self.class.klasses.map(&:inspect)}."
90
- end
91
- end
92
-
93
- def option(key)
94
- options[key]
95
- end
96
-
97
- def option?(key)
98
- # rubocop:disable Style/DoubleNegation
99
- !!options[key]
100
- # rubocop:enable Style/DoubleNegation
101
- end
102
-
103
- def exec_block
104
- fail Exceptions::InvalidSchemaError, 'Node does not support block.' if block_given?
105
- end
106
-
107
- def resolve_type_klass(type)
108
- klass = NodeResolver.resolve(type)
109
- unless klass
110
- fail Exceptions::InvalidSchemaError, "No validation class found for type #{type.inspect}."
111
- end
112
- return klass
113
- end
114
-
115
- def validate(data, collector)
116
- validate_custom_check(data, collector)
117
- end
118
-
119
- def type_matches?(data)
120
- self.class.type_matches?(data.class) && type_filter_matches?(data)
121
- end
122
-
123
- def type_filter_matches?(data)
124
- !option?(:if) || option(:if).call(data)
125
- end
126
-
127
- protected
128
-
129
- def validate_custom_check(data, collector)
130
- if option?(:check) && (check_result = option(:check).call(data)) != true
131
- if check_result.is_a?(String)
132
- collector.error "Custom :check failed: #{check_result}."
133
- else
134
- collector.error 'Custom :check failed.'
135
- end
136
- end
137
- end
138
- end
139
- end
@@ -1,58 +0,0 @@
1
- module Schemacop
2
- class NodeSupportingField < NodeWithBlock
3
- block_method :req?
4
- block_method :req!
5
- block_method :req
6
- block_method :opt?
7
- block_method :opt!
8
- block_method :opt
9
-
10
- attr_reader :fields
11
-
12
- def initialize(options = {}, &block)
13
- @fields = {}
14
- super
15
- exec_block(&block)
16
- end
17
-
18
- def req?(*args, &block)
19
- field(*args, required: true, allow_nil: true, &block)
20
- end
21
-
22
- def req!(*args, &block)
23
- field(*args, required: true, allow_nil: false, &block)
24
- end
25
-
26
- alias_method :req, :req!
27
-
28
- def opt?(*args, &block)
29
- field(*args, required: false, allow_nil: true, &block)
30
- end
31
-
32
- def opt!(*args, &block)
33
- field(*args, required: false, allow_nil: false, &block)
34
- end
35
-
36
- alias_method :opt, :opt?
37
-
38
- protected
39
-
40
- def field(*args, required:, allow_nil:, &block)
41
- name = args.shift
42
-
43
- if @fields[name]
44
- @fields[name].type(*args, &block)
45
- else
46
- if args.any?
47
- @fields[name] = FieldNode.new(name, required) do
48
- type(*args, &block)
49
- end
50
- else
51
- @fields[name] = FieldNode.new(name, required, &block)
52
- end
53
- end
54
-
55
- @fields[name].type(:nil) if allow_nil
56
- end
57
- end
58
- end
@@ -1,4 +0,0 @@
1
- module Schemacop
2
- class RootNode < NodeSupportingType
3
- end
4
- end
@@ -1,30 +0,0 @@
1
- module Schemacop
2
- class ArrayValidator < NodeSupportingType
3
- register symbols: :array, klasses: Array
4
-
5
- option :min # Minimal number of elements
6
- option :max # Maximal number of elements
7
- option :nil # Whether to allow nil values
8
-
9
- def initialize(*args)
10
- super
11
- type(:nil) if option(:nil)
12
- end
13
-
14
- def validate(data, collector)
15
- validate_custom_check(data, collector)
16
-
17
- if option?(:min) && data.size < option(:min)
18
- collector.error "Array must have more (>=) than #{option(:min)} elements."
19
- end
20
- if option?(:max) && data.size > option(:max)
21
- collector.error "Array must have less (<=) than #{option(:max)} elements."
22
- end
23
- data.each_with_index do |entry, index|
24
- collector.path("[#{index}]", index, :array) do
25
- validate_types(entry, collector)
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,5 +0,0 @@
1
- module Schemacop
2
- class FloatValidator < NumberValidator
3
- register symbols: :float, klasses: Float, before: NumberValidator
4
- end
5
- end
@@ -1,35 +0,0 @@
1
- module Schemacop
2
- class HashValidator < NodeSupportingField
3
- register symbols: :hash, klasses: Hash
4
-
5
- option :allow_obsolete_keys
6
-
7
- def validate(data, collector)
8
- super
9
-
10
- if data.is_a? ActiveSupport::HashWithIndifferentAccess
11
- allowed_fields = @fields.keys.map { |k| k.is_a?(String) ? k.to_sym : k }
12
- data_keys = data.keys.map { |k| k.is_a?(String) ? k.to_sym : k }
13
-
14
- # If the same key is specified in the schema as string and symbol, we
15
- # definitely expect a Ruby hash and not one with indifferent access
16
- if @fields.keys.length != Set.new(allowed_fields).length
17
- fail Exceptions::ValidationError, 'Hash expected, but got ActiveSupport::HashWithIndifferentAccess.'
18
- end
19
- else
20
- allowed_fields = @fields.keys
21
- data_keys = data.keys
22
- end
23
-
24
- obsolete_keys = data_keys - allowed_fields
25
-
26
- unless option?(:allow_obsolete_keys)
27
- collector.error "Obsolete keys: #{obsolete_keys.inspect}." if obsolete_keys.any?
28
- end
29
-
30
- @fields.values.each do |field|
31
- field.validate(data, collector)
32
- end
33
- end
34
- end
35
- end
@@ -1,5 +0,0 @@
1
- module Schemacop
2
- class IntegerValidator < NumberValidator
3
- register symbols: :integer, klasses: Integer, before: NumberValidator
4
- end
5
- end
@@ -1,19 +0,0 @@
1
- module Schemacop
2
- class NumberValidator < Node
3
- register symbols: :number, klasses: [Integer, Float]
4
-
5
- option :min
6
- option :max
7
-
8
- def validate(data, collector)
9
- super
10
-
11
- if option?(:min) && data < option(:min)
12
- collector.error "Value must be >= #{option(:min)}."
13
- end
14
- if option?(:max) && data > option(:max)
15
- collector.error "Value must be <= #{option(:max)}."
16
- end
17
- end
18
- end
19
- end
@@ -1,27 +0,0 @@
1
- module Schemacop
2
- class ObjectValidator < Node
3
- register symbols: :object, klasses: BasicObject
4
-
5
- option :classes
6
- option :strict
7
-
8
- def type_label
9
- "#{super} (#{classes.join(', ')})"
10
- end
11
-
12
- def type_matches?(data)
13
- if option(:strict).is_a?(FalseClass)
14
- sub_or_class = classes.map { |klass| data.class <= klass }.include?(true)
15
- super && (classes.empty? || sub_or_class) && !data.nil?
16
- else
17
- super && (classes.empty? || classes.include?(data.class)) && !data.nil?
18
- end
19
- end
20
-
21
- private
22
-
23
- def classes
24
- [*option(:classes)]
25
- end
26
- end
27
- end