Mercurial > hgrepos > Python > libs > data-schema
comparison tests/test_schema.py @ 5:84dfd1a94926
Add the existing implementation.
All tests work.
The documentation as text file is included also.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 06 Jul 2023 23:41:41 +0200 |
| parents | |
| children | 940676a0de84 |
comparison
equal
deleted
inserted
replaced
| 4:d715f0c13c60 | 5:84dfd1a94926 |
|---|---|
| 1 | |
| 2 import copy | |
| 3 import datetime | |
| 4 import re | |
| 5 import unittest | |
| 6 | |
| 7 import _config | |
| 8 | |
| 9 import configmix.yaml | |
| 10 | |
| 11 import data_schema | |
| 12 import data_schema.util | |
| 13 | |
| 14 | |
| 15 TYPE_RE = type(re.compile(r"\A.+\Z")) | |
| 16 | |
| 17 | |
| 18 def _test_generic_validator_for_yaml(obj, schema, context): | |
| 19 """Callback for loading test1.schema.yml: Always successful""" | |
| 20 yield from () | |
| 21 | |
| 22 | |
| 23 class YAML(unittest.TestCase): | |
| 24 | |
| 25 """Tests to load Python objects from YAML with complex Python-specific | |
| 26 tags. | |
| 27 | |
| 28 .. seealso:: https://pyyaml.org/wiki/PyYAMLDocumentation | |
| 29 | |
| 30 """ | |
| 31 | |
| 32 def test_load_python_name(self): | |
| 33 y = configmix.yaml.load("key: !!python/name:data_schema.validate") | |
| 34 self.assertTrue(callable(y["key"])) | |
| 35 | |
| 36 def test_load_re(self): | |
| 37 y = configmix.yaml.load("key: !!python/object/apply:re.compile\n - '^[0-9]+$'") | |
| 38 self.assertTrue(isinstance(y["key"], TYPE_RE)) | |
| 39 | |
| 40 | |
| 41 class SchemaInYAML(unittest.TestCase): | |
| 42 def test_file(self): | |
| 43 with data_schema.util.get_data_stream( | |
| 44 _config.FILEURI_PREFIX + "test1.schema.yml", | |
| 45 basedir=_config.config.getvar_s("projectdir")) as f: | |
| 46 schema = data_schema._Schema( | |
| 47 None, True, configmix.yaml.load(f)) | |
| 48 | |
| 49 def test_data(self): | |
| 50 with data_schema.util.get_data_stream( | |
| 51 "data:testschematalib:test2.schema.yml") as f: | |
| 52 schema = data_schema._Schema( | |
| 53 None, True, configmix.yaml.load(f)) | |
| 54 | |
| 55 | |
| 56 class SchemaCheck(unittest.TestCase): | |
| 57 | |
| 58 def test_root_creation(self): | |
| 59 schema = data_schema._Schema(None, True) | |
| 60 self.assertIsInstance(schema, dict) | |
| 61 self.assertEqual(0, len(schema)) | |
| 62 self.assertFalse(schema) | |
| 63 | |
| 64 def test_root_creation_wrong(self): | |
| 65 self.assertRaises( | |
| 66 ValueError, | |
| 67 data_schema._Schema, | |
| 68 None, | |
| 69 False) | |
| 70 | |
| 71 def test_root_properties(self): | |
| 72 schema = data_schema._Schema(None, True) | |
| 73 self.assertIsNone(schema.parent) | |
| 74 self.assertIs(schema, schema.ROOT) | |
| 75 self.assertTrue(schema.is_sub_root) | |
| 76 self.assertIs(schema, schema.SELF) | |
| 77 | |
| 78 def test_dict_len_bool(self): | |
| 79 schema = data_schema._Schema(None, True, a=1, b=2) | |
| 80 self.assertTrue(schema) | |
| 81 self.assertEqual(2, len(schema)) | |
| 82 | |
| 83 def test_equality(self): | |
| 84 schema1 = data_schema._Schema(None, True, a=1, b=2) | |
| 85 schema2 = data_schema._Schema(None, True, b=2, a=1) | |
| 86 self.assertEqual(schema1, schema2) | |
| 87 self.assertIsNot(schema1, schema2) | |
| 88 | |
| 89 def test_copy(self): | |
| 90 schema = data_schema._Schema(None, True, type="str") | |
| 91 schema2 = schema.copy() | |
| 92 self.assertEqual(schema, schema2) | |
| 93 | |
| 94 def test_deepcopy(self): | |
| 95 d1 = {} | |
| 96 schema = data_schema._Schema(None, True, type="str", b=d1) | |
| 97 schema2 = copy.deepcopy(schema) | |
| 98 self.assertEqual(schema, schema2) | |
| 99 self.assertIs(schema["b"], d1) | |
| 100 self.assertIsNot(schema2["b"], d1) | |
| 101 self.assertIs(schema.parent, schema2.parent) | |
| 102 self.assertIs(schema.is_sub_root, schema2.is_sub_root) | |
| 103 | |
| 104 def test_nested_copy(self): | |
| 105 d1 = {} | |
| 106 d2 = {} | |
| 107 root_schema = data_schema._Schema(None, True, type="str", b=d1) | |
| 108 child_schema = data_schema._Schema(root_schema, True, type="bool", b=d2) | |
| 109 copied_child = child_schema.copy() | |
| 110 self.assertIs(copied_child.ROOT, root_schema) | |
| 111 self.assertIs(copied_child.SELF, copied_child) | |
| 112 self.assertIsNot(copied_child.SELF, root_schema) | |
| 113 self.assertEqual(child_schema, copied_child) | |
| 114 self.assertIs(copied_child["b"], d2) | |
| 115 | |
| 116 def test_nested_deepcopy(self): | |
| 117 d1 = {} | |
| 118 d2 = {} | |
| 119 root_schema = data_schema._Schema(None, True, type="str", b=d1) | |
| 120 child_schema = data_schema._Schema(root_schema, True, type="bool", b=d2) | |
| 121 copied_child = copy.deepcopy(child_schema) | |
| 122 self.assertIs(copied_child.ROOT, root_schema) | |
| 123 self.assertIs(copied_child.SELF, copied_child) | |
| 124 self.assertEqual(child_schema, copied_child) | |
| 125 self.assertIsNot(copied_child["b"], d2) | |
| 126 self.assertNotEqual(root_schema, child_schema) | |
| 127 | |
| 128 | |
| 129 class ContextCheck(unittest.TestCase): | |
| 130 | |
| 131 def test_root_without_settings(self): | |
| 132 self.assertRaises(TypeError, | |
| 133 data_schema.Context, | |
| 134 None, | |
| 135 root_object=object(), | |
| 136 schema=dict()) | |
| 137 | |
| 138 def test_root_context(self): | |
| 139 obj = object() | |
| 140 schema = object() | |
| 141 settings = data_schema.ValidationSettings( | |
| 142 skip_keys=[], break_on_keynames_problems=True) | |
| 143 ctx = data_schema.Context( | |
| 144 None, root_object=obj, root_schema=schema, settings=settings) | |
| 145 self.assertEqual("<ROOT>", str(ctx)) | |
| 146 self.assertTrue(ctx.root_object is obj) | |
| 147 self.assertTrue(ctx.root_schema is schema) | |
| 148 self.assertTrue(ctx.settings is settings) | |
| 149 | |
| 150 def test_parent_of_root_context(self): | |
| 151 obj = object() | |
| 152 schema = object() | |
| 153 settings = data_schema.ValidationSettings( | |
| 154 skip_keys=[], break_on_keynames_problems=True) | |
| 155 ctx = data_schema.Context( | |
| 156 None, root_object=obj, root_schema=schema, settings=settings) | |
| 157 self.assertTrue(ctx.is_root) | |
| 158 self.assertIsNone(ctx.parent) | |
| 159 try: | |
| 160 ctx.safe_parent | |
| 161 except TypeError: | |
| 162 pass | |
| 163 else: | |
| 164 self.fail( | |
| 165 "Context.safe_parent was expected to raise for a root context") | |
| 166 | |
| 167 def test_root_context_init_root_empty(self): | |
| 168 settings = data_schema.ValidationSettings( | |
| 169 skip_keys=[], break_on_keynames_problems=True) | |
| 170 self.assertRaises( | |
| 171 TypeError, | |
| 172 data_schema.Context, None, key="key", settings=settings) | |
| 173 self.assertRaises( | |
| 174 TypeError, | |
| 175 data_schema.Context, None, index="key", settings=settings) | |
| 176 | |
| 177 def test_root_context_init_only_one_of_key_index(self): | |
| 178 settings = data_schema.ValidationSettings( | |
| 179 skip_keys=[], break_on_keynames_problems=True) | |
| 180 root = data_schema.Context(None, settings=settings) | |
| 181 self.assertRaises( | |
| 182 ValueError, | |
| 183 data_schema.Context, root, key="key", index="index") | |
| 184 | |
| 185 def test_root_context_init_exactly_one(self): | |
| 186 settings = data_schema.ValidationSettings( | |
| 187 skip_keys=[], break_on_keynames_problems=True) | |
| 188 root = data_schema.Context(None, settings=settings) | |
| 189 self.assertRaises(TypeError, data_schema.Context, root) | |
| 190 | |
| 191 def test_nonroot_rootobj_schema(self): | |
| 192 settings = data_schema.ValidationSettings( | |
| 193 skip_keys=[], break_on_keynames_problems=True) | |
| 194 obj = object() | |
| 195 schema = object() | |
| 196 ctx = data_schema.Context( | |
| 197 None, root_object=obj, root_schema=schema, settings=settings) | |
| 198 self.assertEqual("<ROOT>", str(ctx)) | |
| 199 self.assertTrue(ctx.root_object is obj) | |
| 200 self.assertTrue(ctx.root_schema is schema) | |
| 201 self.assertTrue(ctx.settings is settings) | |
| 202 self.assertRaises(TypeError, data_schema.Context, ctx, index=0, | |
| 203 root_object=object()) | |
| 204 self.assertRaises(TypeError, data_schema.Context, ctx, index=0, | |
| 205 root_schema=object()) | |
| 206 | |
| 207 def test_str(self): | |
| 208 settings = data_schema.ValidationSettings( | |
| 209 skip_keys=[], break_on_keynames_problems=True) | |
| 210 root = data_schema.Context(None, settings=settings) | |
| 211 ctx1 = data_schema.Context(root, key="key1") | |
| 212 ctx2 = data_schema.Context(ctx1, index=2) | |
| 213 ctx3 = data_schema.Context(ctx2, key="key3") | |
| 214 self.assertEqual("key1 / INDEX:2 / key3", str(ctx3)) | |
| 215 | |
| 216 def test_repr(self): | |
| 217 settings = data_schema.ValidationSettings( | |
| 218 skip_keys=[], break_on_keynames_problems=True) | |
| 219 root = data_schema.Context(None, settings=settings) | |
| 220 ctx1 = data_schema.Context(root, key="key1") | |
| 221 ctx2 = data_schema.Context(ctx1, index=2) | |
| 222 ctx3 = data_schema.Context(ctx2, key="key3") | |
| 223 self.assertEqual("<Context path=`key1 / INDEX:2 / key3'>", repr(ctx3)) | |
| 224 | |
| 225 def test_root(self): | |
| 226 settings = data_schema.ValidationSettings( | |
| 227 skip_keys=[], break_on_keynames_problems=True) | |
| 228 root = data_schema.Context(None, settings=settings) | |
| 229 self.assertTrue(root.is_root) | |
| 230 self.assertTrue(root is root.root) | |
| 231 self.assertTrue(root.settings is settings) | |
| 232 ctx1 = data_schema.Context(root, key="key1") | |
| 233 self.assertFalse(ctx1.is_root) | |
| 234 self.assertTrue(ctx1.root is root) | |
| 235 self.assertTrue(ctx1.settings is settings) | |
| 236 ctx2 = data_schema.Context(ctx1, index=2) | |
| 237 self.assertTrue(ctx2.settings is settings) | |
| 238 ctx3 = data_schema.Context(ctx2, key="key3") | |
| 239 self.assertEqual("key1 / INDEX:2 / key3", str(ctx3)) | |
| 240 self.assertFalse(ctx3.is_root) | |
| 241 self.assertTrue(ctx3.root is root) | |
| 242 self.assertTrue(ctx3.settings is settings) | |
| 243 | |
| 244 def test_extra_settings_in_between(self): | |
| 245 settings = data_schema.ValidationSettings( | |
| 246 skip_keys=[], break_on_keynames_problems=True) | |
| 247 settings2 = data_schema.ValidationSettings( | |
| 248 skip_keys=[], break_on_keynames_problems=True) | |
| 249 root = data_schema.Context(None, settings=settings) | |
| 250 self.assertTrue(root.is_root) | |
| 251 self.assertTrue(root is root.root) | |
| 252 self.assertTrue(root.settings is settings) | |
| 253 ctx1 = data_schema.Context(root, key="key1") | |
| 254 self.assertFalse(ctx1.is_root) | |
| 255 self.assertTrue(ctx1.root is root) | |
| 256 self.assertTrue(ctx1.settings is settings) | |
| 257 ctx2 = data_schema.Context(ctx1, index=2, settings=settings2) | |
| 258 self.assertTrue(ctx2.settings is settings2) | |
| 259 ctx3 = data_schema.Context(ctx2, key="key3") | |
| 260 self.assertEqual("key1 / INDEX:2 / key3", str(ctx3)) | |
| 261 self.assertFalse(ctx3.is_root) | |
| 262 self.assertTrue(ctx3.root is root) | |
| 263 self.assertTrue(ctx3.settings is settings2) | |
| 264 | |
| 265 def test_key_xor_index(self): | |
| 266 settings = data_schema.ValidationSettings( | |
| 267 skip_keys=[], break_on_keynames_problems=True) | |
| 268 root = data_schema.Context(None, settings=settings) | |
| 269 self.assertRaises( | |
| 270 ValueError, | |
| 271 data_schema.Context, | |
| 272 root, | |
| 273 index=0, | |
| 274 key="huhu") | |
| 275 | |
| 276 def test_keyindex_requires_key(self): | |
| 277 settings = data_schema.ValidationSettings( | |
| 278 skip_keys=[], break_on_keynames_problems=True) | |
| 279 self.assertRaises( | |
| 280 ValueError, | |
| 281 data_schema.Context, | |
| 282 None, | |
| 283 key_index=0, | |
| 284 settings=settings) | |
| 285 | |
| 286 | |
| 287 class SchemaReferences(unittest.TestCase): | |
| 288 | |
| 289 def setUp(self): | |
| 290 self.empty_schema = data_schema._Schema(None, True) | |
| 291 | |
| 292 def test_no_fragment(self): | |
| 293 ctx = data_schema.Context(None, root_object={"foo": "bar"}, settings=None) | |
| 294 self.assertRaises(data_schema.SchemaError, | |
| 295 data_schema.try_get_reference, | |
| 296 "object:", | |
| 297 ctx, | |
| 298 self.empty_schema) | |
| 299 | |
| 300 def test_empty_fragment(self): | |
| 301 ctx = data_schema.Context(None, root_object={"foo": "bar"}, settings=None) | |
| 302 r = data_schema.try_get_reference( | |
| 303 "object:#", | |
| 304 ctx, | |
| 305 self.empty_schema) | |
| 306 self.assertIs(r, ctx.root_object) | |
| 307 self.assertIs(r, ctx.current_object) | |
| 308 | |
| 309 def test_point_fragment_with_root(self): | |
| 310 ctx = data_schema.Context(None, root_object={"foo": "bar"}, settings=None) | |
| 311 r = data_schema.try_get_reference( | |
| 312 "object:#.", | |
| 313 ctx, | |
| 314 self.empty_schema) | |
| 315 self.assertIs(r, ctx.root_object) | |
| 316 self.assertIs(r, ctx.current_object) | |
| 317 | |
| 318 def test_point_fragment_with_current_object(self): | |
| 319 current_object = { | |
| 320 "current": { | |
| 321 "object": "value"}} | |
| 322 root_object = {"root": current_object} | |
| 323 ctx = data_schema.Context(None, current_object=current_object, | |
| 324 root_object=root_object, settings=None) | |
| 325 r = data_schema.try_get_reference( | |
| 326 "object:#.", | |
| 327 ctx, | |
| 328 self.empty_schema) | |
| 329 self.assertIs(r, ctx.current_object) | |
| 330 self.assertIs(r, current_object) | |
| 331 self.assertIsNot(r, ctx.root_object) | |
| 332 | |
| 333 r = data_schema.try_get_reference( | |
| 334 "object:#.current", | |
| 335 ctx, | |
| 336 self.empty_schema) | |
| 337 self.assertEqual({"object": "value"}, r) | |
| 338 | |
| 339 r = data_schema.try_get_reference( | |
| 340 "object:#.current.object", | |
| 341 ctx, | |
| 342 self.empty_schema) | |
| 343 self.assertEqual("value", r) | |
| 344 | |
| 345 def test_point_fragment_with_invalid_current_object_refs(self): | |
| 346 current_object = { | |
| 347 "current": { | |
| 348 "object": "value"}} | |
| 349 root_object = {"root": current_object} | |
| 350 ctx = data_schema.Context(None, current_object=current_object, | |
| 351 root_object=root_object, settings=None) | |
| 352 r = data_schema.try_get_reference( | |
| 353 "object:#.", | |
| 354 ctx, | |
| 355 self.empty_schema) | |
| 356 self.assertIs(r, ctx.current_object) | |
| 357 self.assertIs(r, current_object) | |
| 358 | |
| 359 r = data_schema.try_get_reference( | |
| 360 "object:#.non-current", | |
| 361 ctx, | |
| 362 self.empty_schema) | |
| 363 self.assertIsNone(r) | |
| 364 | |
| 365 r = data_schema.try_get_reference( | |
| 366 "object:#.non-current.object", ctx, self.empty_schema) | |
| 367 self.assertIsNone(r) | |
| 368 | |
| 369 r = data_schema.try_get_reference( | |
| 370 "object:#.current.non-object", ctx, self.empty_schema) | |
| 371 self.assertIsNone(r) | |
| 372 | |
| 373 self.assertRaises( | |
| 374 data_schema.SchemaError, | |
| 375 data_schema.try_get_reference, | |
| 376 "object:#.current..", | |
| 377 ctx, | |
| 378 self.empty_schema) | |
| 379 | |
| 380 self.assertRaises( | |
| 381 TypeError, | |
| 382 data_schema.try_get_reference, | |
| 383 "object:#..current.object", | |
| 384 ctx, | |
| 385 self.empty_schema) | |
| 386 | |
| 387 def test_fragment_with_current_object_and_root(self): | |
| 388 current_object = { | |
| 389 "current": { | |
| 390 "object": "value"}} | |
| 391 root_object = {"root": current_object} | |
| 392 ctx = data_schema.Context(None, current_object=current_object, | |
| 393 root_object=root_object, settings=None) | |
| 394 r = data_schema.try_get_reference( | |
| 395 "object:#", ctx, self.empty_schema) | |
| 396 self.assertIs(r, ctx.root_object) | |
| 397 self.assertIs(r, root_object) | |
| 398 | |
| 399 def test_default_schema_ref(self): | |
| 400 ctx = data_schema.Context(None, root_object={"foo": "bar"}, | |
| 401 settings=None) | |
| 402 r = data_schema.try_get_reference("#foo", ctx, self.empty_schema) | |
| 403 self.assertEqual("bar", r) | |
| 404 r = data_schema.try_get_reference("#bar", ctx, self.empty_schema) | |
| 405 self.assertIsNone(r) | |
| 406 sentinel = object() | |
| 407 r = data_schema.try_get_reference("#bar", ctx, self.empty_schema, | |
| 408 default=sentinel) | |
| 409 self.assertIs(r, sentinel) | |
| 410 | |
| 411 def test_object_schema_ref(self): | |
| 412 ctx = data_schema.Context(None, root_object={"foo": "bar"}, | |
| 413 settings=None) | |
| 414 r = data_schema.try_get_reference("object:#foo", ctx, | |
| 415 self.empty_schema) | |
| 416 self.assertEqual("bar", r) | |
| 417 r = data_schema.try_get_reference("object:#bar", ctx, | |
| 418 self.empty_schema) | |
| 419 self.assertIsNone(r) | |
| 420 sentinel = object() | |
| 421 r = data_schema.try_get_reference( | |
| 422 "object:#bar", | |
| 423 ctx, | |
| 424 self.empty_schema, | |
| 425 default=sentinel) | |
| 426 self.assertIs(r, sentinel) | |
| 427 | |
| 428 def test_nested_keys(self): | |
| 429 sentinel = object() | |
| 430 ctx = data_schema.Context( | |
| 431 None, | |
| 432 root_object={"foo": "bar", | |
| 433 "k1": {"k2": "v2", | |
| 434 "k3": None}, | |
| 435 "k4": None, | |
| 436 "k5": [1, 2, 3]}, | |
| 437 settings=None) | |
| 438 r = data_schema.try_get_reference( | |
| 439 "#k1.k2", ctx, self.empty_schema) | |
| 440 self.assertEqual("v2", r) | |
| 441 r = data_schema.try_get_reference( | |
| 442 "#k1.k3", ctx, self.empty_schema) | |
| 443 self.assertIsNone(r) | |
| 444 r = data_schema.try_get_reference( | |
| 445 "#k1.k3.fornone", ctx, self.empty_schema) | |
| 446 self.assertIsNone(r) | |
| 447 r = data_schema.try_get_reference( | |
| 448 "#k1.k3.fornone", ctx, self.empty_schema, default=sentinel) | |
| 449 self.assertIs(r, sentinel) | |
| 450 r = data_schema.try_get_reference( | |
| 451 "#k5.0", ctx, self.empty_schema, default=sentinel) | |
| 452 self.assertIs(r, sentinel) | |
| 453 r = data_schema.try_get_reference( | |
| 454 "#k6", ctx, self.empty_schema, default=sentinel) | |
| 455 self.assertIs(r, sentinel) | |
| 456 | |
| 457 def test_url_quoted_fragment(self): | |
| 458 ctx = data_schema.Context( | |
| 459 None, | |
| 460 root_object={"foo": "bar", | |
| 461 "k1": {"k2": "v2", | |
| 462 "k3": None}, | |
| 463 "k4": None, | |
| 464 "k5": [1, 2, 3]}, | |
| 465 settings=None) | |
| 466 r = data_schema.try_get_reference( | |
| 467 "#fo%6F", ctx, self.empty_schema) | |
| 468 self.assertEqual("bar", r) | |
| 469 | |
| 470 def test_no_duplicate_unquoting_in_fragment(self): | |
| 471 ctx = data_schema.Context( | |
| 472 None, | |
| 473 root_object={"fo%o": "bar"}, | |
| 474 settings=None) | |
| 475 r = data_schema.try_get_reference( | |
| 476 "#fo%25o", ctx, self.empty_schema) | |
| 477 self.assertEqual("bar", r) | |
| 478 | |
| 479 def test_schema_ref_must_have_fragment(self): | |
| 480 ctx = data_schema.Context(None, root_schema={"foo": "bar"}, settings=None) | |
| 481 self.assertRaises( | |
| 482 data_schema.SchemaError, | |
| 483 data_schema.try_get_reference, | |
| 484 "schema:", | |
| 485 ctx, | |
| 486 self.empty_schema) | |
| 487 | |
| 488 def test_schema_ref_must_have_absolute_fragment(self): | |
| 489 ctx = data_schema.Context(None, root_schema={"foo": "bar"}, settings=None) | |
| 490 self.assertRaises( | |
| 491 data_schema.SchemaError, | |
| 492 data_schema.try_get_reference, | |
| 493 "schema:#", | |
| 494 ctx, | |
| 495 self.empty_schema) | |
| 496 | |
| 497 def test_schema_ref_root_schema(self): | |
| 498 schema = data_schema._Schema( | |
| 499 None, True, {"foo": "bar"}) | |
| 500 ctx = data_schema.Context(None, root_schema=schema, settings=None) | |
| 501 r = data_schema.try_get_reference( | |
| 502 "schema:#/", ctx, schema) | |
| 503 self.assertIs(r, schema) | |
| 504 | |
| 505 def test_unknown_schema_ref_yet(self): | |
| 506 ctx = data_schema.Context(None, root_object={"foo": "bar"}, settings=None) | |
| 507 self.assertRaises( | |
| 508 data_schema.SchemaError, | |
| 509 data_schema.try_get_reference, | |
| 510 "data:#", | |
| 511 ctx, | |
| 512 self.empty_schema) | |
| 513 | |
| 514 def test_schema_not_found(self): | |
| 515 sentinel = object() | |
| 516 root_schema = data_schema._Schema(None, True, {"foo": "bar"}) | |
| 517 ctx = data_schema.Context(None, root_schema=root_schema, | |
| 518 settings=None) | |
| 519 r = data_schema.try_get_reference( | |
| 520 "schema:#/foo/bar", ctx, root_schema, default=sentinel) | |
| 521 self.assertIs(r, sentinel) | |
| 522 r = data_schema.try_get_reference( | |
| 523 "schema:#/foo2", ctx, root_schema, default=sentinel) | |
| 524 self.assertIs(r, sentinel) | |
| 525 r = data_schema.try_get_reference( | |
| 526 "schema:#/foo3", ctx, root_schema) | |
| 527 self.assertIsNone(r) | |
| 528 | |
| 529 def test_schema_is_found(self): | |
| 530 subsubschema = {"foo3": "bar3"} | |
| 531 subschema = {"foo2": subsubschema} | |
| 532 schema = data_schema._Schema(None, True, {"foo": subschema}) | |
| 533 ctx = data_schema.Context(None, root_schema=schema, settings=None) | |
| 534 r = data_schema.try_get_reference( | |
| 535 "schema:#/foo/foo2", ctx, schema) | |
| 536 self.assertEqual(subsubschema, r) | |
| 537 | |
| 538 def test_schema_with_trailing_slash_is_found(self): | |
| 539 subsubschema = {"foo3": "bar3"} | |
| 540 subschema = {"foo2": subsubschema} | |
| 541 schema = data_schema._Schema(None, True, {"foo": subschema}) | |
| 542 ctx = data_schema.Context(None, root_schema=schema, settings=None) | |
| 543 r = data_schema.try_get_reference( | |
| 544 "schema:#/foo/foo2/", ctx, schema) | |
| 545 self.assertIsNone(r) | |
| 546 | |
| 547 def test_schema_is_found_with_quoted_fragment(self): | |
| 548 subsubschema = {"foo3": "bar3"} | |
| 549 subschema = {"foo2": subsubschema} | |
| 550 schema = data_schema._Schema(None, True, {"foo": subschema}) | |
| 551 ctx = data_schema.Context(None, root_schema=schema, settings=None) | |
| 552 r = data_schema.try_get_reference( | |
| 553 "schema:#/f%6Fo/foo%32", ctx, schema) | |
| 554 self.assertEqual(subsubschema, r) | |
| 555 | |
| 556 | |
| 557 class SchemaConditionals(unittest.TestCase): | |
| 558 | |
| 559 def setUp(self): | |
| 560 self._ctx = data_schema.Context( | |
| 561 None, root_object={"foo": "bar", "foo2": None}, settings=None) | |
| 562 | |
| 563 def test_no_cond(self): | |
| 564 schema = data_schema._Schema(None, True, {"type": None}) | |
| 565 self.assertIs(data_schema.process_schema_conditionals( | |
| 566 schema, self._ctx), | |
| 567 schema) | |
| 568 | |
| 569 def test_cond_is_none(self): | |
| 570 schema = data_schema._Schema(None, True, {"type": None, | |
| 571 "cond": None}) | |
| 572 self.assertIs(data_schema.process_schema_conditionals( | |
| 573 schema, self._ctx), | |
| 574 schema) | |
| 575 | |
| 576 def test_ambiguous(self): | |
| 577 schema = data_schema._Schema(None, True, {"type": None, | |
| 578 "cond": None, | |
| 579 "match": None}) | |
| 580 self.assertRaises( | |
| 581 data_schema.SchemaError, | |
| 582 data_schema.process_schema_conditionals, | |
| 583 schema, | |
| 584 self._ctx) | |
| 585 | |
| 586 def test_cond_not_a_sequence(self): | |
| 587 schema = data_schema._Schema(None, True, {"type": None, | |
| 588 "cond": {"type": None}}) | |
| 589 self.assertRaises( | |
| 590 data_schema.SchemaError, | |
| 591 data_schema.process_schema_conditionals, | |
| 592 schema, | |
| 593 self._ctx) | |
| 594 | |
| 595 def test_match_not_a_sequence(self): | |
| 596 schema = data_schema._Schema( | |
| 597 None, True, {"type": None, | |
| 598 "match": {"type": None}}) | |
| 599 self.assertRaises( | |
| 600 data_schema.SchemaError, | |
| 601 data_schema.process_schema_conditionals, | |
| 602 schema, | |
| 603 self._ctx) | |
| 604 | |
| 605 def test_condline_not_a_dict(self): | |
| 606 schema = data_schema._Schema(None, True, {"type": None, | |
| 607 "cond": [None]}) | |
| 608 self.assertRaises( | |
| 609 data_schema.SchemaError, | |
| 610 data_schema.process_schema_conditionals, | |
| 611 schema, | |
| 612 self._ctx) | |
| 613 | |
| 614 def test_matchline_not_a_dict(self): | |
| 615 schema = {"type": None, | |
| 616 "match": [None]} | |
| 617 self.assertRaises( | |
| 618 data_schema.SchemaError, | |
| 619 data_schema.process_schema_conditionals, | |
| 620 schema, | |
| 621 self._ctx) | |
| 622 | |
| 623 def test_cond_unknown_predicate(self): | |
| 624 schema = data_schema._Schema( | |
| 625 None, True, {"type": None, | |
| 626 "cond": [ | |
| 627 {"unexisting-when-xxxx": None, | |
| 628 "then": {}} | |
| 629 ]}) | |
| 630 self.assertRaises( | |
| 631 data_schema.SchemaError, | |
| 632 data_schema.process_schema_conditionals, | |
| 633 schema, | |
| 634 self._ctx) | |
| 635 | |
| 636 def test_match_unknown_predicate(self): | |
| 637 schema = data_schema._Schema( | |
| 638 None, True, {"type": None, | |
| 639 "match": [ | |
| 640 {"unexisting-when-xxxx": None, | |
| 641 "then": {}} | |
| 642 ]}) | |
| 643 self.assertRaises( | |
| 644 data_schema.SchemaError, | |
| 645 data_schema.process_schema_conditionals, | |
| 646 schema, | |
| 647 self._ctx) | |
| 648 | |
| 649 def test_simple_replace_when_true(self): | |
| 650 schema = data_schema._Schema( | |
| 651 None, True, {"type": None, | |
| 652 "require": ["huhu", "haha"], | |
| 653 "cond": [ | |
| 654 {"when": True, | |
| 655 "then": { | |
| 656 "require": ["r1", "r2", "r3"], | |
| 657 "new-key": None, | |
| 658 }} | |
| 659 ]}) | |
| 660 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 661 self.assertIsNot(r, schema) | |
| 662 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 663 self.assertTrue("new-key" in r) | |
| 664 self.assertIsNone(r["new-key"]) | |
| 665 self.assertFalse("cond" in r) | |
| 666 | |
| 667 def test_simple_replace_when_not_false(self): | |
| 668 schema = data_schema._Schema( | |
| 669 None, True, {"type": None, | |
| 670 "require": ["huhu", "haha"], | |
| 671 "cond": [ | |
| 672 {"when": {"not": False}, | |
| 673 "then": { | |
| 674 "require": ["r1", "r2", "r3"], | |
| 675 "new-key": None, | |
| 676 }} | |
| 677 ]}) | |
| 678 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 679 self.assertIsNot(r, schema) | |
| 680 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 681 self.assertTrue("new-key" in r) | |
| 682 self.assertIsNone(r["new-key"]) | |
| 683 self.assertFalse("cond" in r) | |
| 684 | |
| 685 def test_simple_merge_when_true(self): | |
| 686 schema = data_schema._Schema( | |
| 687 None, True, {"type": None, | |
| 688 "require": ["huhu", "haha"], | |
| 689 "old-key": "here I am", | |
| 690 "cond": [ | |
| 691 {"when": True, | |
| 692 "then-merge": { | |
| 693 "require": ["r1", "r2", "r3"], | |
| 694 "new-key": None, | |
| 695 "old-key": "{{::DEL::}}" | |
| 696 }} | |
| 697 ]}) | |
| 698 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 699 self.assertIsNot(r, schema) | |
| 700 self.assertEqual(["huhu", "haha", "r1", "r2", "r3"], r["require"]) | |
| 701 self.assertTrue("new-key" in r) | |
| 702 self.assertIsNone(r["new-key"]) | |
| 703 self.assertFalse("old-key" in r) | |
| 704 self.assertFalse("cond" in r) | |
| 705 | |
| 706 def test_simple_replace_first_wins_1(self): | |
| 707 schema = data_schema._Schema( | |
| 708 None, True, {"type": None, | |
| 709 "require": ["huhu", "haha", "hehe"], | |
| 710 "cond": [ | |
| 711 {"when": True, | |
| 712 "then": { | |
| 713 "new-key2": "v2"}}, | |
| 714 {"when": True, | |
| 715 "then": { | |
| 716 "require": ["r1", "r2", "r3"], | |
| 717 "new-key": None}} | |
| 718 ]}) | |
| 719 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 720 self.assertIsNot(r, schema) | |
| 721 self.assertEqual(["huhu", "haha", "hehe"], r["require"]) | |
| 722 self.assertTrue("new-key2" in r) | |
| 723 self.assertEqual("v2", r["new-key2"]) | |
| 724 self.assertFalse("cond" in r) | |
| 725 | |
| 726 def test_simple_replace_first_wins_2(self): | |
| 727 schema = data_schema._Schema( | |
| 728 None, True, {"type": None, | |
| 729 "require": ["huhu", "haha", "hehe"], | |
| 730 "cond": [ | |
| 731 {"when": False, | |
| 732 "then": { | |
| 733 "new-key2": "v2"}}, | |
| 734 {"when": True, | |
| 735 "then": { | |
| 736 "require": ["r1", "r2", "r3"], | |
| 737 "new-key": None}} | |
| 738 ]}) | |
| 739 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 740 self.assertIsNot(r, schema) | |
| 741 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 742 self.assertTrue("new-key" in r) | |
| 743 self.assertIsNone(r["new-key"]) | |
| 744 self.assertFalse("new-key2" in r) | |
| 745 self.assertFalse("cond" in r) | |
| 746 | |
| 747 def test_simple_replace_when_false(self): | |
| 748 schema = data_schema._Schema( | |
| 749 None, True, {"type": None, | |
| 750 "require": ["huhu", "haha"], | |
| 751 "cond": [ | |
| 752 {"when": False, | |
| 753 "then": { | |
| 754 "require": ["r1", "r2", "r3"], | |
| 755 "new-key": None, | |
| 756 }} | |
| 757 ]}) | |
| 758 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 759 self.assertIsNot(r, schema) | |
| 760 self.assertEqual(["huhu", "haha"], r["require"]) | |
| 761 self.assertFalse("new-key" in r) | |
| 762 self.assertFalse("cond" in r) | |
| 763 | |
| 764 def test_simple_replace_when_ref_true(self): | |
| 765 schema = data_schema._Schema( | |
| 766 None, True, {"type": None, | |
| 767 "require": ["huhu", "haha"], | |
| 768 "cond": [ | |
| 769 {"when-ref-true": '#foo', | |
| 770 "then": { | |
| 771 "require": ["r1", "r2", "r3"], | |
| 772 "new-key": None, | |
| 773 }} | |
| 774 ]}) | |
| 775 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 776 self.assertIsNot(r, schema) | |
| 777 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 778 self.assertTrue("new-key" in r) | |
| 779 self.assertIsNone(r["new-key"]) | |
| 780 self.assertFalse("cond" in r) | |
| 781 | |
| 782 def test_simple_replace_when_ref_true_2(self): | |
| 783 schema = data_schema._Schema( | |
| 784 None, True, {"type": None, | |
| 785 "require": ["huhu", "haha"], | |
| 786 "cond": [ | |
| 787 {"when": {"ref-true": '#foo'}, | |
| 788 "then": { | |
| 789 "require": ["r1", "r2", "r3"], | |
| 790 "new-key": None, | |
| 791 }} | |
| 792 ]}) | |
| 793 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 794 self.assertIsNot(r, schema) | |
| 795 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 796 self.assertTrue("new-key" in r) | |
| 797 self.assertIsNone(r["new-key"]) | |
| 798 self.assertFalse("cond" in r) | |
| 799 | |
| 800 def test_simple_replace_when_ref_is_not_true(self): | |
| 801 schema = data_schema._Schema( | |
| 802 None, True, {"type": None, | |
| 803 "require": ["huhu", "haha"], | |
| 804 "cond": [ | |
| 805 {"when-ref-true": '#not-a-foo', | |
| 806 "then": { | |
| 807 "require": ["r1", "r2", "r3"], | |
| 808 "new-key": None, | |
| 809 }} | |
| 810 ]}) | |
| 811 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 812 self.assertIsNot(r, schema) | |
| 813 self.assertEqual(["huhu", "haha"], r["require"]) | |
| 814 self.assertTrue("new-key" not in r) | |
| 815 self.assertFalse("cond" in r) | |
| 816 | |
| 817 def test_simple_replace_when_ref_is_not_true_2(self): | |
| 818 schema = data_schema._Schema( | |
| 819 None, True, {"type": None, | |
| 820 "require": ["huhu", "haha"], | |
| 821 "cond": [ | |
| 822 {"when": {"ref-true": '#not-a-foo'}, | |
| 823 "then": { | |
| 824 "require": ["r1", "r2", "r3"], | |
| 825 "new-key": None, | |
| 826 }} | |
| 827 ]}) | |
| 828 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 829 self.assertIsNot(r, schema) | |
| 830 self.assertEqual(["huhu", "haha"], r["require"]) | |
| 831 self.assertTrue("new-key" not in r) | |
| 832 self.assertFalse("cond" in r) | |
| 833 | |
| 834 def test_simple_replace_when_ref_exists(self): | |
| 835 schema = data_schema._Schema( | |
| 836 None, True, {"type": None, | |
| 837 "require": ["huhu", "haha"], | |
| 838 "cond": [ | |
| 839 {"when-ref-exists": '#foo2', | |
| 840 "then": { | |
| 841 "require": ["r1", "r2", "r3"], | |
| 842 "new-key": None, | |
| 843 }}, | |
| 844 {"when": True, | |
| 845 "then": { | |
| 846 "new-key3": "val"}} | |
| 847 ]}) | |
| 848 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 849 self.assertIsNot(r, schema) | |
| 850 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 851 self.assertTrue("new-key" in r) | |
| 852 self.assertIsNone(r["new-key"]) | |
| 853 self.assertFalse("new-key3" in r) | |
| 854 self.assertFalse("cond" in r) | |
| 855 | |
| 856 def test_simple_replace_when_ref_exists_2(self): | |
| 857 schema = data_schema._Schema( | |
| 858 None, True, {"type": None, | |
| 859 "require": ["huhu", "haha"], | |
| 860 "cond": [ | |
| 861 {"when": {"ref-exists": '#foo2'}, | |
| 862 "then": { | |
| 863 "require": ["r1", "r2", "r3"], | |
| 864 "new-key": None, | |
| 865 }}, | |
| 866 {"when": True, | |
| 867 "then": { | |
| 868 "new-key3": "val"}} | |
| 869 ]}) | |
| 870 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 871 self.assertIsNot(r, schema) | |
| 872 self.assertEqual(["r1", "r2", "r3"], r["require"]) | |
| 873 self.assertTrue("new-key" in r) | |
| 874 self.assertIsNone(r["new-key"]) | |
| 875 self.assertFalse("new-key3" in r) | |
| 876 self.assertFalse("cond" in r) | |
| 877 | |
| 878 def test_simple_replace_when_ref_exists_is_false(self): | |
| 879 schema = data_schema._Schema( | |
| 880 None, True, {"type": None, | |
| 881 "cond": [ | |
| 882 {"when-ref-exists": '#foo-not-existing', | |
| 883 "then": { | |
| 884 "require": ["r1", "r2", "r3"], | |
| 885 "new-key": None, | |
| 886 }}, | |
| 887 {"when": True, | |
| 888 "then": { | |
| 889 "new-key3": "val"}} | |
| 890 ]}) | |
| 891 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 892 self.assertIsNot(r, schema) | |
| 893 self.assertFalse("require" in r) | |
| 894 self.assertFalse("new-key" in r) | |
| 895 self.assertEqual("val", r["new-key3"]) | |
| 896 self.assertFalse("cond" in r) | |
| 897 | |
| 898 def test_simple_replace_when_ref_exists_is_false_2(self): | |
| 899 schema = data_schema._Schema( | |
| 900 None, True, {"type": None, | |
| 901 "cond": [ | |
| 902 {"when": {"ref-exists": '#foo-not-existing'}, | |
| 903 "then": { | |
| 904 "require": ["r1", "r2", "r3"], | |
| 905 "new-key": None, | |
| 906 }}, | |
| 907 {"when": True, | |
| 908 "then": { | |
| 909 "new-key3": "val"}} | |
| 910 ]}) | |
| 911 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 912 self.assertIsNot(r, schema) | |
| 913 self.assertFalse("require" in r) | |
| 914 self.assertFalse("new-key" in r) | |
| 915 self.assertEqual("val", r["new-key3"]) | |
| 916 self.assertFalse("cond" in r) | |
| 917 | |
| 918 def test_allOf_true(self): | |
| 919 schema = data_schema._Schema( | |
| 920 None, True, {"cond": [ | |
| 921 {"when": {"all-of": [ | |
| 922 True, | |
| 923 {"ref-exists": '#foo2'}, | |
| 924 {"ref-true": '#foo'}]}, | |
| 925 "then": {"type": "string"}}, | |
| 926 {"when": True, | |
| 927 "then": {"type": None}} | |
| 928 ]}) | |
| 929 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 930 self.assertIsNot(r, schema) | |
| 931 self.assertEqual("string", r["type"]) | |
| 932 | |
| 933 def test_allOf_false(self): | |
| 934 schema = data_schema._Schema( | |
| 935 None, True, {"cond": [ | |
| 936 {"when": {"all-of": [ | |
| 937 True, | |
| 938 {"ref-exists": '#foo-non-existing'}, | |
| 939 {"ref-true": '#foo'}]}, | |
| 940 "then": {"type": "string"}}, | |
| 941 {"when": True, | |
| 942 "then": {"type": None}} | |
| 943 ]}) | |
| 944 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 945 self.assertIsNot(r, schema) | |
| 946 self.assertIsNone(r["type"]) | |
| 947 | |
| 948 def test_short_allOf_true(self): | |
| 949 schema = data_schema._Schema( | |
| 950 None, True, {"cond": [ | |
| 951 {"when": [ | |
| 952 True, | |
| 953 {"ref-exists": '#foo2'}, | |
| 954 {"ref-true": '#foo'}], | |
| 955 "then": {"type": "string"}}, | |
| 956 {"when": True, | |
| 957 "then": {"type": None}} | |
| 958 ]}) | |
| 959 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 960 self.assertIsNot(r, schema) | |
| 961 self.assertEqual("string", r["type"]) | |
| 962 | |
| 963 def test_short_allOf_false(self): | |
| 964 schema = data_schema._Schema( | |
| 965 None, True, {"cond": [ | |
| 966 {"when": [ | |
| 967 True, | |
| 968 {"ref-exists": '#foo-non-existing'}, | |
| 969 {"ref-true": '#foo'}], | |
| 970 "then": {"type": "string"}}, | |
| 971 {"when": True, | |
| 972 "then": {"type": None}} | |
| 973 ]}) | |
| 974 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 975 self.assertIsNot(r, schema) | |
| 976 self.assertIsNone(r["type"]) | |
| 977 | |
| 978 def test_anyOf_true(self): | |
| 979 schema = data_schema._Schema( | |
| 980 None, True, {"cond": [ | |
| 981 {"when": {"any-of": [ | |
| 982 False, | |
| 983 {"ref-exists": '#foo2'}, | |
| 984 {"ref-true": '#foo'}]}, | |
| 985 "then": {"type": "string"}}, | |
| 986 {"when": True, | |
| 987 "then": {"type": None}} | |
| 988 ]}) | |
| 989 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 990 self.assertIsNot(r, schema) | |
| 991 self.assertEqual("string", r["type"]) | |
| 992 | |
| 993 def test_anyOf_false(self): | |
| 994 schema = data_schema._Schema( | |
| 995 None, True, {"cond": [ | |
| 996 {"when": {"any-of": [ | |
| 997 False, | |
| 998 {"ref-exists": '#foo2-non'}, | |
| 999 {"ref-true": '#foo2'}]}, | |
| 1000 "then": {"type": "string"}}, | |
| 1001 {"when": True, | |
| 1002 "then": {"type": None}} | |
| 1003 ]}) | |
| 1004 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1005 self.assertIsNot(r, schema) | |
| 1006 self.assertIsNone(r["type"]) | |
| 1007 | |
| 1008 def test_oneOf_true(self): | |
| 1009 schema = data_schema._Schema( | |
| 1010 None, True, {"cond": [ | |
| 1011 {"when": {"one-of": [ | |
| 1012 False, | |
| 1013 {"ref-exists": '#foo2'}, | |
| 1014 {"not": {"ref-true": '#foo'}}]}, | |
| 1015 "then": {"type": "string"}}, | |
| 1016 {"when": True, | |
| 1017 "then": {"type": None}} | |
| 1018 ]}) | |
| 1019 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1020 self.assertIsNot(r, schema) | |
| 1021 self.assertEqual("string", r["type"]) | |
| 1022 | |
| 1023 def test_oneOf_false(self): | |
| 1024 schema = data_schema._Schema( | |
| 1025 None, True, {"cond": [ | |
| 1026 {"when": {"one-of": [ | |
| 1027 False, | |
| 1028 {"ref-exists": '#foo2'}, | |
| 1029 {"ref-true": '#foo'}]}, | |
| 1030 "then": {"type": "string"}}, | |
| 1031 {"when": True, | |
| 1032 "then": {"type": None}} | |
| 1033 ]}) | |
| 1034 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1035 self.assertIsNot(r, schema) | |
| 1036 self.assertIsNone(r["type"]) | |
| 1037 | |
| 1038 def test_oneOf_false_2(self): | |
| 1039 schema = data_schema._Schema( | |
| 1040 None, True, {"cond": [ | |
| 1041 {"when": {"one-of": [ | |
| 1042 False, | |
| 1043 {"not": {"ref-exists": '#foo2'}}, | |
| 1044 {"not": {"ref-true": '#foo'}}]}, | |
| 1045 "then": {"type": "string"}}, | |
| 1046 {"when": True, | |
| 1047 "then": {"type": None}} | |
| 1048 ]}) | |
| 1049 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1050 self.assertIsNot(r, schema) | |
| 1051 self.assertIsNone(r["type"]) | |
| 1052 | |
| 1053 def test_match_nothing(self): | |
| 1054 schema = data_schema._Schema( | |
| 1055 None, | |
| 1056 True, | |
| 1057 { | |
| 1058 "match": [ | |
| 1059 {"when": False, | |
| 1060 "then": {"new-key": None}}, | |
| 1061 {"when": False, | |
| 1062 "then": {"new-key2": None}} | |
| 1063 ]}) | |
| 1064 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1065 self.assertFalse("new-key" in r) | |
| 1066 self.assertFalse("new-key2" in r) | |
| 1067 | |
| 1068 def test_match_all(self): | |
| 1069 schema = data_schema._Schema( | |
| 1070 None, | |
| 1071 True, | |
| 1072 { | |
| 1073 "match": [ | |
| 1074 {"when": True, | |
| 1075 "then": {"new-key": "value"}}, | |
| 1076 {"when": True, | |
| 1077 "then": {"new-key2": "value2"}} | |
| 1078 ]}) | |
| 1079 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1080 self.assertEqual("value", r["new-key"]) | |
| 1081 self.assertEqual("value2", r["new-key2"]) | |
| 1082 | |
| 1083 def test_match_some(self): | |
| 1084 schema = data_schema._Schema( | |
| 1085 None, | |
| 1086 True, | |
| 1087 { | |
| 1088 "match": [ | |
| 1089 {"when": True, | |
| 1090 "then": {"new-key": "value"}}, | |
| 1091 {"when": False, | |
| 1092 "then": {"new-key2": "value2"}}, | |
| 1093 {"when": True, | |
| 1094 "then": {"new-key3": "value3"}}, | |
| 1095 {"when": False, | |
| 1096 "then": {"new-key4": "value4"}} | |
| 1097 ]}) | |
| 1098 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1099 self.assertEqual("value", r["new-key"]) | |
| 1100 self.assertFalse("new-key2" in r) | |
| 1101 self.assertEqual("value3", r["new-key3"]) | |
| 1102 self.assertFalse("new-key4" in r) | |
| 1103 | |
| 1104 def test_match_some_merge(self): | |
| 1105 schema = data_schema._Schema( | |
| 1106 None, | |
| 1107 True, | |
| 1108 {"match": [ | |
| 1109 {"when": True, | |
| 1110 "then": {"new-key": [1, 2]}}, | |
| 1111 {"when": False, | |
| 1112 "then": {"new-key2": "value2"}}, | |
| 1113 {"when": True, | |
| 1114 "then-merge": {"new-key": ["value3"]}}, | |
| 1115 {"when": False, | |
| 1116 "then": {"new-key3": "value3"}} | |
| 1117 ]}) | |
| 1118 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1119 self.assertEqual([1, 2, "value3"], r["new-key"]) | |
| 1120 self.assertFalse("new-key2" in r) | |
| 1121 self.assertFalse("new-key3" in r) | |
| 1122 | |
| 1123 def test_match_some_replace(self): | |
| 1124 schema = data_schema._Schema( | |
| 1125 None, | |
| 1126 True, | |
| 1127 {"match": [ | |
| 1128 {"when": True, | |
| 1129 "then": {"new-key": [1, 2]}}, | |
| 1130 {"when": False, | |
| 1131 "then": {"new-key2": "value2"}}, | |
| 1132 {"when": True, | |
| 1133 "then-replace": {"new-key": ["value3"]}}, | |
| 1134 {"when": True, | |
| 1135 "then": {"new-key3": "value3"}} | |
| 1136 ]}) | |
| 1137 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1138 self.assertEqual(["value3"], r["new-key"]) | |
| 1139 self.assertFalse("new-key2" in r) | |
| 1140 self.assertEqual("value3", r["new-key3"]) | |
| 1141 | |
| 1142 def test_match_some_merge_existing(self): | |
| 1143 # the typical case within vlobby: just extend "required" | |
| 1144 schema = data_schema._Schema( | |
| 1145 None, True, {"required": [1, 2], | |
| 1146 "match": [ | |
| 1147 {"when": True, | |
| 1148 "then": {"required": [3, 4]}}, | |
| 1149 {"when": False, | |
| 1150 "then": {"required": [0]}}, | |
| 1151 {"when": True, | |
| 1152 "then-merge": {"required": [5, 6, 7]}}, | |
| 1153 {"when": True, | |
| 1154 "then-merge": {"required": [4, 8]}} | |
| 1155 ]}) | |
| 1156 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1157 self.assertEqual([3, 4, 5, 6, 7, 4, 8], r["required"]) | |
| 1158 | |
| 1159 def test_equal_ref_and_value(self): | |
| 1160 schema = data_schema._Schema( | |
| 1161 None, True, {"foos": "bar", | |
| 1162 "match": [{ | |
| 1163 "when": { | |
| 1164 "equals": [ | |
| 1165 {"ref": "object:#foo"}, | |
| 1166 {"value": "bar"}]}, | |
| 1167 "then-replace": { | |
| 1168 "foos": "new-bar"}}] | |
| 1169 }) | |
| 1170 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1171 self.assertEqual("new-bar", r["foos"]) | |
| 1172 | |
| 1173 def test_equal_val_and_ref(self): | |
| 1174 schema = data_schema._Schema( | |
| 1175 None, True, {"foos": "bar", | |
| 1176 "cond": [{ | |
| 1177 "when": { | |
| 1178 "equals": [ | |
| 1179 {"val": "bar"}, | |
| 1180 {"ref": "object:#foo"}]}, | |
| 1181 "then-replace": { | |
| 1182 "foos": "new-bar"}}] | |
| 1183 }) | |
| 1184 r = data_schema.process_schema_conditionals(schema, self._ctx) | |
| 1185 self.assertEqual("new-bar", r["foos"]) | |
| 1186 | |
| 1187 def test_equal_no_list(self): | |
| 1188 schema = data_schema._Schema( | |
| 1189 None, True, {"foos": "bar", | |
| 1190 "match": [{ | |
| 1191 "when": { | |
| 1192 "equals": {"type": None}, | |
| 1193 "then-replace": { | |
| 1194 "foos": "new-bar"}}}] | |
| 1195 }) | |
| 1196 self.assertRaises( | |
| 1197 data_schema.SchemaError, | |
| 1198 data_schema.process_schema_conditionals, | |
| 1199 schema, | |
| 1200 self._ctx) | |
| 1201 | |
| 1202 def test_equal_list_length_mismatch_1(self): | |
| 1203 schema = data_schema._Schema( | |
| 1204 None, True, {"foo": "bar", | |
| 1205 "match": [{ | |
| 1206 "when": { | |
| 1207 "equals": [ | |
| 1208 {"ref": "object:#foo"}]}, | |
| 1209 "then-replace": { | |
| 1210 "foo": "new-bar"}}] | |
| 1211 }) | |
| 1212 self.assertRaises( | |
| 1213 data_schema.SchemaError, | |
| 1214 data_schema.process_schema_conditionals, | |
| 1215 schema, | |
| 1216 self._ctx) | |
| 1217 | |
| 1218 def test_equal_list_length_mismatch_3(self): | |
| 1219 schema = data_schema._Schema( | |
| 1220 None, True, {"foo": "bar", | |
| 1221 "match": [{ | |
| 1222 "when": { | |
| 1223 "equals": [ | |
| 1224 {"ref": "object:#foo"}, | |
| 1225 {"ref": "object:#foo"}, | |
| 1226 {"ref": "object:#foo"}]}, | |
| 1227 "then-replace": { | |
| 1228 "foo": "new-bar"}}] | |
| 1229 }) | |
| 1230 self.assertRaises( | |
| 1231 data_schema.SchemaError, | |
| 1232 data_schema.process_schema_conditionals, | |
| 1233 schema, | |
| 1234 self._ctx) | |
| 1235 | |
| 1236 def test_raise_if_scheme_ref_is_not_the_single_key(self): | |
| 1237 schema = data_schema._Schema( | |
| 1238 None, True, {"$ref": "schema:#/", | |
| 1239 "type": None | |
| 1240 }) | |
| 1241 ctx = data_schema.Context( | |
| 1242 None, root_schema=schema, settings=None) | |
| 1243 self.assertRaises( | |
| 1244 data_schema.SchemaError, | |
| 1245 data_schema.process_schema_references, | |
| 1246 schema, | |
| 1247 ctx) | |
| 1248 | |
| 1249 def test_raise_if_scheme_ref_is_not_the_single_key_root(self): | |
| 1250 schema = data_schema._Schema( | |
| 1251 None, True, {"$ref": "schema:#/subschema", | |
| 1252 "subschema": { | |
| 1253 "type": None | |
| 1254 } | |
| 1255 }) | |
| 1256 ctx = data_schema.Context( | |
| 1257 None, root_schema=schema, settings=None) | |
| 1258 r = data_schema.process_schema_references( | |
| 1259 schema, | |
| 1260 ctx, | |
| 1261 check_single_ref_key=False) | |
| 1262 self.assertEqual({"type": None}, r) | |
| 1263 | |
| 1264 def test_recursive_schema_scheme(self): | |
| 1265 barschema = { | |
| 1266 "type": "null" | |
| 1267 } | |
| 1268 fooschema = { | |
| 1269 "$ref": "schema:#/bar" | |
| 1270 } | |
| 1271 schema = data_schema._Schema( | |
| 1272 None, True, {"foo": fooschema, | |
| 1273 "bar": barschema, | |
| 1274 "$ref": "schema:#/foo" | |
| 1275 }) | |
| 1276 ctx = data_schema.Context( | |
| 1277 None, root_schema=schema, settings=None) | |
| 1278 r = data_schema.process_schema_references( | |
| 1279 schema, | |
| 1280 ctx, | |
| 1281 check_single_ref_key=False) | |
| 1282 self.assertEqual({"type": "null"}, r) | |
| 1283 | |
| 1284 def test_recursive_schema_scheme_raises_if_non_root_is_not_single_key(self): | |
| 1285 barschema = { | |
| 1286 "type": "null" | |
| 1287 } | |
| 1288 fooschema = { | |
| 1289 "$ref": "schema:#/bar", | |
| 1290 "type": "dict", | |
| 1291 } | |
| 1292 schema = data_schema._Schema( | |
| 1293 None, True, { | |
| 1294 "foo": fooschema, | |
| 1295 "bar": barschema, | |
| 1296 "$ref": "schema:#/foo" | |
| 1297 }) | |
| 1298 ctx = data_schema.Context( | |
| 1299 None, root_schema=schema, settings=None) | |
| 1300 self.assertRaises( | |
| 1301 data_schema.SchemaError, | |
| 1302 data_schema.process_schema_references, | |
| 1303 schema, | |
| 1304 ctx, | |
| 1305 check_single_ref_key=False) | |
| 1306 | |
| 1307 def test_recursive_schema_scheme_ref_to_non_existing_schema_raises(self): | |
| 1308 barschema = { | |
| 1309 "type": "null" | |
| 1310 } | |
| 1311 fooschema = { | |
| 1312 "$ref": "schema:#/non-bar", | |
| 1313 } | |
| 1314 schema = data_schema._Schema( | |
| 1315 None, True, { | |
| 1316 "foo": fooschema, | |
| 1317 "bar": barschema, | |
| 1318 "$ref": "schema:#/foo" | |
| 1319 }) | |
| 1320 ctx = data_schema.Context( | |
| 1321 None, root_schema=schema, settings=None) | |
| 1322 self.assertRaises( | |
| 1323 data_schema.SchemaError, | |
| 1324 data_schema.process_schema_references, | |
| 1325 schema, | |
| 1326 ctx, | |
| 1327 check_single_ref_key=False) | |
| 1328 | |
| 1329 | |
| 1330 class BasicValidation(unittest.TestCase): | |
| 1331 | |
| 1332 def test_schema_must_be_a_dict_alike(self): | |
| 1333 try: | |
| 1334 pr = list(data_schema.validate(None, None)) | |
| 1335 except data_schema.SchemaError: | |
| 1336 pass | |
| 1337 else: | |
| 1338 self.assertFalse( | |
| 1339 "no SchemaError raised when a non-dict given as schema") | |
| 1340 | |
| 1341 def test_problem_ctor_nonexisting_code(self): | |
| 1342 self.assertRaises(ValueError, data_schema.ValidationProblem, code=2) | |
| 1343 | |
| 1344 def test_problem_ctor_no_code(self): | |
| 1345 self.assertRaises(TypeError, data_schema.ValidationProblem, code=None) | |
| 1346 | |
| 1347 def test_error_ctor(self): | |
| 1348 v = data_schema.ValidationProblem(code=10000) | |
| 1349 self.assertEqual(data_schema.ERROR, v.severity) | |
| 1350 | |
| 1351 def test_warning_ctor(self): | |
| 1352 v = data_schema.ValidationProblem(code=80000) | |
| 1353 self.assertEqual(data_schema.WARNING, v.severity) | |
| 1354 | |
| 1355 def test_d1(self): | |
| 1356 x = list(data_schema.validate({}, {"type": "dict"})) | |
| 1357 self.assertEqual(0, len(x)) | |
| 1358 | |
| 1359 def test_d1_not_nullable(self): | |
| 1360 x = list(data_schema.validate(None, {"type": "dict"})) | |
| 1361 self.assertEqual(1, len(x)) | |
| 1362 self.assertEqual(10000, x[0].code) | |
| 1363 | |
| 1364 def test_d1_nullable(self): | |
| 1365 x = list(data_schema.validate(None, {"type": "dict", | |
| 1366 "nullable": True})) | |
| 1367 self.assertEqual(0, len(x)) | |
| 1368 | |
| 1369 def test_d2(self): | |
| 1370 x = list(data_schema.validate([], {"type": "map"})) | |
| 1371 self.assertEqual(1, len(x)) | |
| 1372 self.assertEqual(data_schema.ERROR, x[0].severity) | |
| 1373 self.assertEqual(10000, x[0].code) | |
| 1374 | |
| 1375 def test_d3(self): | |
| 1376 x = list(data_schema.validate( | |
| 1377 {"key": "value"}, | |
| 1378 {"type": "dict", | |
| 1379 "required": ["key2"]})) | |
| 1380 self.assertEqual(2, len(x)) | |
| 1381 self.assertEqual(data_schema.ERROR, x[0].severity) | |
| 1382 self.assertEqual(10004, x[0].code) | |
| 1383 self.assertEqual("key", x[0].hint) | |
| 1384 self.assertEqual(data_schema.ERROR, x[1].severity) | |
| 1385 self.assertEqual(10005, x[1].code) | |
| 1386 self.assertEqual(["key2"], x[1].hint) | |
| 1387 | |
| 1388 def test_d4(self): | |
| 1389 x = list(data_schema.validate( | |
| 1390 {"key": "value"}, | |
| 1391 {"type": "dict", | |
| 1392 "keys": { | |
| 1393 "key": {"type": "string"}, | |
| 1394 }, | |
| 1395 "required": ["key"]})) | |
| 1396 self.assertEqual(0, len(x)) | |
| 1397 | |
| 1398 def test_d5(self): | |
| 1399 x = list(data_schema.validate( | |
| 1400 {"key": "value"}, | |
| 1401 {"type": "dict", | |
| 1402 "additionalKeys": False})) | |
| 1403 self.assertEqual(1, len(x)) | |
| 1404 self.assertEqual(10004, x[0].code) | |
| 1405 self.assertEqual("key", x[0].hint) | |
| 1406 | |
| 1407 def test_d5_2(self): | |
| 1408 x = list(data_schema.validate( | |
| 1409 {"key": "value"}, | |
| 1410 {"type": "dict", | |
| 1411 "additionalKeys": False}, | |
| 1412 skip_keys=["key"])) | |
| 1413 self.assertEqual(0, len(x)) | |
| 1414 | |
| 1415 def test_d5_3(self): | |
| 1416 x = list(data_schema.validate( | |
| 1417 {"key": "value", | |
| 1418 "key2": "value"}, | |
| 1419 {"type": "dict", | |
| 1420 "additionalKeys": False}, | |
| 1421 skip_keys=[re.compile(r"\Akey\d*\Z")])) | |
| 1422 self.assertEqual(0, len(x)) | |
| 1423 | |
| 1424 def test_d5_4(self): | |
| 1425 x = list(data_schema.validate( | |
| 1426 {"key": "value", | |
| 1427 "key2": "value"}, | |
| 1428 {"type": "dict", | |
| 1429 "additionalKeys": False}, | |
| 1430 skip_keys=[re.compile(r"\A__.+"), re.compile(r"\Akey\d+\Z")])) | |
| 1431 self.assertEqual(1, len(x)) | |
| 1432 self.assertEqual(10004, x[0].code) | |
| 1433 self.assertEqual("key", x[0].hint) | |
| 1434 | |
| 1435 def test_d6(self): | |
| 1436 x = list(data_schema.validate( | |
| 1437 {"key": "value"}, | |
| 1438 {"type": "dict", | |
| 1439 "additionalKeys": True})) | |
| 1440 self.assertEqual(0, len(x)) | |
| 1441 | |
| 1442 def test_d7(self): | |
| 1443 x = list(data_schema.validate( | |
| 1444 {"key": "value"}, | |
| 1445 {"type": "dict", | |
| 1446 "additionalKeys": { | |
| 1447 "type": "string"}})) | |
| 1448 self.assertEqual(0, len(x)) | |
| 1449 | |
| 1450 def test_d8(self): | |
| 1451 x = list(data_schema.validate( | |
| 1452 {"key": 1234}, | |
| 1453 {"type": "dict", | |
| 1454 "additionalKeys": { | |
| 1455 "type": "string"}})) | |
| 1456 self.assertEqual(1, len(x)) | |
| 1457 self.assertEqual(10002, x[0].code) | |
| 1458 self.assertEqual(1234, x[0].hint) | |
| 1459 | |
| 1460 def test_d8_2(self): | |
| 1461 x = list(data_schema.validate( | |
| 1462 {"key": 1234}, | |
| 1463 {"type": "dict", | |
| 1464 "additionalKeys": { | |
| 1465 "type": "string"}}, | |
| 1466 skip_keys=["key"])) | |
| 1467 self.assertEqual(0, len(x)) | |
| 1468 | |
| 1469 def test_d9_non_string_keys(self): | |
| 1470 pr = list(data_schema.validate( | |
| 1471 {0: "value"}, | |
| 1472 {"type": "dict", | |
| 1473 "additionalKeys": True})) | |
| 1474 self.assertEqual(1, len(pr)) | |
| 1475 self.assertEqual(10003, pr[0].code) | |
| 1476 | |
| 1477 def test_d10_int_dict_keys(self): | |
| 1478 pr = list(data_schema.validate( | |
| 1479 {1: "value", 2: "value2"}, | |
| 1480 {"type": "dict", | |
| 1481 "keys": { | |
| 1482 1: {"type": "string"}}, | |
| 1483 "additionalKeys": True, | |
| 1484 "keyNames": {"type": "int"}})) | |
| 1485 self.assertEqual(0, len(pr)) | |
| 1486 | |
| 1487 def test_error_message(self): | |
| 1488 self.assertEqual("dict expected", | |
| 1489 data_schema.problem_message(10000)) | |
| 1490 pr = data_schema.ValidationProblem(code=10000) | |
| 1491 self.assertEqual("dict expected", data_schema.problem_message(pr)) | |
| 1492 | |
| 1493 self.assertEqual("duplicate dict key", | |
| 1494 data_schema.problem_message(80000)) | |
| 1495 pr = data_schema.ValidationProblem(code=80000) | |
| 1496 self.assertEqual("duplicate dict key", | |
| 1497 data_schema.problem_message(pr)) | |
| 1498 | |
| 1499 self.assertRaises(KeyError, data_schema.problem_message, 1234) | |
| 1500 | |
| 1501 def test_str_enum(self): | |
| 1502 pr = list(data_schema.validate( | |
| 1503 "e1", | |
| 1504 {"type": "string", | |
| 1505 "enum": ["e1", "e2"]})) | |
| 1506 self.assertEqual(0, len(pr)) | |
| 1507 | |
| 1508 pr = list(data_schema.validate( | |
| 1509 "e2", | |
| 1510 {"type": "string", | |
| 1511 "enum": ["e1", "e2"]})) | |
| 1512 self.assertEqual(0, len(pr)) | |
| 1513 | |
| 1514 def test_str_not_in_enum(self): | |
| 1515 pr = list(data_schema.validate( | |
| 1516 "e3", | |
| 1517 {"type": "string", | |
| 1518 "enum": ["e1", "e2"]})) | |
| 1519 self.assertEqual(1, len(pr)) | |
| 1520 self.assertEqual(10043, pr[0].code) | |
| 1521 | |
| 1522 def test_str_minlen(self): | |
| 1523 pr = list(data_schema.validate( | |
| 1524 "", | |
| 1525 {"type": "string", | |
| 1526 "minLength": 0})) | |
| 1527 self.assertEqual(0, len(pr)) | |
| 1528 | |
| 1529 pr = list(data_schema.validate( | |
| 1530 "", | |
| 1531 {"type": "string", | |
| 1532 "minLength": 1})) | |
| 1533 self.assertEqual(1, len(pr)) | |
| 1534 self.assertEqual(10006, pr[0].code) | |
| 1535 | |
| 1536 pr = list(data_schema.validate( | |
| 1537 "x", | |
| 1538 {"type": "string", | |
| 1539 "minLength": 1})) | |
| 1540 self.assertEqual(0, len(pr)) | |
| 1541 | |
| 1542 def test_str_maxlen(self): | |
| 1543 pr = list(data_schema.validate( | |
| 1544 "", | |
| 1545 {"type": "string", | |
| 1546 "maxLength": 0})) | |
| 1547 self.assertEqual(0, len(pr)) | |
| 1548 | |
| 1549 pr = list(data_schema.validate( | |
| 1550 "x", | |
| 1551 {"type": "string", | |
| 1552 "maxLength": 0})) | |
| 1553 self.assertEqual(1, len(pr)) | |
| 1554 self.assertEqual(10007, pr[0].code) | |
| 1555 | |
| 1556 pr = list(data_schema.validate( | |
| 1557 "x", | |
| 1558 {"type": "string", | |
| 1559 "maxLength": 1})) | |
| 1560 self.assertEqual(0, len(pr)) | |
| 1561 | |
| 1562 pr = list(data_schema.validate( | |
| 1563 b"x", | |
| 1564 {"type": "string", | |
| 1565 "maxLength": 1})) | |
| 1566 self.assertEqual(1, len(pr)) | |
| 1567 self.assertEqual(10002, pr[0].code) | |
| 1568 | |
| 1569 @staticmethod | |
| 1570 def _pattern_check_function(obj, schema, context=None): | |
| 1571 if obj == " 5 ": | |
| 1572 yield data_schema.ValidationProblem(code=10009) | |
| 1573 | |
| 1574 def test_str_re(self): | |
| 1575 pr = list(data_schema.validate( | |
| 1576 "abc", | |
| 1577 {"type": "string", | |
| 1578 "pattern": r'\A[0-9]+\Z'})) | |
| 1579 self.assertEqual(1, len(pr)) | |
| 1580 self.assertEqual(10008, pr[0].code) | |
| 1581 | |
| 1582 pr = list(data_schema.validate( | |
| 1583 "123", | |
| 1584 {"type": "string", | |
| 1585 "pattern": re.compile(r'\A[a-z]+\Z')})) | |
| 1586 self.assertEqual(1, len(pr)) | |
| 1587 self.assertEqual(10008, pr[0].code) | |
| 1588 | |
| 1589 pr = list(data_schema.validate( | |
| 1590 "123", | |
| 1591 {"type": "string", | |
| 1592 "pattern": self._pattern_check_function})) | |
| 1593 self.assertEqual(0, len(pr)) | |
| 1594 | |
| 1595 pr = list(data_schema.validate( | |
| 1596 " 5 ", | |
| 1597 {"type": "string", | |
| 1598 "pattern": self._pattern_check_function})) | |
| 1599 self.assertEqual(1, len(pr)) | |
| 1600 self.assertEqual(10009, pr[0].code) | |
| 1601 | |
| 1602 def test_binary_basic(self): | |
| 1603 pr = list(data_schema.validate( | |
| 1604 b"", | |
| 1605 {"type": "binary"})) | |
| 1606 self.assertEqual(0, len(pr)) | |
| 1607 | |
| 1608 def test_str_is_not_binary(self): | |
| 1609 pr = list(data_schema.validate( | |
| 1610 "", | |
| 1611 {"type": "binary"})) | |
| 1612 self.assertEqual(1, len(pr)) | |
| 1613 self.assertEqual(10035, pr[0].code) | |
| 1614 | |
| 1615 @staticmethod | |
| 1616 def _binary_pattern_check_function(obj, schema, context=None): | |
| 1617 if obj != b"\x00": | |
| 1618 yield data_schema.ValidationProblem(code=10009) | |
| 1619 | |
| 1620 def test_binary_pattern_check(self): | |
| 1621 pr = list(data_schema.validate( | |
| 1622 b"\x00", | |
| 1623 {"type": "binary", | |
| 1624 "pattern": self._binary_pattern_check_function})) | |
| 1625 self.assertEqual(0, len(pr)) | |
| 1626 | |
| 1627 pr = list(data_schema.validate( | |
| 1628 b"\x01", | |
| 1629 {"type": "binary", | |
| 1630 "pattern": self._binary_pattern_check_function})) | |
| 1631 self.assertEqual(1, len(pr)) | |
| 1632 self.assertEqual(10009, pr[0].code) | |
| 1633 | |
| 1634 def test_binary_re_str_match(self): | |
| 1635 pr = list(data_schema.validate( | |
| 1636 b"\x00\x00\x00", | |
| 1637 {"type": "binary", | |
| 1638 "pattern": u"\\x00+"})) | |
| 1639 self.assertEqual(0, len(pr)) | |
| 1640 | |
| 1641 def test_binary_re_bytes_match(self): | |
| 1642 pr = list(data_schema.validate( | |
| 1643 b"\x00\x00\x00", | |
| 1644 {"type": "binary", | |
| 1645 "pattern": b"\x00+"})) | |
| 1646 self.assertEqual(0, len(pr)) | |
| 1647 | |
| 1648 def test_binary_re_str_mismatch(self): | |
| 1649 pr = list(data_schema.validate( | |
| 1650 b"\x00\x00\x00", | |
| 1651 {"type": "binary", | |
| 1652 "pattern": u"\\x01+"})) | |
| 1653 self.assertEqual(1, len(pr)) | |
| 1654 self.assertEqual(10047, pr[0].code) | |
| 1655 | |
| 1656 def test_binary_re_bytes_mismatch(self): | |
| 1657 pr = list(data_schema.validate( | |
| 1658 b"\x00\x00\x00", | |
| 1659 {"type": "binary", | |
| 1660 "pattern": b"\x01+"})) | |
| 1661 self.assertEqual(1, len(pr)) | |
| 1662 self.assertEqual(10047, pr[0].code) | |
| 1663 | |
| 1664 def test_binary_length(self): | |
| 1665 pr = list(data_schema.validate( | |
| 1666 b"", | |
| 1667 {"type": "binary", | |
| 1668 "minLength": 1})) | |
| 1669 self.assertEqual(1, len(pr)) | |
| 1670 self.assertEqual(10036, pr[0].code) | |
| 1671 | |
| 1672 pr = list(data_schema.validate( | |
| 1673 b"1", | |
| 1674 {"type": "binary", | |
| 1675 "maxLength": 0})) | |
| 1676 self.assertEqual(1, len(pr)) | |
| 1677 self.assertEqual(10037, pr[0].code) | |
| 1678 | |
| 1679 def test_deny(self): | |
| 1680 pr = list(data_schema.validate("abc", {"type": "deny"})) | |
| 1681 self.assertEqual(1, len(pr)) | |
| 1682 self.assertEqual(10010, pr[0].code) | |
| 1683 | |
| 1684 def test_accept(self): | |
| 1685 pr = list(data_schema.validate("abc", {"type": "accept"})) | |
| 1686 self.assertEqual(0, len(pr)) | |
| 1687 | |
| 1688 pr = list(data_schema.validate(None, {"type": "accept"})) | |
| 1689 self.assertEqual(0, len(pr)) | |
| 1690 | |
| 1691 def test_null(self): | |
| 1692 pr = list(data_schema.validate(None, {"type": "none"})) | |
| 1693 self.assertEqual(0, len(pr)) | |
| 1694 | |
| 1695 pr = list(data_schema.validate(None, {"type": "null"})) | |
| 1696 self.assertEqual(0, len(pr)) | |
| 1697 | |
| 1698 pr = list(data_schema.validate(None, {"type": "nil"})) | |
| 1699 self.assertEqual(0, len(pr)) | |
| 1700 | |
| 1701 pr = list(data_schema.validate(None, {"type": None})) | |
| 1702 self.assertEqual(0, len(pr)) | |
| 1703 | |
| 1704 pr = list(data_schema.validate({}, {"type": None})) | |
| 1705 self.assertEqual(1, len(pr)) | |
| 1706 self.assertEqual(10011, pr[0].code) | |
| 1707 | |
| 1708 def test_l1(self): | |
| 1709 pr = list(data_schema.validate([], {"type": "list"})) | |
| 1710 self.assertEqual(0, len(pr)) | |
| 1711 | |
| 1712 pr = list(data_schema.validate(tuple(), {"type": "list"})) | |
| 1713 self.assertEqual(0, len(pr)) | |
| 1714 | |
| 1715 def test_l1_not_nullable(self): | |
| 1716 pr = list(data_schema.validate(None, {"type": "list"})) | |
| 1717 self.assertEqual(1, len(pr)) | |
| 1718 self.assertEqual(10001, pr[0].code) | |
| 1719 | |
| 1720 def test_l1_nullable(self): | |
| 1721 pr = list(data_schema.validate( | |
| 1722 None, {"type": "list", "nullable": True})) | |
| 1723 self.assertEqual(0, len(pr)) | |
| 1724 | |
| 1725 def test_l2_default_schema_for_items_is_deny(self): | |
| 1726 pr = list(data_schema.validate(["a", "b", "c"], {"type": "list"})) | |
| 1727 self.assertEqual(3, len(pr)) | |
| 1728 for i in range(0, 3): | |
| 1729 self.assertEqual(10010, pr[i].code) | |
| 1730 | |
| 1731 def test_l3_schema_for_items(self): | |
| 1732 pr = list(data_schema.validate( | |
| 1733 ["a", "b", "c"], | |
| 1734 {"type": "array", | |
| 1735 "items": {"type": "string"}})) | |
| 1736 self.assertEqual(0, len(pr)) | |
| 1737 | |
| 1738 def test_t1(self): | |
| 1739 pr = list(data_schema.validate([], {"type": "tuple"})) | |
| 1740 self.assertEqual(0, len(pr)) | |
| 1741 | |
| 1742 pr = list(data_schema.validate(tuple(), {"type": "tuple"})) | |
| 1743 self.assertEqual(0, len(pr)) | |
| 1744 | |
| 1745 def test_t1_not_nullable(self): | |
| 1746 pr = list(data_schema.validate(None, {"type": "tuple"})) | |
| 1747 self.assertEqual(1, len(pr)) | |
| 1748 self.assertEqual(10014, pr[0].code) | |
| 1749 | |
| 1750 def test_t1_nullable(self): | |
| 1751 pr = list(data_schema.validate( | |
| 1752 None, {"type": "tuple", "nullable": True})) | |
| 1753 self.assertEqual(0, len(pr)) | |
| 1754 | |
| 1755 def test_t2(self): | |
| 1756 pr = list(data_schema.validate( | |
| 1757 ["a", None, {"key": "value"}], | |
| 1758 {"type": "tuple", | |
| 1759 "items": [ | |
| 1760 {"type": "string"}, | |
| 1761 {"type": None}, | |
| 1762 {"type": "accept"}]})) | |
| 1763 self.assertEqual(0, len(pr)) | |
| 1764 | |
| 1765 def test_t3(self): | |
| 1766 pr = list(data_schema.validate( | |
| 1767 ["a", None, {"key": "value"}], | |
| 1768 {"type": "tuple", | |
| 1769 "items": [ | |
| 1770 {"type": "string"}, | |
| 1771 {"type": None}, | |
| 1772 {"type": "deny"}]})) | |
| 1773 self.assertEqual(1, len(pr)) | |
| 1774 self.assertEqual(10010, pr[0].code) | |
| 1775 self.assertEqual(2, pr[0].context.index) | |
| 1776 | |
| 1777 def test_t4(self): | |
| 1778 pr = list(data_schema.validate( | |
| 1779 ["a", None, {"key": "value"}], | |
| 1780 {"type": "tuple", | |
| 1781 "items": [ | |
| 1782 {"type": "string"}, | |
| 1783 {"type": None}]})) | |
| 1784 self.assertEqual(1, len(pr)) | |
| 1785 self.assertEqual(10017, pr[0].code) | |
| 1786 self.assertEqual(2, pr[0].context.index) | |
| 1787 | |
| 1788 def test_t5(self): | |
| 1789 pr = list(data_schema.validate( | |
| 1790 ["a", None, {"key": "value"}], | |
| 1791 {"type": "tuple", | |
| 1792 "items": [ | |
| 1793 {"type": "string"}, | |
| 1794 {"type": None}], | |
| 1795 "additionalItems": True})) | |
| 1796 self.assertEqual(0, len(pr)) | |
| 1797 | |
| 1798 def test_t6(self): | |
| 1799 pr = list(data_schema.validate( | |
| 1800 ["a", None, {"key": "value"}, {"key": "value"}], | |
| 1801 {"type": "tuple", | |
| 1802 "items": [ | |
| 1803 {"type": "string"}, | |
| 1804 {"type": None}], | |
| 1805 "additionalItems": { | |
| 1806 "type": "dict", | |
| 1807 "keys": {"key": {"type": "string"}} | |
| 1808 }})) | |
| 1809 self.assertEqual(0, len(pr)) | |
| 1810 | |
| 1811 def test_t7(self): | |
| 1812 # do not check anything that exceeds maxLength | |
| 1813 pr = list(data_schema.validate( | |
| 1814 ["a", None, {"key": "value"}, {"key": "value"}, {"key2": "value"}], | |
| 1815 {"type": "tuple", | |
| 1816 "maxLength": 4, | |
| 1817 "items": [ | |
| 1818 {"type": "string"}, | |
| 1819 {"type": None}], | |
| 1820 "additionalItems": { | |
| 1821 "type": "dict", | |
| 1822 "keys": {"key": {"type": "string"}} | |
| 1823 }})) | |
| 1824 self.assertEqual(1, len(pr)) | |
| 1825 self.assertEqual(10016, pr[0].code) | |
| 1826 | |
| 1827 def test_t8(self): | |
| 1828 # do not check anything that exceeds maxLength | |
| 1829 pr = list(data_schema.validate( | |
| 1830 ["a", None, {"key": "value"}, {"key": "value"}, {"key2": "value"}], | |
| 1831 {"type": "tuple", | |
| 1832 "minLength": 6, | |
| 1833 "maxLength": 4, | |
| 1834 "items": [ | |
| 1835 {"type": "string"}, | |
| 1836 {"type": None}], | |
| 1837 "additionalItems": { | |
| 1838 "type": "dict", | |
| 1839 "keys": {"key": {"type": "string"}} | |
| 1840 }})) | |
| 1841 self.assertEqual(2, len(pr)) | |
| 1842 self.assertEqual(10015, pr[0].code) | |
| 1843 self.assertEqual(10016, pr[1].code) | |
| 1844 | |
| 1845 def test_set1(self): | |
| 1846 # do not check anything that exceeds maxLength | |
| 1847 pr = list(data_schema.validate( | |
| 1848 set(["a", None, "b"]), | |
| 1849 {"type": "set", | |
| 1850 "minLength": 3, | |
| 1851 "items": {"any-of": [ | |
| 1852 {"type": "string"}, | |
| 1853 {"type": None}]}} | |
| 1854 )) | |
| 1855 self.assertEqual(0, len(pr)) | |
| 1856 | |
| 1857 def test_set1_not_nullable(self): | |
| 1858 # do not check anything that exceeds maxLength | |
| 1859 pr = list(data_schema.validate( | |
| 1860 None, | |
| 1861 {"type": "set"})) | |
| 1862 self.assertEqual(1, len(pr)) | |
| 1863 self.assertEqual(10038, pr[0].code) | |
| 1864 | |
| 1865 def test_set1_nullable(self): | |
| 1866 # do not check anything that exceeds maxLength | |
| 1867 pr = list(data_schema.validate( | |
| 1868 None, | |
| 1869 {"type": "set", "nullable": True})) | |
| 1870 self.assertEqual(0, len(pr)) | |
| 1871 | |
| 1872 def test_set2(self): | |
| 1873 # do not check anything that exceeds maxLength | |
| 1874 pr = list(data_schema.validate( | |
| 1875 set(["a", None, "b"]), | |
| 1876 {"type": "set", | |
| 1877 "minLength": 4, | |
| 1878 "items": {"any-of": [ | |
| 1879 {"type": "string"}, | |
| 1880 {"type": None}]}} | |
| 1881 )) | |
| 1882 self.assertEqual(1, len(pr)) | |
| 1883 self.assertEqual(10039, pr[0].code) | |
| 1884 | |
| 1885 def test_set3(self): | |
| 1886 # do not check anything that exceeds maxLength | |
| 1887 pr = list(data_schema.validate( | |
| 1888 set(["a", None, "b"]), | |
| 1889 {"type": "set", | |
| 1890 "maxLength": 2, | |
| 1891 "items": {"any-of": [ | |
| 1892 {"type": "string"}, | |
| 1893 {"type": None}]}} | |
| 1894 )) | |
| 1895 self.assertEqual(1, len(pr)) | |
| 1896 self.assertEqual(10040, pr[0].code) | |
| 1897 | |
| 1898 def test_set4_itemschema(self): | |
| 1899 pr = list(data_schema.validate( | |
| 1900 set(["a", None, "b"]), | |
| 1901 {"type": "set", | |
| 1902 "items": {"any-of": [ | |
| 1903 {"type": "string"}, | |
| 1904 {"type": "int"}]}} | |
| 1905 )) | |
| 1906 codes = set([p.code for p in pr]) | |
| 1907 | |
| 1908 self.assertEqual(1, len(pr)) | |
| 1909 self.assertEqual(10055, pr[0].code) | |
| 1910 self.assertEqual(2, len(pr[0].cause)) | |
| 1911 self.assertEqual(10056, pr[0].cause[0].code) | |
| 1912 self.assertEqual(1, len(pr[0].cause[0].cause)) | |
| 1913 self.assertEqual(10002, pr[0].cause[0].cause[0].code) | |
| 1914 self.assertEqual(10056, pr[0].cause[1].code) | |
| 1915 self.assertEqual(1, len(pr[0].cause[1].cause)) | |
| 1916 self.assertEqual(10020, pr[0].cause[1].cause[0].code) | |
| 1917 | |
| 1918 def test_empty(self): | |
| 1919 pr = list(data_schema.validate(None, {"type": "empty"})) | |
| 1920 self.assertEqual(0, len(pr)) | |
| 1921 | |
| 1922 pr = list(data_schema.validate([], {"type": "empty"})) | |
| 1923 self.assertEqual(0, len(pr)) | |
| 1924 | |
| 1925 pr = list(data_schema.validate(["a"], {"type": "empty"})) | |
| 1926 self.assertEqual(1, len(pr)) | |
| 1927 self.assertEqual(10018, pr[0].code) | |
| 1928 | |
| 1929 pr = list(data_schema.validate(tuple(), {"type": "empty"})) | |
| 1930 self.assertEqual(0, len(pr)) | |
| 1931 | |
| 1932 pr = list(data_schema.validate(set(), {"type": "empty"})) | |
| 1933 self.assertEqual(0, len(pr)) | |
| 1934 | |
| 1935 pr = list(data_schema.validate(frozenset(), {"type": "empty"})) | |
| 1936 self.assertEqual(0, len(pr)) | |
| 1937 | |
| 1938 pr = list(data_schema.validate(tuple(["a"]), {"type": "empty"})) | |
| 1939 self.assertEqual(1, len(pr)) | |
| 1940 self.assertEqual(10018, pr[0].code) | |
| 1941 | |
| 1942 pr = list(data_schema.validate({}, {"type": "empty"})) | |
| 1943 self.assertEqual(0, len(pr)) | |
| 1944 | |
| 1945 pr = list(data_schema.validate({"key": "value"}, {"type": "empty"})) | |
| 1946 self.assertEqual(1, len(pr)) | |
| 1947 self.assertEqual(10018, pr[0].code) | |
| 1948 | |
| 1949 pr = list(data_schema.validate("", {"type": "empty"})) | |
| 1950 self.assertEqual(1, len(pr)) | |
| 1951 self.assertEqual(10018, pr[0].code) | |
| 1952 | |
| 1953 def test_allOf(self): | |
| 1954 pr = list(data_schema.validate( | |
| 1955 None, | |
| 1956 {"type": { | |
| 1957 "all-of": [ | |
| 1958 {"type": None}, | |
| 1959 {"type": "accept"}, | |
| 1960 ] | |
| 1961 }})) | |
| 1962 self.assertEqual(0, len(pr)) | |
| 1963 | |
| 1964 pr = list(data_schema.validate( | |
| 1965 None, | |
| 1966 {"type": { | |
| 1967 "all-of": [ | |
| 1968 {"type": None}, | |
| 1969 {"type": "accept"}, | |
| 1970 {"type": "deny"}, | |
| 1971 ] | |
| 1972 }})) | |
| 1973 self.assertEqual(1, len(pr)) | |
| 1974 self.assertEqual(10057, pr[0].code) | |
| 1975 self.assertEqual(1, len(pr[0].cause)) | |
| 1976 self.assertEqual(10058, pr[0].cause[0].code) | |
| 1977 self.assertEqual(1, len(pr[0].cause[0].cause)) | |
| 1978 self.assertEqual(10010, pr[0].cause[0].cause[0].code) | |
| 1979 | |
| 1980 def test_anyOf(self): | |
| 1981 pr = list(data_schema.validate( | |
| 1982 None, | |
| 1983 {"type": { | |
| 1984 "any-of": [ | |
| 1985 {"type": "deny"}, | |
| 1986 {"type": None}, | |
| 1987 ] | |
| 1988 }})) | |
| 1989 self.assertEqual(0, len(pr)) | |
| 1990 | |
| 1991 pr = list(data_schema.validate( | |
| 1992 None, | |
| 1993 {"type": { | |
| 1994 "any-of": [ | |
| 1995 {"type": "string"}, | |
| 1996 {"type": "deny"}, | |
| 1997 ] | |
| 1998 }})) | |
| 1999 self.assertEqual(1, len(pr)) | |
| 2000 self.assertEqual(10055, pr[0].code) | |
| 2001 self.assertEqual(2, len(pr[0].cause)) | |
| 2002 self.assertEqual(10056, pr[0].cause[0].code) | |
| 2003 self.assertEqual(1, len(pr[0].cause[0].cause)) | |
| 2004 self.assertEqual(10002, pr[0].cause[0].cause[0].code) | |
| 2005 self.assertEqual(10056, pr[0].cause[1].code) | |
| 2006 self.assertEqual(1, len(pr[0].cause[1].cause)) | |
| 2007 self.assertEqual(10010, pr[0].cause[1].cause[0].code) | |
| 2008 | |
| 2009 def test_anyOf_with_list(self): | |
| 2010 pr = list(data_schema.validate( | |
| 2011 None, | |
| 2012 {"type": [ | |
| 2013 {"type": "deny"}, | |
| 2014 {"type": None}, | |
| 2015 ]})) | |
| 2016 self.assertEqual(0, len(pr)) | |
| 2017 | |
| 2018 pr = list(data_schema.validate( | |
| 2019 None, | |
| 2020 {"type": [ | |
| 2021 {"type": "string"}, | |
| 2022 {"type": "deny"}, | |
| 2023 ]})) | |
| 2024 self.assertEqual(1, len(pr)) | |
| 2025 self.assertEqual(10055, pr[0].code) | |
| 2026 self.assertEqual(2, len(pr[0].cause)) | |
| 2027 self.assertEqual(10056, pr[0].cause[0].code) | |
| 2028 self.assertEqual(1, len(pr[0].cause[0].cause)) | |
| 2029 self.assertEqual(10002, pr[0].cause[0].cause[0].code) | |
| 2030 self.assertEqual(10056, pr[0].cause[1].code) | |
| 2031 self.assertEqual(1, len(pr[0].cause[1].cause)) | |
| 2032 self.assertEqual(10010, pr[0].cause[1].cause[0].code) | |
| 2033 | |
| 2034 def test_oneOf(self): | |
| 2035 pr = list(data_schema.validate( | |
| 2036 None, | |
| 2037 {"type": { | |
| 2038 "one-of": [ | |
| 2039 {"type": "deny"}, | |
| 2040 {"type": None}, | |
| 2041 ] | |
| 2042 }})) | |
| 2043 self.assertEqual(0, len(pr)) | |
| 2044 | |
| 2045 pr = list(data_schema.validate( | |
| 2046 None, | |
| 2047 {"type": { | |
| 2048 "one-of": [ | |
| 2049 {"type": "string"}, | |
| 2050 {"type": "deny"}, | |
| 2051 ] | |
| 2052 }})) | |
| 2053 | |
| 2054 self.assertEqual(1, len(pr)) | |
| 2055 self.assertEqual(10053, pr[0].code) | |
| 2056 self.assertEqual(2, len(pr[0].cause)) | |
| 2057 self.assertEqual(10054, pr[0].cause[0].code) | |
| 2058 self.assertEqual(1, len(pr[0].cause[0].cause)) | |
| 2059 self.assertEqual(10002, pr[0].cause[0].cause[0].code) | |
| 2060 self.assertEqual(10054, pr[0].cause[1].code) | |
| 2061 self.assertEqual(1, len(pr[0].cause[1].cause)) | |
| 2062 self.assertEqual(10010, pr[0].cause[1].cause[0].code) | |
| 2063 | |
| 2064 pr = list(data_schema.validate( | |
| 2065 None, | |
| 2066 {"type": { | |
| 2067 "one-of": [ | |
| 2068 {"type": "string"}, | |
| 2069 {"type": "deny"}, | |
| 2070 {"type": "empty"}, | |
| 2071 {"type": None}, | |
| 2072 ] | |
| 2073 }})) | |
| 2074 self.assertEqual(1, len(pr)) | |
| 2075 self.assertEqual(10019, pr[0].code) | |
| 2076 self.assertEqual("2,3", pr[0].hint) | |
| 2077 | |
| 2078 def test_not(self): | |
| 2079 pr = list(data_schema.validate( | |
| 2080 None, | |
| 2081 {"type": { | |
| 2082 "not": { | |
| 2083 "type": "empty"}}})) | |
| 2084 self.assertEqual(1, len(pr)) | |
| 2085 self.assertEqual(10029, pr[0].code) | |
| 2086 | |
| 2087 pr = list(data_schema.validate( | |
| 2088 None, | |
| 2089 {"type": { | |
| 2090 "not": { | |
| 2091 "type": { | |
| 2092 "not": { | |
| 2093 "type": "empty"}}}}})) | |
| 2094 self.assertEqual(0, len(pr)) | |
| 2095 | |
| 2096 pr = list(data_schema.validate( | |
| 2097 2, | |
| 2098 {"type": { | |
| 2099 "not": { | |
| 2100 "type": "int"}}})) | |
| 2101 self.assertEqual(1, len(pr)) | |
| 2102 self.assertEqual(10029, pr[0].code) | |
| 2103 | |
| 2104 pr = list(data_schema.validate( | |
| 2105 1, | |
| 2106 {"type": { | |
| 2107 "not": { | |
| 2108 "type": { | |
| 2109 "not": { | |
| 2110 "type": "int"}}}}})) | |
| 2111 self.assertEqual(0, len(pr)) | |
| 2112 | |
| 2113 pr = list(data_schema.validate( | |
| 2114 2.0, | |
| 2115 {"type": { | |
| 2116 "not": { | |
| 2117 "type": "int"}}})) | |
| 2118 self.assertEqual(0, len(pr)) | |
| 2119 | |
| 2120 def test_not_shortcut(self): | |
| 2121 pr = list(data_schema.validate( | |
| 2122 None, | |
| 2123 {"not": { | |
| 2124 "type": "empty"}})) | |
| 2125 self.assertEqual(1, len(pr)) | |
| 2126 self.assertEqual(10029, pr[0].code) | |
| 2127 | |
| 2128 pr = list(data_schema.validate( | |
| 2129 None, | |
| 2130 {"not": { | |
| 2131 "not": { | |
| 2132 "type": "empty"}}})) | |
| 2133 self.assertEqual(0, len(pr)) | |
| 2134 | |
| 2135 pr = list(data_schema.validate( | |
| 2136 2, | |
| 2137 {"not": { | |
| 2138 "type": "int"}})) | |
| 2139 self.assertEqual(1, len(pr)) | |
| 2140 self.assertEqual(10029, pr[0].code) | |
| 2141 | |
| 2142 pr = list(data_schema.validate( | |
| 2143 1, | |
| 2144 {"not": { | |
| 2145 "not": { | |
| 2146 "type": "int"}}})) | |
| 2147 self.assertEqual(0, len(pr)) | |
| 2148 | |
| 2149 pr = list(data_schema.validate( | |
| 2150 2.0, | |
| 2151 {"not": { | |
| 2152 "type": "int"}})) | |
| 2153 self.assertEqual(0, len(pr)) | |
| 2154 | |
| 2155 def test_integer(self): | |
| 2156 pr = list(data_schema.validate(1, {"type": "integer"})) | |
| 2157 self.assertEqual(0, len(pr)) | |
| 2158 | |
| 2159 pr = list(data_schema.validate(1, {"type": "float"})) | |
| 2160 self.assertEqual(1, len(pr)) | |
| 2161 self.assertEqual(10023, pr[0].code) | |
| 2162 | |
| 2163 pr = list(data_schema.validate( | |
| 2164 2, | |
| 2165 {"type": "int", | |
| 2166 "minValue": 3, | |
| 2167 "maxValue": 1})) | |
| 2168 | |
| 2169 self.assertEqual(2, len(pr)) | |
| 2170 self.assertEqual(10021, pr[0].code) | |
| 2171 self.assertEqual(10022, pr[1].code) | |
| 2172 | |
| 2173 def test_float(self): | |
| 2174 pr = list(data_schema.validate(1.8, {"type": "float"})) | |
| 2175 self.assertEqual(0, len(pr)) | |
| 2176 | |
| 2177 pr = list(data_schema.validate(1, {"type": "float"})) | |
| 2178 self.assertEqual(1, len(pr)) | |
| 2179 self.assertEqual(10023, pr[0].code) | |
| 2180 | |
| 2181 pr = list(data_schema.validate( | |
| 2182 2.0, | |
| 2183 {"type": "real", | |
| 2184 "minValue": 2.1, | |
| 2185 "maxValue": 1.9})) | |
| 2186 | |
| 2187 self.assertEqual(2, len(pr)) | |
| 2188 self.assertEqual(10024, pr[0].code) | |
| 2189 self.assertEqual(10025, pr[1].code) | |
| 2190 | |
| 2191 def test_number(self): | |
| 2192 pr = list(data_schema.validate(1.8, {"type": "number"})) | |
| 2193 self.assertEqual(0, len(pr)) | |
| 2194 pr = list(data_schema.validate(1, {"type": "num"})) | |
| 2195 self.assertEqual(0, len(pr)) | |
| 2196 | |
| 2197 pr = list(data_schema.validate( | |
| 2198 2.0, | |
| 2199 {"type": "number", | |
| 2200 "minValue": 3, | |
| 2201 "maxValue": 1.3})) | |
| 2202 | |
| 2203 self.assertEqual(2, len(pr)) | |
| 2204 self.assertEqual(10031, pr[0].code) | |
| 2205 self.assertEqual(10032, pr[1].code) | |
| 2206 | |
| 2207 pr = list(data_schema.validate({}, {"type": "number"})) | |
| 2208 self.assertEqual(1, len(pr)) | |
| 2209 self.assertEqual(10030, pr[0].code) | |
| 2210 | |
| 2211 def test_bool(self): | |
| 2212 pr = list(data_schema.validate(True, {"type": "bool"})) | |
| 2213 self.assertEqual(0, len(pr)) | |
| 2214 | |
| 2215 pr = list(data_schema.validate(True, {"type": "boolean", | |
| 2216 "value": True})) | |
| 2217 self.assertEqual(0, len(pr)) | |
| 2218 | |
| 2219 pr = list(data_schema.validate(True, {"type": "boolean", | |
| 2220 "value": False})) | |
| 2221 self.assertEqual(1, len(pr)) | |
| 2222 self.assertEqual(10028, pr[0].code) | |
| 2223 | |
| 2224 pr = list(data_schema.validate(False, {"type": "boolean"})) | |
| 2225 self.assertEqual(0, len(pr)) | |
| 2226 | |
| 2227 pr = list(data_schema.validate(False, {"type": "boolean", | |
| 2228 "value": False})) | |
| 2229 self.assertEqual(0, len(pr)) | |
| 2230 | |
| 2231 pr = list(data_schema.validate(False, {"type": "boolean", | |
| 2232 "value": True})) | |
| 2233 self.assertEqual(1, len(pr)) | |
| 2234 self.assertEqual(10027, pr[0].code) | |
| 2235 | |
| 2236 def test_bool_real(self): | |
| 2237 pr = list(data_schema.validate([1, 2], {"type": "bool"})) | |
| 2238 self.assertEqual(1, len(pr)) | |
| 2239 self.assertEqual(10026, pr[0].code) | |
| 2240 | |
| 2241 pr = list(data_schema.validate([], {"type": "bool"})) | |
| 2242 self.assertEqual(1, len(pr)) | |
| 2243 self.assertEqual(10026, pr[0].code) | |
| 2244 | |
| 2245 pr = list(data_schema.validate(None, {"type": "bool"})) | |
| 2246 self.assertEqual(1, len(pr)) | |
| 2247 self.assertEqual(10026, pr[0].code) | |
| 2248 | |
| 2249 @staticmethod | |
| 2250 def _check_value_ts(obj, schema, context): | |
| 2251 if obj == datetime.datetime.fromtimestamp(0): | |
| 2252 yield data_schema.ValidationProblem( | |
| 2253 code=10042, hint=obj, context=context) | |
| 2254 | |
| 2255 def test_timestamp(self): | |
| 2256 pr = list(data_schema.validate( | |
| 2257 datetime.datetime.utcnow(), | |
| 2258 {"type": "timestamp"})) | |
| 2259 | |
| 2260 pr = list(data_schema.validate( | |
| 2261 datetime.datetime.fromtimestamp(180000), | |
| 2262 {"type": "datetime", | |
| 2263 "value": self._check_value_ts})) | |
| 2264 self.assertEqual(0, len(pr)) | |
| 2265 | |
| 2266 pr = list(data_schema.validate( | |
| 2267 datetime.datetime.fromtimestamp(0), | |
| 2268 {"type": "datetime", | |
| 2269 "value": self._check_value_ts})) | |
| 2270 self.assertEqual(1, len(pr)) | |
| 2271 self.assertEqual(10042, pr[0].code) | |
| 2272 | |
| 2273 def test_scalar(self): | |
| 2274 pr = list(data_schema.validate(1, {"type": "scalar"})) | |
| 2275 self.assertEqual(0, len(pr)) | |
| 2276 | |
| 2277 pr = list(data_schema.validate("", {"type": "scalar"})) | |
| 2278 self.assertEqual(0, len(pr)) | |
| 2279 | |
| 2280 pr = list(data_schema.validate(False, {"type": "scalar"})) | |
| 2281 self.assertEqual(0, len(pr)) | |
| 2282 | |
| 2283 pr = list(data_schema.validate(datetime.datetime.utcnow(), | |
| 2284 {"type": "scalar"})) | |
| 2285 self.assertEqual(0, len(pr)) | |
| 2286 | |
| 2287 pr = list(data_schema.validate(None, {"type": "scalar"})) | |
| 2288 self.assertEqual(1, len(pr)) | |
| 2289 self.assertEqual(10033, pr[0].code) | |
| 2290 | |
| 2291 pr = list(data_schema.validate({}, {"type": "scalar"})) | |
| 2292 self.assertEqual(1, len(pr)) | |
| 2293 self.assertEqual(10033, pr[0].code) | |
| 2294 | |
| 2295 pr = list(data_schema.validate([], {"type": "scalar"})) | |
| 2296 self.assertEqual(1, len(pr)) | |
| 2297 self.assertEqual(10033, pr[0].code) | |
| 2298 | |
| 2299 pr = list(data_schema.validate(tuple(), {"type": "scalar"})) | |
| 2300 self.assertEqual(1, len(pr)) | |
| 2301 self.assertEqual(10033, pr[0].code) | |
| 2302 | |
| 2303 pr = list(data_schema.validate(set(), {"type": "scalar"})) | |
| 2304 self.assertEqual(1, len(pr)) | |
| 2305 self.assertEqual(10033, pr[0].code) | |
| 2306 | |
| 2307 pr = list(data_schema.validate(frozenset(), {"type": "scalar"})) | |
| 2308 self.assertEqual(1, len(pr)) | |
| 2309 self.assertEqual(10033, pr[0].code) | |
| 2310 | |
| 2311 pr = list(data_schema.validate( | |
| 2312 None, | |
| 2313 {"type": { | |
| 2314 "one-of": [ | |
| 2315 {"type": "scalar"}, | |
| 2316 {"type": None}, | |
| 2317 ]}})) | |
| 2318 self.assertEqual(0, len(pr)) | |
| 2319 | |
| 2320 | |
| 2321 if __name__ == "__main__": | |
| 2322 unittest.main() |
