summaryrefslogtreecommitdiff
path: root/jstests/core/json_schema/logical_keywords.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/core/json_schema/logical_keywords.js')
-rw-r--r--jstests/core/json_schema/logical_keywords.js482
1 files changed, 264 insertions, 218 deletions
diff --git a/jstests/core/json_schema/logical_keywords.js b/jstests/core/json_schema/logical_keywords.js
index 507123e2c69..3b7895f27cd 100644
--- a/jstests/core/json_schema/logical_keywords.js
+++ b/jstests/core/json_schema/logical_keywords.js
@@ -10,222 +10,268 @@
* - enum
*/
(function() {
- "use strict";
-
- load("jstests/libs/assert_schema_match.js");
-
- const coll = db.jstests_json_schema_logical;
-
- // Test that $jsonSchema fails to parse if the values for the allOf, anyOf, and oneOf
- // keywords are not arrays of valid schema.
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {allOf: {maximum: "0"}}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {allOf: [0]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {allOf: [{invalid: "0"}]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {anyOf: {maximum: "0"}}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {anyOf: [0]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {anyOf: [{invalid: "0"}]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {oneOf: {maximum: "0"}}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {oneOf: [0]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {oneOf: [{invalid: "0"}]}}}}).itcount();
- });
-
- // Test that $jsonSchema fails to parse if the value for the 'not' keyword is not a
- // valid schema object.
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {not: {maximum: "0"}}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {not: [0]}}}}).itcount();
- });
- assert.throws(function() {
- coll.find({$jsonSchema: {properties: {foo: {not: [{}]}}}}).itcount();
- });
-
- // Test that the 'allOf' keyword correctly returns documents that match every schema in
- // the array.
- let schema = {properties: {foo: {allOf: [{minimum: 1}]}}};
- assertSchemaMatch(coll, schema, {foo: 1}, true);
- assertSchemaMatch(coll, schema, {foo: 0}, false);
- assertSchemaMatch(coll, schema, {foo: "string"}, true);
-
- schema = {properties: {foo: {allOf: [{}]}}};
- assertSchemaMatch(coll, schema, {foo: {}}, true);
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: 0}, true);
-
- schema = {properties: {foo: {allOf: [{type: 'number'}, {minimum: 0}]}}};
- assertSchemaMatch(coll, schema, {foo: 0}, true);
- assertSchemaMatch(coll, schema, {foo: "string"}, false);
- assertSchemaMatch(coll, schema, {foo: [0]}, false);
-
- // Test that a top-level 'allOf' keyword matches the correct documents.
- assertSchemaMatch(coll, {allOf: [{}]}, {}, true);
- assertSchemaMatch(coll, {allOf: [{}]}, {foo: 0}, true);
- assertSchemaMatch(coll, {allOf: [{type: 'string'}]}, {}, false);
- assertSchemaMatch(coll, {allOf: [{properties: {foo: {type: 'string'}}}]}, {foo: "str"}, true);
- assertSchemaMatch(coll, {allOf: [{properties: {foo: {type: 'string'}}}]}, {foo: 1}, false);
-
- // Test that 'allOf' in conjunction with another keyword matches the correct documents.
- assertSchemaMatch(
- coll, {properties: {foo: {type: "number", allOf: [{minimum: 1}]}}}, {foo: 1}, true);
- assertSchemaMatch(
- coll, {properties: {foo: {type: "number", allOf: [{minimum: 1}]}}}, {foo: "str"}, false);
-
- // Test that the 'anyOf' keyword correctly returns documents that match at least one schema
- // in the array.
- schema = {properties: {foo: {anyOf: [{type: 'string'}, {type: 'number', minimum: 1}]}}};
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, true);
- assertSchemaMatch(coll, schema, {foo: 0}, false);
-
- schema = {properties: {foo: {anyOf: [{type: 'string'}, {type: 'object'}]}}};
- assertSchemaMatch(coll, schema, {foo: {}}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: [{}]}, false);
-
- schema = {properties: {foo: {anyOf: [{}]}}};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: {}}, true);
- assertSchemaMatch(coll, schema, {foo: 0}, true);
-
- // Test that a top-level 'anyOf' keyword matches the correct documents.
- schema = {anyOf: [{}]};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, true);
-
- schema = {anyOf: [{properties: {foo: {type: 'string'}}}]};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
-
- // Test that 'anyOf' in conjunction with another keyword matches the correct documents.
- schema = {properties: {foo: {type: "number", anyOf: [{minimum: 1}]}}};
- assertSchemaMatch(coll, schema, {foo: 1}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, false);
-
- // Test that the 'oneOf' keyword correctly returns documents that match exactly one schema
- // in the array.
- schema = {properties: {foo: {oneOf: [{minimum: 0}, {maximum: 3}]}}};
- assertSchemaMatch(coll, schema, {foo: 4}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
- assertSchemaMatch(coll, schema, {foo: "str"}, false);
-
- schema = {properties: {foo: {oneOf: [{type: 'string'}, {pattern: "ing"}]}}};
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: "string"}, false);
-
- schema = {properties: {foo: {oneOf: [{}]}}};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, true);
-
- // Test that a top-level 'oneOf' keyword matches the correct documents.
- schema = {oneOf: [{}]};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, true);
-
- schema = {oneOf: [{properties: {foo: {type: 'string'}}}]};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
-
- assertSchemaMatch(coll, {oneOf: [{}, {}]}, {}, false);
-
- // Test that 'oneOf' in conjunction with another keyword matches the correct documents.
- schema = {properties: {foo: {type: "number", oneOf: [{minimum: 4}]}}};
- assertSchemaMatch(coll, schema, {foo: 4}, true);
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, false);
-
- // Test that the 'not' keyword correctly returns documents that do not match any schema
- // in the array.
- schema = {properties: {foo: {not: {type: 'number'}}}};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
-
- schema = {properties: {foo: {not: {}}}};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
-
- // Test that a top-level 'not' keyword matches the correct documents.
- assertSchemaMatch(coll, {not: {}}, {}, false);
-
- schema = {not: {properties: {foo: {type: 'string'}}}};
- assertSchemaMatch(coll, schema, {foo: 1}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, false);
- assertSchemaMatch(coll, schema, {}, false);
-
- // Test that 'not' in conjunction with another keyword matches the correct documents.
- schema = {properties: {foo: {type: "string", not: {maxLength: 4}}}};
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {foo: "string"}, true);
- assertSchemaMatch(coll, schema, {foo: "str"}, false);
- assertSchemaMatch(coll, schema, {foo: 1}, false);
-
- // Test that the 'enum' keyword correctly matches scalar values.
- schema = {properties: {a: {enum: ["str", 5]}}};
- assertSchemaMatch(coll, schema, {a: "str"}, true);
- assertSchemaMatch(coll, schema, {a: 5}, true);
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {a: ["str"]}, false);
-
- // Test that the 'enum' keyword with a null value correctly matches literal null elements, but
- // not 'missing' or 'undefined.
- schema = {properties: {a: {enum: [null]}}};
- assertSchemaMatch(coll, schema, {a: null}, true);
- assertSchemaMatch(coll, schema, {a: undefined}, false);
- assertSchemaMatch(coll, schema, {a: 1}, false);
- assertSchemaMatch(coll, {properties: {a: {enum: [null]}}, required: ['a']}, {}, false);
-
- // Test that the 'enum' keyword correctly matches array values.
- schema = {properties: {a: {enum: [[1, 2, "3"]]}}};
- assertSchemaMatch(coll, schema, {a: [1, 2, "3"]}, true);
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {a: [2, "3", 1]}, false);
-
- schema = {properties: {a: {enum: [[]]}}};
- assertSchemaMatch(coll, schema, {a: []}, true);
- assertSchemaMatch(coll, schema, {}, true);
- assertSchemaMatch(coll, schema, {a: [1]}, false);
-
- // Test that the 'enum' keyword does not traverse arrays when matching.
- schema = {properties: {a: {enum: ["str", 1]}}};
- assertSchemaMatch(coll, schema, {a: ["str"]}, false);
- assertSchemaMatch(coll, schema, {a: [1]}, false);
-
- // Test that the 'enum' keyword matches objects regardless of the field ordering.
- schema = {properties: {a: {enum: [{name: "tiny", size: "large"}]}}};
- assertSchemaMatch(coll, schema, {a: {name: "tiny", size: "large"}}, true);
- assertSchemaMatch(coll, schema, {a: {size: "large", name: "tiny"}}, true);
-
- // Test that the 'enum' keyword does not match documents with additional fields.
- assertSchemaMatch(coll,
- {properties: {a: {enum: [{name: "tiny"}]}}},
- {a: {size: "large", name: "tiny"}},
- false);
-
- // Test that a top-level 'enum' matches the correct documents.
- assertSchemaMatch(coll, {enum: [{_id: 0}]}, {_id: 0}, true);
- assertSchemaMatch(coll, {enum: [{_id: 0, a: "str"}]}, {_id: 0, a: "str"}, true);
- assertSchemaMatch(coll, {enum: [{}]}, {}, false);
- assertSchemaMatch(coll, {enum: [null]}, {}, false);
- assertSchemaMatch(coll, {enum: [{_id: 0, a: "str"}]}, {_id: 0, a: "str", b: 1}, false);
- assertSchemaMatch(coll, {enum: [1, 2]}, {}, false);
+"use strict";
+
+load("jstests/libs/assert_schema_match.js");
+
+const coll = db.jstests_json_schema_logical;
+
+// Test that $jsonSchema fails to parse if the values for the allOf, anyOf, and oneOf
+// keywords are not arrays of valid schema.
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {allOf: {maximum: "0"}}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {allOf: [0]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {allOf: [{invalid: "0"}]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {anyOf: {maximum: "0"}}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {anyOf: [0]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {anyOf: [{invalid: "0"}]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {oneOf: {maximum: "0"}}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {oneOf: [0]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {oneOf: [{invalid: "0"}]}}}}).itcount();
+});
+
+// Test that $jsonSchema fails to parse if the value for the 'not' keyword is not a
+// valid schema object.
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {not: {maximum: "0"}}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {not: [0]}}}}).itcount();
+});
+assert.throws(function() {
+ coll.find({$jsonSchema: {properties: {foo: {not: [{}]}}}}).itcount();
+});
+
+// Test that the 'allOf' keyword correctly returns documents that match every schema in
+// the array.
+let schema = {properties: {foo: {allOf: [{minimum: 1}]}}};
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+assertSchemaMatch(coll, schema, {foo: 0}, false);
+assertSchemaMatch(coll, schema, {foo: "string"}, true);
+
+schema = {
+ properties: {foo: {allOf: [{}]}}
+};
+assertSchemaMatch(coll, schema, {foo: {}}, true);
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: 0}, true);
+
+schema = {
+ properties: {foo: {allOf: [{type: 'number'}, {minimum: 0}]}}
+};
+assertSchemaMatch(coll, schema, {foo: 0}, true);
+assertSchemaMatch(coll, schema, {foo: "string"}, false);
+assertSchemaMatch(coll, schema, {foo: [0]}, false);
+
+// Test that a top-level 'allOf' keyword matches the correct documents.
+assertSchemaMatch(coll, {allOf: [{}]}, {}, true);
+assertSchemaMatch(coll, {allOf: [{}]}, {foo: 0}, true);
+assertSchemaMatch(coll, {allOf: [{type: 'string'}]}, {}, false);
+assertSchemaMatch(coll, {allOf: [{properties: {foo: {type: 'string'}}}]}, {foo: "str"}, true);
+assertSchemaMatch(coll, {allOf: [{properties: {foo: {type: 'string'}}}]}, {foo: 1}, false);
+
+// Test that 'allOf' in conjunction with another keyword matches the correct documents.
+assertSchemaMatch(
+ coll, {properties: {foo: {type: "number", allOf: [{minimum: 1}]}}}, {foo: 1}, true);
+assertSchemaMatch(
+ coll, {properties: {foo: {type: "number", allOf: [{minimum: 1}]}}}, {foo: "str"}, false);
+
+// Test that the 'anyOf' keyword correctly returns documents that match at least one schema
+// in the array.
+schema = {
+ properties: {foo: {anyOf: [{type: 'string'}, {type: 'number', minimum: 1}]}}
+};
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+assertSchemaMatch(coll, schema, {foo: 0}, false);
+
+schema = {
+ properties: {foo: {anyOf: [{type: 'string'}, {type: 'object'}]}}
+};
+assertSchemaMatch(coll, schema, {foo: {}}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: [{}]}, false);
+
+schema = {
+ properties: {foo: {anyOf: [{}]}}
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: {}}, true);
+assertSchemaMatch(coll, schema, {foo: 0}, true);
+
+// Test that a top-level 'anyOf' keyword matches the correct documents.
+schema = {
+ anyOf: [{}]
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+
+schema = {
+ anyOf: [{properties: {foo: {type: 'string'}}}]
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+
+// Test that 'anyOf' in conjunction with another keyword matches the correct documents.
+schema = {
+ properties: {foo: {type: "number", anyOf: [{minimum: 1}]}}
+};
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, false);
+
+// Test that the 'oneOf' keyword correctly returns documents that match exactly one schema
+// in the array.
+schema = {
+ properties: {foo: {oneOf: [{minimum: 0}, {maximum: 3}]}}
+};
+assertSchemaMatch(coll, schema, {foo: 4}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+assertSchemaMatch(coll, schema, {foo: "str"}, false);
+
+schema = {
+ properties: {foo: {oneOf: [{type: 'string'}, {pattern: "ing"}]}}
+};
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: "string"}, false);
+
+schema = {
+ properties: {foo: {oneOf: [{}]}}
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+
+// Test that a top-level 'oneOf' keyword matches the correct documents.
+schema = {
+ oneOf: [{}]
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+
+schema = {
+ oneOf: [{properties: {foo: {type: 'string'}}}]
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+
+assertSchemaMatch(coll, {oneOf: [{}, {}]}, {}, false);
+
+// Test that 'oneOf' in conjunction with another keyword matches the correct documents.
+schema = {
+ properties: {foo: {type: "number", oneOf: [{minimum: 4}]}}
+};
+assertSchemaMatch(coll, schema, {foo: 4}, true);
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, false);
+
+// Test that the 'not' keyword correctly returns documents that do not match any schema
+// in the array.
+schema = {
+ properties: {foo: {not: {type: 'number'}}}
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+
+schema = {
+ properties: {foo: {not: {}}}
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+
+// Test that a top-level 'not' keyword matches the correct documents.
+assertSchemaMatch(coll, {not: {}}, {}, false);
+
+schema = {
+ not: {properties: {foo: {type: 'string'}}}
+};
+assertSchemaMatch(coll, schema, {foo: 1}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, false);
+assertSchemaMatch(coll, schema, {}, false);
+
+// Test that 'not' in conjunction with another keyword matches the correct documents.
+schema = {
+ properties: {foo: {type: "string", not: {maxLength: 4}}}
+};
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {foo: "string"}, true);
+assertSchemaMatch(coll, schema, {foo: "str"}, false);
+assertSchemaMatch(coll, schema, {foo: 1}, false);
+
+// Test that the 'enum' keyword correctly matches scalar values.
+schema = {
+ properties: {a: {enum: ["str", 5]}}
+};
+assertSchemaMatch(coll, schema, {a: "str"}, true);
+assertSchemaMatch(coll, schema, {a: 5}, true);
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {a: ["str"]}, false);
+
+// Test that the 'enum' keyword with a null value correctly matches literal null elements, but
+// not 'missing' or 'undefined.
+schema = {
+ properties: {a: {enum: [null]}}
+};
+assertSchemaMatch(coll, schema, {a: null}, true);
+assertSchemaMatch(coll, schema, {a: undefined}, false);
+assertSchemaMatch(coll, schema, {a: 1}, false);
+assertSchemaMatch(coll, {properties: {a: {enum: [null]}}, required: ['a']}, {}, false);
+
+// Test that the 'enum' keyword correctly matches array values.
+schema = {
+ properties: {a: {enum: [[1, 2, "3"]]}}
+};
+assertSchemaMatch(coll, schema, {a: [1, 2, "3"]}, true);
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {a: [2, "3", 1]}, false);
+
+schema = {
+ properties: {a: {enum: [[]]}}
+};
+assertSchemaMatch(coll, schema, {a: []}, true);
+assertSchemaMatch(coll, schema, {}, true);
+assertSchemaMatch(coll, schema, {a: [1]}, false);
+
+// Test that the 'enum' keyword does not traverse arrays when matching.
+schema = {
+ properties: {a: {enum: ["str", 1]}}
+};
+assertSchemaMatch(coll, schema, {a: ["str"]}, false);
+assertSchemaMatch(coll, schema, {a: [1]}, false);
+
+// Test that the 'enum' keyword matches objects regardless of the field ordering.
+schema = {
+ properties: {a: {enum: [{name: "tiny", size: "large"}]}}
+};
+assertSchemaMatch(coll, schema, {a: {name: "tiny", size: "large"}}, true);
+assertSchemaMatch(coll, schema, {a: {size: "large", name: "tiny"}}, true);
+
+// Test that the 'enum' keyword does not match documents with additional fields.
+assertSchemaMatch(
+ coll, {properties: {a: {enum: [{name: "tiny"}]}}}, {a: {size: "large", name: "tiny"}}, false);
+
+// Test that a top-level 'enum' matches the correct documents.
+assertSchemaMatch(coll, {enum: [{_id: 0}]}, {_id: 0}, true);
+assertSchemaMatch(coll, {enum: [{_id: 0, a: "str"}]}, {_id: 0, a: "str"}, true);
+assertSchemaMatch(coll, {enum: [{}]}, {}, false);
+assertSchemaMatch(coll, {enum: [null]}, {}, false);
+assertSchemaMatch(coll, {enum: [{_id: 0, a: "str"}]}, {_id: 0, a: "str", b: 1}, false);
+assertSchemaMatch(coll, {enum: [1, 2]}, {}, false);
}());