respect 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 (97) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +289 -0
  3. data/RELATED_WORK.md +40 -0
  4. data/RELEASE_NOTES.md +23 -0
  5. data/Rakefile +31 -0
  6. data/STATUS_MATRIX.html +137 -0
  7. data/lib/respect.rb +231 -0
  8. data/lib/respect/any_schema.rb +22 -0
  9. data/lib/respect/array_def.rb +28 -0
  10. data/lib/respect/array_schema.rb +203 -0
  11. data/lib/respect/boolean_schema.rb +32 -0
  12. data/lib/respect/composite_schema.rb +86 -0
  13. data/lib/respect/core_statements.rb +206 -0
  14. data/lib/respect/datetime_schema.rb +27 -0
  15. data/lib/respect/def_without_name.rb +6 -0
  16. data/lib/respect/divisible_by_validator.rb +20 -0
  17. data/lib/respect/doc_helper.rb +24 -0
  18. data/lib/respect/doc_parser.rb +37 -0
  19. data/lib/respect/dsl_dumper.rb +181 -0
  20. data/lib/respect/equal_to_validator.rb +20 -0
  21. data/lib/respect/fake_name_proxy.rb +116 -0
  22. data/lib/respect/float_schema.rb +27 -0
  23. data/lib/respect/format_validator.rb +136 -0
  24. data/lib/respect/global_def.rb +79 -0
  25. data/lib/respect/greater_than_or_equal_to_validator.rb +19 -0
  26. data/lib/respect/greater_than_validator.rb +19 -0
  27. data/lib/respect/has_constraints.rb +34 -0
  28. data/lib/respect/hash_def.rb +40 -0
  29. data/lib/respect/hash_schema.rb +218 -0
  30. data/lib/respect/in_validator.rb +19 -0
  31. data/lib/respect/integer_schema.rb +27 -0
  32. data/lib/respect/ip_addr_schema.rb +23 -0
  33. data/lib/respect/ipv4_addr_schema.rb +27 -0
  34. data/lib/respect/ipv6_addr_schema.rb +27 -0
  35. data/lib/respect/items_def.rb +21 -0
  36. data/lib/respect/json_schema_html_formatter.rb +143 -0
  37. data/lib/respect/less_than_or_equal_to_validator.rb +19 -0
  38. data/lib/respect/less_than_validator.rb +19 -0
  39. data/lib/respect/match_validator.rb +19 -0
  40. data/lib/respect/max_length_validator.rb +20 -0
  41. data/lib/respect/min_length_validator.rb +20 -0
  42. data/lib/respect/multiple_of_validator.rb +10 -0
  43. data/lib/respect/null_schema.rb +26 -0
  44. data/lib/respect/numeric_schema.rb +33 -0
  45. data/lib/respect/org3_dumper.rb +213 -0
  46. data/lib/respect/regexp_schema.rb +19 -0
  47. data/lib/respect/schema.rb +285 -0
  48. data/lib/respect/schema_def.rb +16 -0
  49. data/lib/respect/string_schema.rb +21 -0
  50. data/lib/respect/unit_test_helper.rb +37 -0
  51. data/lib/respect/uri_schema.rb +23 -0
  52. data/lib/respect/utc_time_schema.rb +17 -0
  53. data/lib/respect/validator.rb +51 -0
  54. data/lib/respect/version.rb +3 -0
  55. data/test/any_schema_test.rb +79 -0
  56. data/test/array_def_test.rb +113 -0
  57. data/test/array_schema_test.rb +487 -0
  58. data/test/boolean_schema_test.rb +89 -0
  59. data/test/composite_schema_test.rb +30 -0
  60. data/test/datetime_schema_test.rb +83 -0
  61. data/test/doc_helper_test.rb +34 -0
  62. data/test/doc_parser_test.rb +109 -0
  63. data/test/dsl_dumper_test.rb +395 -0
  64. data/test/fake_name_proxy_test.rb +138 -0
  65. data/test/float_schema_test.rb +146 -0
  66. data/test/format_validator_test.rb +224 -0
  67. data/test/hash_def_test.rb +126 -0
  68. data/test/hash_schema_test.rb +613 -0
  69. data/test/integer_schema_test.rb +142 -0
  70. data/test/ip_addr_schema_test.rb +78 -0
  71. data/test/ipv4_addr_schema_test.rb +71 -0
  72. data/test/ipv6_addr_schema_test.rb +71 -0
  73. data/test/json_schema_html_formatter_test.rb +214 -0
  74. data/test/null_schema_test.rb +46 -0
  75. data/test/numeric_schema_test.rb +294 -0
  76. data/test/org3_dumper_test.rb +784 -0
  77. data/test/regexp_schema_test.rb +54 -0
  78. data/test/respect_test.rb +108 -0
  79. data/test/schema_def_test.rb +405 -0
  80. data/test/schema_test.rb +290 -0
  81. data/test/string_schema_test.rb +209 -0
  82. data/test/support/circle.rb +11 -0
  83. data/test/support/color.rb +24 -0
  84. data/test/support/point.rb +11 -0
  85. data/test/support/respect/circle_schema.rb +16 -0
  86. data/test/support/respect/color_def.rb +19 -0
  87. data/test/support/respect/color_schema.rb +33 -0
  88. data/test/support/respect/point_schema.rb +19 -0
  89. data/test/support/respect/rgba_schema.rb +20 -0
  90. data/test/support/respect/universal_validator.rb +25 -0
  91. data/test/support/respect/user_macros.rb +12 -0
  92. data/test/support/rgba.rb +11 -0
  93. data/test/test_helper.rb +90 -0
  94. data/test/uri_schema_test.rb +54 -0
  95. data/test/utc_time_schema_test.rb +63 -0
  96. data/test/validator_test.rb +22 -0
  97. metadata +288 -0
