schemacop 2.4.7 → 3.0.0.rc0

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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +25 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +8 -0
  6. data/README.md +41 -708
  7. data/README_V2.md +775 -0
  8. data/README_V3.md +683 -0
  9. data/Rakefile +8 -12
  10. data/VERSION +1 -1
  11. data/lib/schemacop.rb +35 -37
  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/{node_supporting_field.rb → v2/node_supporting_field.rb} +8 -10
  26. data/lib/schemacop/{node_supporting_type.rb → v2/node_supporting_type.rb} +6 -3
  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 +219 -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 +217 -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 +214 -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 +199 -0
  86. data/test/unit/schemacop/v3/any_of_node_test.rb +218 -0
  87. data/test/unit/schemacop/v3/array_node_test.rb +805 -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 +775 -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/root_node.rb +0 -4
  145. data/lib/schemacop/validator/array_validator.rb +0 -30
  146. data/lib/schemacop/validator/float_validator.rb +0 -5
  147. data/lib/schemacop/validator/hash_validator.rb +0 -35
  148. data/lib/schemacop/validator/integer_validator.rb +0 -5
  149. data/lib/schemacop/validator/number_validator.rb +0 -19
  150. data/lib/schemacop/validator/object_validator.rb +0 -27
  151. data/lib/schemacop/validator/string_validator.rb +0 -37
  152. data/test/casting_test.rb +0 -118
  153. data/test/collector_test.rb +0 -45
  154. data/test/custom_check_test.rb +0 -93
  155. data/test/custom_if_test.rb +0 -95
  156. data/test/defaults_test.rb +0 -93
  157. data/test/empty_test.rb +0 -14
  158. data/test/nil_dis_allow_test.rb +0 -41
  159. data/test/node_resolver_test.rb +0 -26
  160. data/test/short_forms_test.rb +0 -349
  161. data/test/test_helper.rb +0 -13
  162. data/test/types_test.rb +0 -84
  163. data/test/validator_array_test.rb +0 -97
  164. data/test/validator_boolean_test.rb +0 -15
  165. data/test/validator_float_test.rb +0 -57
  166. data/test/validator_hash_test.rb +0 -93
  167. data/test/validator_integer_test.rb +0 -46
  168. data/test/validator_nil_test.rb +0 -13
  169. data/test/validator_number_test.rb +0 -60
  170. data/test/validator_object_test.rb +0 -139
  171. data/test/validator_string_test.rb +0 -76
  172. data/test/validator_symbol_test.rb +0 -16
