From 8bbc1a21072a455a8f8fd6ef6c3ea0f44e117f84 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 3 Mar 2018 10:35:40 +0000 Subject: [PATCH] fix: uniqueItems when item type is array of types, closes #727 --- lib/dot/uniqueItems.jst | 14 +++-- spec/tests/rules/uniqueItems.json | 88 +++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/lib/dot/uniqueItems.jst b/lib/dot/uniqueItems.jst index 77f0ede..22f82f9 100644 --- a/lib/dot/uniqueItems.jst +++ b/lib/dot/uniqueItems.jst @@ -18,8 +18,12 @@ , {{=$valid}} = true , j; if (i > 1) { - {{ var $itemType = it.schema.items && it.schema.items.type; }} - {{? !$itemType || $itemType == 'object' || $itemType == 'array' }} + {{ + var $itemType = it.schema.items && it.schema.items.type + , $typeIsArray = Array.isArray($itemType); + }} + {{? !$itemType || $itemType == 'object' || $itemType == 'array' || + ($typeIsArray && ($itemType.indexOf('object') >= 0 || $itemType.indexOf('array') >= 0)) }} outer: for (;i--;) { for (j = i; j--;) { @@ -33,7 +37,11 @@ var itemIndices = {}, item; for (;i--;) { var item = {{=$data}}[i]; - if (typeof item != '{{=$itemType}}') continue; + {{ var $method = 'checkDataType' + ($typeIsArray ? 's' : ''); }} + if ({{= it.util[$method]($itemType, 'item', true) }}) continue; + {{? $typeIsArray}} + if (typeof item == 'string') item = '"' + item; + {{?}} if (typeof itemIndices[item] == 'number') { {{=$valid}} = false; j = itemIndices[item]; diff --git a/spec/tests/rules/uniqueItems.json b/spec/tests/rules/uniqueItems.json index 2618ac5..d283d20 100644 --- a/spec/tests/rules/uniqueItems.json +++ b/spec/tests/rules/uniqueItems.json @@ -7,17 +7,17 @@ }, "tests": [ { - "description": "array of unique strings are valid", + "description": "array of unique strings is valid", "data": ["foo", "bar", "baz"], "valid": true }, { - "description": "array of unique items with strings that are properties of hash are valid", + "description": "array of unique items with strings that are properties of hash is valid", "data": ["toString", "foo"], "valid": true }, { - "description": "array of non-unique strings are invalid", + "description": "array of non-unique strings is invalid", "data": ["foo", "bar", "bar"], "valid": false }, @@ -27,5 +27,87 @@ "valid": false } ] + }, + { + "description": "uniqueItems with multiple types when the list of types includes array", + "schema": { + "items": { "type": ["array", "string"] }, + "uniqueItems": true + }, + "tests": [ + { + "description": "array of unique items is valid", + "data": [[1], [2], "foo"], + "valid": true + }, + { + "description": "array of non-unique items is invalid", + "data": [[1], [1], "foo"], + "valid": false + }, + { + "description": "array with incorrect type is invalid", + "data": [{}, 1, 2], + "valid": false + } + ] + }, + { + "description": "uniqueItems with multiple types when the list of types includes object", + "schema": { + "items": { "type": ["object", "string"] }, + "uniqueItems": true + }, + "tests": [ + { + "description": "array of unique items is valid", + "data": [{"a": 1}, {"b": 2}, "foo"], + "valid": true + }, + { + "description": "array of non-unique items is invalid", + "data": [{"a": 1}, {"a": 1}, "foo"], + "valid": false + }, + { + "description": "array with incorrect type is invalid", + "data": [[], 1, 2], + "valid": false + } + ] + }, + { + "description": "uniqueItems with multiple types when all types are scalar", + "schema": { + "items": { "type": ["number", "string", "boolean", "null"] }, + "uniqueItems": true + }, + "tests": [ + { + "description": "array of unique items is valid (string/number)", + "data": ["1", 1, 2], + "valid": true + }, + { + "description": "array of unique items is valid (string/boolean)", + "data": ["true", true, false], + "valid": true + }, + { + "description": "array of unique items is valid (string/null)", + "data": ["null", null, 0], + "valid": true + }, + { + "description": "array of non-unique items is invalid", + "data": [1, 1, 2], + "valid": false + }, + { + "description": "array with incorrect type is invalid", + "data": [[], 1, 2], + "valid": false + } + ] } ]