@@ -0,0 +1,3 @@
1
+ module Respect
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,79 @@
1
+ require "test_helper"
2
+
3
+ class AnySchemaTest < Test::Unit::TestCase
4
+ def test_any_schema_validate_any_value
5
+ s1 = Respect::AnySchema.new
6
+ s2 = Respect::Schema.define do |s|
7
+ s.any
8
+ end
9
+ s3 = Respect::HashSchema.define do |s|
10
+ s.any "test"
11
+ s.extra do |s|
12
+ s.any "opt"
13
+ end
14
+ end
15
+ [
16
+ [ { "test" => 42 }, true, "hash" ],
17
+ [ [ 42 ], true, "array" ],
18
+ [ 42, true, "integer" ],
19
+ [ 42.5, true, "float" ],
20
+ [ "test", true, "string" ],
21
+ [ false, true, "false boolean" ],
22
+ [ true, true, "true boolean" ],
23
+ [ nil, true, "null" ],
24
+ [ Object.new, false, "unknown type" ],
25
+ ].each do |data|
26
+ assert_schema_validation_is data[1], s1, data[0], data[2]
27
+ assert_schema_validation_is data[1], s2, data[0], data[2]
28
+ assert_schema_validation_is data[1], s3["test"], data[0], data[2]
29
+ assert_schema_validation_is data[1], s3.optional_properties["opt"], data[0], data[2]
30
+ end
31
+ end
32
+
33
+ def test_any_schema_do_not_convert_anything
34
+ [
35
+ [ { "test" => 42 }, "hash" ],
36
+ [ [ 42 ], "array" ],
37
+ [ 42, "integer" ],
38
+ [ 42.5, "float" ],
39
+ [ "test", "string" ],
40
+ [ false, "false boolean" ],
41
+ [ true, "true boolean" ],
42
+ [ nil, "null" ],
43
+ [ Object.new, "unknown type" ],
44
+ ].each do |data|
45
+ s = Respect::AnySchema.new
46
+ assert_nil s.sanitized_object
47
+ if s.validate?(data[0])
48
+ assert_equal data[0], s.sanitized_object, data[1]
49
+ else
50
+ assert_nil s.sanitized_object, data[1]
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_failed_validation_reset_sanitized_object
56
+ s = Respect::AnySchema.define equal_to: 42
57
+ assert_schema_validate(s, 42)
58
+ assert_equal(42, s.sanitized_object)
59
+ assert_schema_invalidate(s, Object.new)
60
+ assert_equal(nil, s.sanitized_object)
61
+ end
62
+
63
+ def test_allow_nil
64
+ s = Respect::AnySchema.new(allow_nil: true)
65
+ assert_schema_validate s, nil
66
+ assert_equal(nil, s.sanitized_object)
67
+ assert_schema_validate s, 42
68
+ assert_equal(42, s.sanitized_object)
69
+ end
70
+
71
+ def test_disallow_nil
72
+ s = Respect::AnySchema.new
73
+ assert !s.allow_nil?
74
+ assert_schema_validate s, nil
75
+ assert_equal(nil, s.sanitized_object)
76
+ assert_schema_validate s, 42
77
+ assert_equal(42, s.sanitized_object)
78
+ end
79
+ end
@@ -0,0 +1,113 @@
1
+ require "test_helper"
2
+
3
+ class ArrayDefTest < Test::Unit::TestCase
4
+
5
+ def test_array_schema_definition_accept_integer
6
+ s = Respect::ArraySchema.define do |s|
7
+ s.integer equal_to: 15
8
+ end
9
+ assert_schema_validate s, ["15"]
10
+ assert_schema_validate s, [15]
11
+ end
12
+
13
+ def test_array_schema_definition_accept_null
14
+ s = Respect::ArraySchema.define do |s|
15
+ s.null
16
+ end
17
+ assert_schema_validate s, ["null"]
18
+ assert_schema_validate s, [nil]
19
+ end
20
+
21
+ def test_array_schema_definition_accept_float
22
+ s = Respect::ArraySchema.define do |s|
23
+ s.float equal_to: 1.5
24
+ end
25
+ assert_schema_validate s, ["1.5"]
26
+ assert_schema_validate s, [1.5]
27
+ end
28
+
29
+ def test_array_schema_definition_accept_boolean
30
+ s = Respect::ArraySchema.define do |s|
31
+ s.boolean equal_to: true
32
+ end
33
+ assert_schema_validate s, ["true"]
34
+ assert_schema_validate s, [true]
35
+ end
36
+
37
+ def test_array_schema_definition_accept_array
38
+ s = Respect::ArraySchema.define do |s|
39
+ s.items do |s|
40
+ s.array
41
+ end
42
+ end
43
+ assert_schema_validate s, [[]]
44
+ assert_schema_validate s, [[]]
45
+ end
46
+
47
+ def test_array_schema_statement_cannot_accept_name_argument
48
+ [
49
+ :hash,
50
+ :integer,
51
+ :string,
52
+ :array,
53
+ :any,
54
+ :boolean,
55
+ :null,
56
+ :float,
57
+ :numeric,
58
+ ].each do |meth_name|
59
+ assert_raise(ArgumentError) do
60
+ Respect::ArraySchema.define do |s|
61
+ s.__send__(meth_name, "prop", {})
62
+ end
63
+ end
64
+ assert_raise(ArgumentError) do
65
+ Respect::ArraySchema.define do |s|
66
+ s.items do |s|
67
+ s.__send__(meth_name, "prop", {})
68
+ end
69
+ end
70
+ end
71
+ assert_raise(ArgumentError) do
72
+ Respect::ArraySchema.define do |s|
73
+ s.extra_items do |s|
74
+ s.__send__(meth_name, "prop", {})
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def test_factor_options_with_with_options
82
+ s = Respect::ArraySchema.define do |s|
83
+ s.items do |s|
84
+ s.doc "integer doc"
85
+ s.integer equal_to: 42
86
+ s.with_options required: false do |s|
87
+ assert_nothing_raised("fake name proxy") do
88
+ s.target
89
+ end
90
+ s.doc "float doc"
91
+ s.float greater_than: 0
92
+ s.doc "numeric doc"
93
+ s.numeric less_than: 0
94
+ end
95
+ end
96
+ end
97
+
98
+ assert_equal(Respect::IntegerSchema, s.items[0].class)
99
+ assert_equal(42, s.items[0].options[:equal_to])
100
+ assert_equal(true, s.items[0].options[:required])
101
+ assert_equal("integer doc", s.items[0].doc)
102
+
103
+ assert_equal(Respect::FloatSchema, s.items[1].class)
104
+ assert_equal(false, s.items[1].options[:required])
105
+ assert_equal(0, s.items[1].options[:greater_than])
106
+ assert_equal("float doc", s.items[1].doc)
107
+
108
+ assert_equal(Respect::NumericSchema, s.items[2].class)
109
+ assert_equal(false, s.items[2].options[:required])
110
+ assert_equal(0, s.items[2].options[:less_than])
111
+ assert_equal("numeric doc", s.items[2].doc)
112
+ end
113
+ end
@@ -0,0 +1,487 @@
1
+ require "test_helper"
2
+
3
+ class ArraySchemaTest < Test::Unit::TestCase
4
+ def test_items_validate
5
+ s = Respect::ArraySchema.define do |s|
6
+ s.integer greater_than: 0
7
+ end
8
+ assert_schema_validate s, [ ], "empty array"
9
+ assert_schema_validate s, [ 42 ], "single item"
10
+ assert_schema_validate s, [ 42, 51 ], "two items"
11
+ assert_schema_validate s, [ 42, 51, 51 ], "several items"
12
+ # Single item's value validation fail.
13
+ assert_raise(Respect::ValidationError) do
14
+ assert s.validate([ 0 ])
15
+ end
16
+ # Single item's key validation fail.
17
+ assert_raise(Respect::ValidationError) do
18
+ assert s.validate([ { "test" => 42 } ])
19
+ end
20
+ # One item in the list is invalid.
21
+ assert_raise(Respect::ValidationError) do
22
+ assert s.validate([ 52, 0, 42 ])
23
+ end
24
+ end
25
+
26
+ def test_items_array_validate
27
+ s = Respect::ArraySchema.define do |s|
28
+ s.array do |s|
29
+ s.integer greater_than: 0
30
+ end
31
+ end
32
+ assert_schema_validate s, [ ], "empty array"
33
+ assert_schema_validate s, [ [42] ], "single nested items"
34
+ assert_schema_invalidate s, [ [42], 51 ], "second item is not array"
35
+ assert_schema_validate s, [ [42, 51] ], "several nested items"
36
+ assert_schema_validate s, [ [42, 51], [62, 64] ], "several, several nested items"
37
+ end
38
+
39
+ def test_items_array_validate_array
40
+ s = Respect::ArraySchema.define do |s|
41
+ s.items do |s|
42
+ s.integer greater_than: 0
43
+ s.integer equal_to: 42
44
+ s.integer equal_to: 51
45
+ end
46
+ end
47
+ assert_schema_invalidate s, [ ], "empty array"
48
+ assert_schema_validate s, [ 1, 42, 51 ], "valid"
49
+ assert_schema_invalidate s, [ 0, 42, 51 ], "first item invalid"
50
+ assert_schema_invalidate s, [ 1, 40, 51 ], "second item invalid"
51
+ assert_schema_invalidate s, [ 1, 42, 50 ], "third item invalid"
52
+ assert_schema_invalidate s, [ 42, 51 ], "not enough items"
53
+ assert_schema_invalidate s, [ 1, 42, 51, 0 ], "too many items"
54
+ end
55
+
56
+ def test_cannot_mix_single_item_and_multiple_items_validation
57
+ assert_raise(Respect::InvalidSchemaError) do
58
+ Respect::ArraySchema.define do |s|
59
+ s.integer greater_than: 0
60
+ s.items do |s|
61
+ s.integer greater_than: 0
62
+ end
63
+ end
64
+ end
65
+ assert_raise(Respect::InvalidSchemaError) do
66
+ Respect::ArraySchema.define do |s|
67
+ s.items do |s|
68
+ s.integer greater_than: 0
69
+ end
70
+ s.integer greater_than: 0
71
+ end
72
+ end
73
+ end
74
+
75
+ def test_cannot_mix_single_item_and_extra_items_validation
76
+ assert_raise(Respect::InvalidSchemaError) do
77
+ Respect::ArraySchema.define do |s|
78
+ s.integer greater_than: 0
79
+ s.extra_items do |s|
80
+ s.integer greater_than: 0
81
+ end
82
+ end
83
+ end
84
+ assert_raise(Respect::InvalidSchemaError) do
85
+ Respect::ArraySchema.define do |s|
86
+ s.extra_items do |s|
87
+ s.integer greater_than: 0
88
+ end
89
+ s.integer greater_than: 0
90
+ end
91
+ end
92
+ end
93
+
94
+ def test_extra_items_validate_array
95
+ s = Respect::ArraySchema.define do |s|
96
+ s.items do |s|
97
+ s.integer greater_than: 0
98
+ s.integer equal_to: 42
99
+ end
100
+ s.extra_items do |s|
101
+ s.integer equal_to: 51
102
+ s.integer equal_to: 64
103
+ end
104
+ end
105
+ assert_schema_invalidate s, [ ], "empty array"
106
+ assert_schema_validate s, [ 1, 42 ], "no extra items"
107
+ assert_schema_validate s, [ 1, 42, 51, 64 ], "extra items"
108
+ assert_schema_validate s, [ 1, 42, 51 ], "missing extra item"
109
+ assert_schema_validate s, [ 1, 42, 51, 64, 80 ], "additional extra item"
110
+ assert_schema_invalidate s, [ 1, 42, 52, 64 ], "first extra item invalid"
111
+ assert_schema_invalidate s, [ 1, 42, 51, 65 ], "second extra item invalid"
112
+ assert_schema_invalidate s, [ 1, 42, 52, 65 ], "all extra item invalid"
113
+ end
114
+
115
+ def test_extra_items_with_no_items_validate_array
116
+ s = Respect::ArraySchema.define do |s|
117
+ s.extra_items do |s|
118
+ s.integer equal_to: 51
119
+ s.integer equal_to: 64
120
+ end
121
+ end
122
+ assert_schema_validate s, [ ], "no extra items"
123
+ assert_schema_validate s, [ 51, 64 ], "extra items"
124
+ assert_schema_validate s, [ 51 ], "missing extra item"
125
+ assert_schema_validate s, [ 51, 64, 80 ], "additional extra item"
126
+ assert_schema_invalidate s, [ 52, 64 ], "first extra item invalid"
127
+ assert_schema_invalidate s, [ 51, 65 ], "second extra item invalid"
128
+ assert_schema_invalidate s, [ 52, 65 ], "all extra item invalid"
129
+ end
130
+
131
+ def test_array_schema_do_not_validate_other_type
132
+ s = Respect::ArraySchema.define do |s|
133
+ s.integer greater_than: 0
134
+ end
135
+ [
136
+ { "test" => 0 },
137
+ 42,
138
+ "test",
139
+ nil,
140
+ ].each do |doc|
141
+ assert_raise(Respect::ValidationError) do
142
+ s.validate(doc)
143
+ end
144
+ end
145
+ end
146
+
147
+ def test_array_min_size_constraint
148
+ s = Respect::ArraySchema.define min_size: 2 do |s|
149
+ s.integer greater_than: 0
150
+ end
151
+ assert_schema_invalidate s, [ ], "empty array"
152
+ assert_schema_invalidate s, [ 1 ], "one item"
153
+ assert_schema_validate s, [ 1, 2 ], "two items"
154
+ assert_schema_validate s, [ 1, 2, 3 ], "three items"
155
+ end
156
+
157
+ def test_array_max_size_constraint
158
+ s = Respect::ArraySchema.define max_size: 2 do |s|
159
+ s.integer greater_than: 0
160
+ end
161
+ assert_schema_validate s, [ ], "empty array"
162
+ assert_schema_validate s, [ 1 ], "one item"
163
+ assert_schema_validate s, [ 1, 2 ], "two items"
164
+ assert_schema_invalidate s, [ 1, 2, 3 ], "three items"
165
+ assert_schema_invalidate s, [ 1, 2, 3, 4 ], "four items"
166
+ end
167
+
168
+ def test_array_unique_constraint
169
+ s = Respect::ArraySchema.define uniq: true do |s|
170
+ s.integer greater_than: 0
171
+ end
172
+ assert_schema_validate s, [ ], "empty array"
173
+ assert_schema_validate s, [ 1 ], "one item"
174
+ assert_schema_validate s, [ 1, 2 ], "two different items"
175
+ assert_schema_invalidate s, [ 1, 2, 1 ], "one duplicated item"
176
+ assert_schema_invalidate s, [ 1, 2, 1, 2 ], "two duplicated items"
177
+ end
178
+
179
+ def test_hash_in_array_validate
180
+ s = Respect::ArraySchema.define do |s|
181
+ s.hash do |s|
182
+ s.numeric "prop", equal_to: 51
183
+ end
184
+ end
185
+ assert_schema_validate s, [ { "prop" => 51 } ]
186
+ assert_schema_invalidate s, [ { "prop" => 42 } ]
187
+ end
188
+
189
+ def test_hash_in_array_in_object_validate
190
+ s = Respect::HashSchema.define do |s|
191
+ s.array "level_1" do |s|
192
+ s.hash do |s|
193
+ s.numeric "level_3", equal_to: 51
194
+ end
195
+ end
196
+ end
197
+ assert_schema_validate s, { "level_1" => [ { "level_3" => 51 } ]}
198
+ assert_schema_invalidate s, { "level_1" => [ { "level_3" => 42 } ]}
199
+ end
200
+
201
+ def test_doc_updated_with_sanitized_value
202
+ s = Respect::ArraySchema.define do |s|
203
+ s.integer
204
+ end
205
+ doc = [ "42", "51", "16" ]
206
+ assert_not_nil s.validate!(doc)
207
+ assert_equal [ 42, 51, 16 ], doc
208
+ end
209
+
210
+ def test_doc_updated_with_sanitized_value_with_custom_type
211
+ s = Respect::HashSchema.define do |s|
212
+ s.rgba "color"
213
+ end
214
+ doc = { "color" => [ "0.0", "0.5", "1.0", "0.2" ] }
215
+ assert s.validate!(doc)
216
+ assert_equal Rgba.new(0.0, 0.5, 1.0, 0.2), doc["color"]
217
+ end
218
+
219
+ def test_recursive_doc_updated_with_sanitized_value
220
+ s = Respect::ArraySchema.define do |s|
221
+ s.array do |s|
222
+ s.integer
223
+ end
224
+ end
225
+ doc = [ [ "42" ], [ "51" ], [ "16" ] ]
226
+ assert_not_nil s.validate!(doc)
227
+ assert_equal [ [ 42 ], [ 51 ], [ 16 ] ], doc
228
+ end
229
+
230
+ def test_multi_items_doc_updated_with_sanitized_value
231
+ s = Respect::ArraySchema.define do |s|
232
+ s.items do |s|
233
+ s.integer
234
+ s.array do |s|
235
+ s.integer
236
+ end
237
+ end
238
+ end
239
+ doc = [ "42", [ "51" ] ]
240
+ assert_not_nil s.validate!(doc)
241
+ assert_equal [ 42, [ 51 ] ], doc
242
+ end
243
+
244
+ def test_only_update_validated_items
245
+ s = Respect::ArraySchema.define do |s|
246
+ s.items do |s|
247
+ s.integer
248
+ end
249
+ s.extra_items do |s|
250
+ s.integer
251
+ end
252
+ end
253
+ doc = [ "42", "51", "64" ]
254
+ assert_not_nil s.validate!(doc)
255
+ assert_equal [ 42, 51, "64" ], doc
256
+ end
257
+
258
+ def test_only_update_recursive_validated_items
259
+ s = Respect::ArraySchema.define do |s|
260
+ s.items do |s|
261
+ s.array do |s|
262
+ s.items do |s|
263
+ s.integer
264
+ end
265
+ s.extra_items do |s|
266
+ s.integer
267
+ end
268
+ end
269
+ end
270
+ end
271
+ doc = [ [ "42", "51", "64" ] ]
272
+ assert_not_nil s.validate!(doc)
273
+ assert_equal [ [ 42, 51, "64" ] ], doc
274
+ end
275
+
276
+ def test_sanitize_simple_document
277
+ s = Respect::ArraySchema.define do |s|
278
+ s.integer
279
+ end
280
+ doc = [ "42", "51" ]
281
+ assert_nil s.sanitized_object
282
+ s.validate(doc)
283
+ assert_equal([ "42", "51" ], doc)
284
+ assert_equal([ 42, 51 ], s.sanitized_object)
285
+ end
286
+
287
+ def test_sanitize_recursive_document
288
+ s = Respect::ArraySchema.define do |s|
289
+ s.array do |s|
290
+ s.integer
291
+ end
292
+ end
293
+ doc = [ [ "42", "51" ], [ "16" ] ]
294
+ assert_nil s.sanitized_object
295
+ s.validate(doc)
296
+ assert_equal([ [ "42", "51" ], [ "16" ] ], doc)
297
+ assert_equal([ [ 42, 51 ], [ 16 ] ], s.sanitized_object)
298
+ end
299
+
300
+ def test_do_not_sanitize_unvalidated_optional_property
301
+ s = Respect::ArraySchema.define do |s|
302
+ s.items do |s|
303
+ s.integer
304
+ end
305
+ s.extra_items do |s|
306
+ s.integer
307
+ end
308
+ end
309
+ doc = [ "42" ]
310
+ assert_nil s.sanitized_object
311
+ s.validate(doc)
312
+ assert_equal([ "42" ], doc)
313
+ assert_equal([ 42 ], s.sanitized_object)
314
+ end
315
+
316
+ def test_sanitize_validated_optional_property
317
+ s = Respect::ArraySchema.define do |s|
318
+ s.items do |s|
319
+ s.integer
320
+ end
321
+ s.extra_items do |s|
322
+ s.integer
323
+ end
324
+ end
325
+ doc = [ "42", "52", "16" ]
326
+ assert_nil s.sanitized_object
327
+ s.validate(doc)
328
+ assert_equal([ "42", "52", "16" ], doc)
329
+ assert_equal([ 42, 52 ], s.sanitized_object)
330
+ end
331
+
332
+ def test_array_schema_merge_default_options
333
+ s = Respect::ArraySchema.new
334
+ assert_equal true, s.options[:required]
335
+ assert_equal false, s.options[:uniq]
336
+ end
337
+
338
+ def test_array_schema_merge_options
339
+ s = Respect::ArraySchema.new(opt: 1, uniq: true)
340
+ assert_equal true, s.options[:required]
341
+ assert_equal true, s.options[:uniq]
342
+ assert_equal 1, s.options[:opt]
343
+ end
344
+
345
+ def test_non_default_options
346
+ s = Respect::ArraySchema.new(opt: 1, uniq: true)
347
+ opts = s.non_default_options
348
+ assert !opts.has_key?(:required)
349
+ assert_equal true, opts[:uniq]
350
+ assert_equal 1, opts[:opt]
351
+ end
352
+
353
+ def test_duplicata_are_equal
354
+ s1 = Respect::ArraySchema.define do |s|
355
+ s.integer
356
+ end
357
+ assert_equal s1, s1.dup
358
+ end
359
+
360
+ def test_schema_differs_from_options
361
+ s1 = Respect::ArraySchema.new(required: true)
362
+ s2 = Respect::ArraySchema.new(required: false)
363
+ assert(s1 != s2)
364
+ end
365
+
366
+ def test_schema_differs_from_doc
367
+ s1 = Respect::Schema.define do |s|
368
+ s.doc "hey"
369
+ s.array
370
+ end
371
+ s2 = Respect::Schema.define do |s|
372
+ s.doc "ho"
373
+ s.array
374
+ end
375
+ assert(s1 != s2)
376
+ end
377
+
378
+ def test_schema_differs_from_item
379
+ s1 = Respect::ArraySchema.new
380
+ s1.item = Respect::IntegerSchema.new
381
+ s2 = Respect::ArraySchema.new
382
+ s2.item = Respect::StringSchema.new
383
+ assert(s1 != s2)
384
+ end
385
+
386
+ def test_schema_differs_from_items
387
+ s1 = Respect::ArraySchema.new
388
+ s1.items = [ Respect::IntegerSchema.new ]
389
+ s2 = Respect::ArraySchema.new
390
+ s2.items = [ Respect::StringSchema.new ]
391
+ assert(s1 != s2)
392
+ end
393
+
394
+ def test_schema_differs_from_extra_items
395
+ s1 = Respect::ArraySchema.new
396
+ s1.extra_items = [ Respect::IntegerSchema.new ]
397
+ s2 = Respect::ArraySchema.new
398
+ s2.extra_items = [ Respect::StringSchema.new ]
399
+ assert(s1 != s2)
400
+ end
401
+
402
+ def test_dup_duplicate_options
403
+ s1 = Respect::ArraySchema.define uniq: true
404
+ s2 = s1.dup
405
+ assert(s2.object_id != s1.object_id)
406
+ assert_equal(true, s2.options[:uniq])
407
+ end
408
+
409
+ def test_dup_dont_duplicate_item
410
+ s1 = Respect::ArraySchema.define do |s|
411
+ s.integer
412
+ end
413
+ s2 = s1.dup
414
+ assert(s2.object_id != s1.object_id)
415
+ assert(s1.item.object_id == s2.item.object_id)
416
+ end
417
+
418
+ def test_dup_duplicate_items
419
+ s1 = Respect::ArraySchema.define do |s|
420
+ s.items do |s|
421
+ s.integer
422
+ s.string
423
+ end
424
+ end
425
+ s2 = s1.dup
426
+ assert(s2.object_id != s1.object_id)
427
+ assert(s1.items.object_id != s2.items.object_id)
428
+ assert(s1.items[0].object_id == s2.items[0].object_id)
429
+ assert(s1.items[1].object_id == s2.items[1].object_id)
430
+ end
431
+
432
+ def test_dup_duplicate_extra_items
433
+ s1 = Respect::ArraySchema.define do |s|
434
+ s.extra_items do |s|
435
+ s.integer
436
+ s.string
437
+ end
438
+ end
439
+ s2 = s1.dup
440
+ assert(s2.object_id != s1.object_id)
441
+ assert(s1.extra_items.object_id != s2.extra_items.object_id)
442
+ assert(s1.extra_items[0].object_id == s2.extra_items[0].object_id)
443
+ assert(s1.extra_items[1].object_id == s2.extra_items[1].object_id)
444
+ end
445
+
446
+ def test_failed_validation_reset_sanitized_object
447
+ s = Respect::ArraySchema.define do |s|
448
+ s.integer equal_to: 42
449
+ end
450
+ assert_schema_validate(s, [42])
451
+ assert_equal([42], s.sanitized_object)
452
+ assert_schema_invalidate(s, [51])
453
+ assert_equal(nil, s.sanitized_object)
454
+ end
455
+
456
+ def test_integer_item_accept_nil
457
+ s = Respect::ArraySchema.define do |s|
458
+ s.integer allow_nil: true
459
+ end
460
+ assert_schema_validate(s, [nil])
461
+ assert_equal([nil], s.sanitized_object)
462
+ assert_schema_validate(s, [42])
463
+ assert_equal([42], s.sanitized_object)
464
+ assert_schema_validate(s, [42, nil, 51])
465
+ assert_equal([42, nil, 51], s.sanitized_object)
466
+ assert_schema_invalidate(s, ["wrong"])
467
+ assert_nil(s.sanitized_object)
468
+ end
469
+
470
+ def test_allow_nil
471
+ s = Respect::ArraySchema.new(allow_nil: true)
472
+ assert_schema_validate s, nil
473
+ assert_equal(nil, s.sanitized_object)
474
+ assert_schema_validate s, []
475
+ assert_equal([], s.sanitized_object)
476
+ end
477
+
478
+ def test_disallow_nil
479
+ s = Respect::ArraySchema.new
480
+ assert !s.allow_nil?
481
+ exception = assert_exception(Respect::ValidationError) { s.validate(nil) }
482
+ assert_match exception.message, /\bArraySchema\b/
483
+ assert_equal(nil, s.sanitized_object)
484
+ assert_schema_validate s, []
485
+ assert_equal([], s.sanitized_object)
486
+ end
487
+ end