@@ -0,0 +1,97 @@
1
+ require 'test_helper'
2
+
3
+ module Schemacop
4
+ module V2
5
+ class CustomIfTest < V2Test
6
+ def test_allowed_subset_only
7
+ s = Schema.new do
8
+ type :integer, if: proc { |data| data.odd? }
9
+ end
10
+
11
+ assert_nothing_raised { s.validate! 5 }
12
+ assert_verr { s.validate! nil }
13
+ assert_verr { s.validate! 4 }
14
+ end
15
+
16
+ def test_if_with_multiple_types
17
+ s = Schema.new do
18
+ type :integer, if: proc { |data| data.odd? }
19
+ type :string
20
+ end
21
+
22
+ assert_nothing_raised { s.validate!(5) }
23
+ assert_nothing_raised { s.validate!('abc') }
24
+ assert_verr { s.validate!(4) }
25
+ end
26
+
27
+ def test_if_with_string
28
+ s = Schema.new do
29
+ req :foo, :string, if: proc { |data| data.start_with?('a') }, min: 3
30
+ req :foo, :string, min: 5
31
+ end
32
+
33
+ assert_nothing_raised { s.validate!(foo: 'abc') }
34
+ assert_nothing_raised { s.validate!(foo: 'bcdef') }
35
+ assert_verr { s.validate!(foo: 'a') }
36
+ assert_verr { s.validate!(foo: 'bcde') }
37
+ end
38
+
39
+ def test_if_with_multiple_types_in_field
40
+ s = Schema.new do
41
+ req :foo, :string, if: proc { |data| data.start_with?('a') }
42
+ req :foo, :integer
43
+ end
44
+
45
+ assert_nothing_raised { s.validate!(foo: 3) }
46
+ assert_nothing_raised { s.validate!(foo: 'abc') }
47
+ assert_verr { s.validate!(foo: 'bcd') }
48
+ assert_verr { s.validate!(foo: true) }
49
+ end
50
+
51
+ def test_if_with_hash_in_array
52
+ s = Schema.new do
53
+ req :user, :array do
54
+ type :hash, if: proc { |data| data[:admin] } do
55
+ req :admin, :boolean
56
+ req :admin_only, :string
57
+ end
58
+ type :hash do
59
+ opt :admin
60
+ req :non_admin_only, :string
61
+ end
62
+ end
63
+ end
64
+
65
+ assert_nothing_raised { s.validate!(user: [{ admin: true, admin_only: 'foo' }, { admin: false, non_admin_only: 'foo' }]) }
66
+ assert_nothing_raised { s.validate!(user: [{ admin: true, admin_only: 'foo' }, { non_admin_only: 'foo' }]) }
67
+ assert_verr { s.validate!(user: [{ admin: false, admin_only: 'foo' }]) }
68
+ assert_verr { s.validate!(user: [{ admin: true, non_admin_only: 'foo' }]) }
69
+ end
70
+
71
+ def test_if_true_or_false
72
+ s = Schema.new do
73
+ req :foo, :integer, if: proc { true }, min: 5
74
+ req :bar, :integer, if: proc { false }, min: 5
75
+ # TODO: It should work without the following line
76
+ req :bar, :integer
77
+ end
78
+
79
+ assert_nothing_raised { s.validate!(foo: 5, bar: 5) }
80
+ assert_nothing_raised { s.validate!(foo: 5, bar: 4) }
81
+ assert_verr { s.validate!(foo: 4, bar: 5) }
82
+ assert_verr { s.validate!(foo: 4, bar: 4) }
83
+ end
84
+
85
+ def test_mixed_req_opt
86
+ s = Schema.new do
87
+ req :foo, :integer, if: proc { |data| !data.nil? }
88
+ opt :foo, :integer
89
+ end
90
+
91
+ assert_nothing_raised { s.validate!(foo: 4) }
92
+ assert_verr { s.validate!({}) }
93
+ assert_verr { s.validate!('something') }
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,95 @@
1
+ require 'test_helper'
2
+
3
+ module Schemacop
4
+ module V2
5
+ class DefaultsTest < V2Test
6
+ def test_basic
7
+ s = Schema.new :integer, default: 42
8
+
9
+ input = nil
10
+ output = s.validate!(input)
11
+
12
+ assert_equal(42, output)
13
+ end
14
+
15
+ def test_hash
16
+ s = Schema.new do
17
+ opt :foo, :string, default: 'bar'
18
+ end
19
+
20
+ input = { foo: nil }
21
+ output = s.validate!(input)
22
+ assert_equal({ foo: 'bar' }, output)
23
+ end
24
+
25
+ def test_missing_hash_key
26
+ s = Schema.new do
27
+ opt :foo, :string, default: 'bar'
28
+ end
29
+
30
+ input = {}
31
+ output = s.validate!(input)
32
+ assert_equal({ foo: 'bar' }, output)
33
+ end
34
+
35
+ def test_entire_hash
36
+ s = Schema.new do
37
+ opt :foo, :hash, default: { name: { first: 'Foo', last: 'Bar' } } do
38
+ req :name do
39
+ req :first
40
+ req :last
41
+ end
42
+ end
43
+ end
44
+
45
+ input = {}
46
+ output = s.validate!(input)
47
+ assert_equal({ foo: { name: { first: 'Foo', last: 'Bar' } } }, output)
48
+ end
49
+
50
+ def test_entire_array
51
+ s = Schema.new do
52
+ opt :foo, :array, default: [{ bar: 42 }] do
53
+ req :bar
54
+ end
55
+ end
56
+
57
+ input = {}
58
+ output = s.validate!(input)
59
+ assert_equal({ foo: [{ bar: 42 }] }, output)
60
+ end
61
+
62
+ def test_proc
63
+ s = Schema.new do
64
+ opt :year, :integer, default: -> { Time.now.year }
65
+ end
66
+
67
+ input = {}
68
+ output = s.validate!(input)
69
+ assert_equal({ year: Time.now.year }, output)
70
+ end
71
+
72
+ def test_nested_proc
73
+ myproc = proc { 42 }
74
+
75
+ s = Schema.new do
76
+ opt :myproc, Proc, default: -> { myproc }
77
+ end
78
+
79
+ input = {}
80
+ output = s.validate!(input)
81
+ assert_equal({ myproc: myproc }, output)
82
+ end
83
+
84
+ def test_invalid_default
85
+ s = Schema.new :integer, default: '42'
86
+
87
+ input = nil
88
+
89
+ assert_verr do
90
+ s.validate!(input)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ module Schemacop
4
+ module V2
5
+ class EmptyHashTest < V2Test
6
+ def test_empty_hash
7
+ schema = Schema.new do
8
+ type Hash
9
+ end
10
+
11
+ assert_nothing_raised { schema.validate!({}) }
12
+ assert_verr { schema.validate!(foo: :bar) }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ # Note: A test for req and opt is part of validator_hash_test.rb
4
+
5
+ module Schemacop
6
+ module V2
7
+ class NilDisAllowTest < V2Test
8
+ def test_req
9
+ s = Schema.new do
10
+ req? :o do
11
+ type :boolean
12
+ end
13
+
14
+ req :r do
15
+ type :boolean
16
+ end
17
+ end
18
+ assert_nothing_raised { s.validate!(o: nil, r: false) }
19
+ assert_nothing_raised { s.validate!(o: false, r: false) }
20
+ assert_verr { s.validate!(o: true, r: nil) }
21
+ assert_verr { s.validate!(o: nil, r: nil) }
22
+ assert_verr { s.validate!(r: true) }
23
+ end
24
+
25
+ def test_opt
26
+ s = Schema.new do
27
+ opt :o do
28
+ type :boolean
29
+ end
30
+ opt! :r do
31
+ type :boolean
32
+ end
33
+ end
34
+ assert_nothing_raised { s.validate!(o: nil, r: false) }
35
+ assert_nothing_raised { s.validate!(o: false, r: false) }
36
+ assert_nothing_raised { s.validate!(r: true) }
37
+ assert_nothing_raised { s.validate!({}) }
38
+ assert_verr { s.validate!(o: true, r: nil) }
39
+ assert_verr { s.validate!(o: nil, r: nil) }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ module Schemacop
4
+ module V2
5
+ class NodeResolverTest < V2Test
6
+ class ClassA; end
7
+ class ClassB; end
8
+ class ClassC; end
9
+ class ClassD; end
10
+
11
+ def test_insert_before
12
+ prev_node_classes = NodeResolver.node_classes
13
+
14
+ NodeResolver.node_classes = []
15
+
16
+ NodeResolver.register(ClassA)
17
+ NodeResolver.register(ClassB)
18
+ NodeResolver.register(ClassC)
19
+ NodeResolver.register(ClassD, before: ClassB)
20
+
21
+ assert_equal [ClassA, ClassD, ClassB, ClassC],
22
+ NodeResolver.node_classes
23
+ ensure
24
+ NodeResolver.node_classes = prev_node_classes
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,351 @@
1
+ require 'test_helper'
2
+
3
+ module Schemacop
4
+ module V2
5
+ class ShortFormsTest < V2Test
6
+ class User; end
7
+ class Group; end
8
+
9
+ def test_untyped
10
+ s = Schema.new do
11
+ req :foo
12
+ end
13
+
14
+ assert_nothing_raised { s.validate!(foo: 3) }
15
+ assert_nothing_raised { s.validate!(foo: '42') }
16
+ assert_nothing_raised { s.validate!(foo: Object.new) }
17
+ assert_verr { s.validate!(foo: nil) }
18
+ end
19
+
20
+ def test_constructor_defaults_to_hash
21
+ s = Schema.new do
22
+ req! :r do
23
+ type :integer
24
+ end
25
+ opt? :o do
26
+ type :integer
27
+ end
28
+ end
29
+
30
+ assert_nothing_raised { s.validate!(r: 3) }
31
+ assert_nothing_raised { s.validate!(r: 3, o: 1) }
32
+ assert_verr { s.validate!(o: 1) }
33
+ assert_verr { s.validate!(1) }
34
+ assert_verr { s.validate!(r: 3, n: 5) }
35
+ end
36
+
37
+ def test_field_defaults_to_any
38
+ s = Schema.new do
39
+ type :hash do
40
+ req :r
41
+ opt :o
42
+ end
43
+ end
44
+
45
+ assert_nothing_raised { s.validate!(r: 3) }
46
+ assert_nothing_raised { s.validate!(r: 'asd', o: self) }
47
+ assert_verr { s.validate!(o: -5.3) }
48
+ assert_verr { s.validate!(Class) }
49
+ assert_verr { s.validate!(r: s, n: true) }
50
+ end
51
+
52
+ def test_inline_type_with_attrs_in_hash
53
+ s = Schema.new do
54
+ type :hash do
55
+ req :i, :integer, min: 5
56
+ opt :f, :float, min: 2.3, max: 3
57
+ end
58
+ end
59
+
60
+ assert_nothing_raised { s.validate!(i: 5) }
61
+ assert_nothing_raised { s.validate!(i: 5, f: 2.3) }
62
+ assert_verr { s.validate!(i: 4, f: 2.3) }
63
+ assert_verr { s.validate!(i: 5, f: 2.2) }
64
+ assert_verr { s.validate!(i: 5, f: 3.4) }
65
+ assert_verr { s.validate!(i: 5.3) }
66
+ assert_verr { s.validate!(j: 2.3) }
67
+ assert_verr { s.validate!({}) }
68
+ end
69
+
70
+ def test_inline_type_in_constructor
71
+ s = Schema.new :integer, min: 2, max: 4
72
+ assert_nothing_raised { s.validate!(3) }
73
+ assert_verr { s.validate!(5) }
74
+ assert_verr { s.validate!(1) }
75
+ end
76
+
77
+ def test_mixed_field_and_type_attrs
78
+ s = Schema.new do
79
+ req? :nilbool, :boolean
80
+ req? :nilint, :integer, min: 2, max: 3
81
+ opt! :optint, :integer, min: 2, max: 3
82
+ end
83
+
84
+ assert_nothing_raised { s.validate!(nilbool: nil, nilint: nil) }
85
+ assert_nothing_raised { s.validate!(nilbool: false, nilint: 2) }
86
+ assert_nothing_raised { s.validate!(nilbool: false, nilint: 3, optint: 2) }
87
+ assert_verr { s.validate!(nilbool: false, nilint: 2, optint: nil) }
88
+ assert_verr { s.validate!(nilbool: false, nilint: 2, optint: 4) }
89
+ assert_verr { s.validate!(nilbool: false, nilint: -5, optint: 2) }
90
+ end
91
+
92
+ def test_array_shortform_simple
93
+ s = Schema.new do
94
+ type(:array, :string)
95
+ end
96
+ assert_nothing_raised { s.validate!(%w[a b]) }
97
+ end
98
+
99
+ # TODO: Get the exception message into the assertion
100
+ def test_array_shortform_invalid
101
+ assert_raises Exceptions::InvalidSchemaError do
102
+ Schema.new do
103
+ type(:array, %i[array integer], min: 2)
104
+ end
105
+ end
106
+ end
107
+
108
+ def test_array_shortform_advanced1
109
+ s = Schema.new do
110
+ type(:array, %i[array integer])
111
+ end
112
+ assert_nothing_raised { s.validate! [[], 3] }
113
+ assert_nothing_raised { s.validate! [[:a, 9], 3] }
114
+ assert_nothing_raised { s.validate! [[]] }
115
+ assert_nothing_raised { s.validate! [3] }
116
+ assert_verr { s.validate! [[], 'string'] }
117
+ assert_verr { s.validate! [3, 'string'] }
118
+ assert_verr { s.validate! ['string'] }
119
+ end
120
+
121
+ def test_array_shortform_advanced2
122
+ assert_raises Exceptions::InvalidSchemaError, 'No validation class found for type [:array, :integer].' do
123
+ Schema.new do
124
+ type([:array, %i[array integer], :boolean])
125
+ end
126
+ end
127
+ end
128
+
129
+ # For explicit form test see types_test.rb
130
+ def test_array_subtype_shortform
131
+ s = Schema.new do
132
+ type :array, :integer
133
+ end
134
+ assert_nothing_raised { s.validate! [5] }
135
+ assert_verr { s.validate! [nil] }
136
+ assert_verr { s.validate! ['a'] }
137
+ assert_verr { s.validate! [5, 'a'] }
138
+ assert_verr { s.validate! [5, nil] }
139
+ end
140
+
141
+ def test_array_subsubtype_shortform
142
+ s = Schema.new do
143
+ type :array, :array, :integer
144
+ end
145
+ assert_nothing_raised { s.validate! [[5]] }
146
+ assert_verr { s.validate! [5] }
147
+ assert_verr { s.validate! [[nil]] }
148
+ assert_verr { s.validate! [['a']] }
149
+ assert_verr { s.validate! [[5, 'a']] }
150
+ assert_verr { s.validate! [[5, nil]] }
151
+ end
152
+
153
+ def test_wild_mix_should_pass
154
+ s = Schema.new do
155
+ req :foo do
156
+ req? :bar, :object, classes: NilClass
157
+ end
158
+ req :name, :integer, min: 5, max: 7
159
+ req :id, %i[integer string]
160
+ req :callback, :symbol
161
+ req :attrs do
162
+ req :color do
163
+ type :integer
164
+ end
165
+ end
166
+ req :colors, :array, %i[string integer]
167
+ req :cars, :array, :hash do
168
+ req? :years, :array, :integer
169
+ req! :make, :string
170
+ req! :ps, :integer
171
+ req? :electric, :boolean
172
+ end
173
+ end
174
+
175
+ assert_nothing_raised do
176
+ s.validate!(
177
+ name: 6,
178
+ foo: { bar: nil },
179
+ attrs: { color: 5 },
180
+ id: 'hallo',
181
+ callback: :funky_function,
182
+ colors: [5, 'sdf'],
183
+ cars: [
184
+ {
185
+ make: 'Tesla',
186
+ ps: 5,
187
+ electric: nil,
188
+ years: [1993, 1990]
189
+ }
190
+ ]
191
+ )
192
+ end
193
+ end
194
+
195
+ def test_super_deep_wild_should_pass
196
+ s = Schema.new do
197
+ type :hash do
198
+ opt? :bla do
199
+ type :string
200
+ end
201
+ req :id do
202
+ type :string
203
+ end
204
+ req? :friends do
205
+ type :array do
206
+ type :string, min: 3, max: 6
207
+ type :boolean
208
+ type :hash do
209
+ req :rod do
210
+ type :hash do
211
+ req :fritz do
212
+ type :array, min: 2 do
213
+ type :array do
214
+ type :integer, min: 1
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ type :integer, min: 3
225
+ end
226
+
227
+ assert_nothing_raised do
228
+ s.validate!(
229
+ id: 'meine ID',
230
+ friends: [
231
+ 'Rodney',
232
+ true,
233
+ false,
234
+ {
235
+ rod: {
236
+ fritz:
237
+ [
238
+ [1],
239
+ [3]
240
+ ]
241
+ }
242
+ }
243
+ ]
244
+ )
245
+ end
246
+ assert_nothing_raised { s.validate!(id: 'my ID', friends: nil) }
247
+ assert_nothing_raised { s.validate!(3) }
248
+ end
249
+
250
+ def test_example_from_readme
251
+ schema = Schema.new do
252
+ req :naming, :hash do
253
+ opt :first_name, :string
254
+ req :last_name, :string
255
+ end
256
+ opt! :age, :integer, min: 18
257
+ req? :password do
258
+ type :string, check: proc { |pw| pw.include?('*') }
259
+ type :integer
260
+ end
261
+ end
262
+
263
+ assert_nothing_raised do
264
+ schema.validate!(
265
+ naming: { first_name: 'John',
266
+ last_name: 'Doe' },
267
+ age: 34,
268
+ password: 'my*pass'
269
+ )
270
+ end
271
+
272
+ assert_verr do
273
+ schema.validate!(
274
+ naming: { first_name: 'John',
275
+ last_name: 'Doe' },
276
+ age: 12,
277
+ password: 'my*pass'
278
+ )
279
+ end
280
+
281
+ assert_verr do
282
+ schema.validate!(
283
+ naming: { first_name: 'John',
284
+ last_name: 'Doe' },
285
+ age: 12,
286
+ password: 'mypass'
287
+ )
288
+ end
289
+
290
+ schema2 = Schema.new do
291
+ req :description,
292
+ :string,
293
+ if: proc { |str| str.start_with?('Abstract: ') },
294
+ max: 35,
295
+ check: proc { |str| !str.end_with?('.') }
296
+ req :description, :string, min: 35
297
+ end
298
+
299
+ assert_nothing_raised { schema2.validate!(description: 'Abstract: a short description') }
300
+ assert_nothing_raised { schema2.validate!(description: 'Since this is no abstract, we expect it to be longer.') }
301
+ assert_verr { schema2.validate!(description: 'Abstract: A short description.') }
302
+ assert_verr { schema2.validate!(description: 'Abstract: This is gonna be way way too long for an abstract.') }
303
+ assert_verr { schema2.validate!(description: 'This is too short.') }
304
+ end
305
+
306
+ def test_one_line_subtype_with_options
307
+ s = Schema.new do
308
+ type :array, :integer, min: 3
309
+ end
310
+ assert_nothing_raised { s.validate!([3]) }
311
+ assert_nothing_raised { s.validate!([3, 4, 5]) }
312
+ assert_verr { s.validate!([3, 2]) }
313
+ assert_verr { s.validate!([5, 'string']) }
314
+ end
315
+
316
+ def test_one_line_array_schema
317
+ s = Schema.new :array, :integer, min: 3
318
+ assert_nothing_raised { s.validate!([3]) }
319
+ assert_nothing_raised { s.validate!([3, 4, 5]) }
320
+ assert_verr { s.validate!([3, 2]) }
321
+ assert_verr { s.validate!([5, 'string']) }
322
+ end
323
+
324
+ def test_implicit_hash
325
+ s = Schema.new do
326
+ req :bar
327
+ end
328
+ assert_nothing_raised { s.validate!(bar: 2) }
329
+ assert_verr { s.validate!(foo: 2) }
330
+ assert_verr { s.validate!([2]) }
331
+ end
332
+
333
+ def test_one_line_string_schema
334
+ s = Schema.new :string, min: 4
335
+ assert_nothing_raised { s.validate!('1234') }
336
+ assert_verr { s.validate!('123') }
337
+ assert_verr { s.validate!(string: '1234') }
338
+ end
339
+
340
+ def test_inline_objects
341
+ s = Schema.new do
342
+ req :user, User
343
+ req :group, Group
344
+ end
345
+
346
+ assert_nothing_raised { s.validate!(user: User.new, group: Group.new) }
347
+ assert_verr { s.validate!(user: Group.new, group: User.new) }
348
+ end
349
+ end
350
+ end
351
+ end