schemacop 2.4.3 → 3.0.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) 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 +26 -0
  6. data/README.md +41 -692
  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 -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} +5 -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} +12 -9
  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 -143
  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 -289
  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 -818
  133. data/doc/file_list.html +0 -56
  134. data/doc/frames.html +0 -17
  135. data/doc/index.html +0 -818
  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 -31
  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 -90
  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 -71
  157. data/test/nil_dis_allow_test.rb +0 -41
  158. data/test/node_resolver_test.rb +0 -26
  159. data/test/short_forms_test.rb +0 -349
  160. data/test/test_helper.rb +0 -13
  161. data/test/types_test.rb +0 -84
  162. data/test/validator_array_test.rb +0 -97
  163. data/test/validator_boolean_test.rb +0 -15
  164. data/test/validator_float_test.rb +0 -57
  165. data/test/validator_hash_test.rb +0 -71
  166. data/test/validator_integer_test.rb +0 -46
  167. data/test/validator_nil_test.rb +0 -13
  168. data/test/validator_number_test.rb +0 -60
  169. data/test/validator_object_test.rb +0 -139
  170. data/test/validator_string_test.rb +0 -76
  171. 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