summaryrefslogtreecommitdiff
path: root/jstests/core/json_schema/additional_items.js
blob: c3866c8856535a97e18ffcfa9594c26a426c828b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// @tags: [requires_non_retryable_commands]

/**
 * Tests the JSON Schema "additionalItems" keyword.
 */
(function() {
    "use strict";

    load("jstests/libs/assert_schema_match.js");

    const coll = db.getCollection("json_schema_additional_items");
    coll.drop();

    // Test that the JSON Schema fails to parse if "additionalItems" is not a boolean or object.
    assert.throws(() => coll.find({$jsonSchema: {additionalItems: 1}}).itcount());
    assert.throws(() => coll.find({$jsonSchema: {additionalItems: 1.0}}).itcount());
    assert.throws(() => coll.find({$jsonSchema: {additionalItems: "true"}}).itcount());

    // Test that "additionalItems" has no effect at the top level (but is still accepted).
    assertSchemaMatch(coll, {items: [{type: "number"}], additionalItems: false}, {}, true);
    assertSchemaMatch(coll, {items: [{type: "number"}], additionalItems: true}, {}, true);
    assertSchemaMatch(
        coll, {items: [{type: "number"}], additionalItems: {type: "string"}}, {}, true);

    // Test that "additionalItems" has no effect when "items" is not present.
    let schema = {properties: {a: {additionalItems: false}}};
    assertSchemaMatch(coll, schema, {}, true);
    assertSchemaMatch(coll, schema, {a: "blah"}, true);
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [1, 2, 3]}, true);

    schema = {properties: {a: {additionalItems: {type: "object"}}}};
    assertSchemaMatch(coll, schema, {}, true);
    assertSchemaMatch(coll, schema, {a: "blah"}, true);
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [1, 2, 3]}, true);

    // Test that "additionalItems" has no effect when "items" is a schema that applies to every
    // element in the array.
    schema = {properties: {a: {items: {}, additionalItems: false}}};
    assertSchemaMatch(coll, schema, {}, true);
    assertSchemaMatch(coll, schema, {a: "blah"}, true);
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [1, 2, 3]}, true);

    schema = {properties: {a: {items: {}, additionalItems: {type: "object"}}}};
    assertSchemaMatch(coll, schema, {}, true);
    assertSchemaMatch(coll, schema, {a: "blah"}, true);
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [1, 2, 3]}, true);

    // Test that {additionalItems: false} correctly bans array indexes not covered by "items".
    schema = {
        properties: {a: {items: [{type: "number"}, {type: "string"}], additionalItems: false}}
    };
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [229]}, true);
    assertSchemaMatch(coll, schema, {a: [229, "West 43rd"]}, true);
    assertSchemaMatch(coll, schema, {a: [229, "West 43rd", "Street"]}, false);

    // Test that {additionalItems: true} has no effect.
    assertSchemaMatch(
        coll,
        {properties: {a: {items: [{type: "number"}, {type: "string"}], additionalItems: true}}},
        {a: [229, "West 43rd", "Street"]},
        true);
    assertSchemaMatch(
        coll, {properties: {a: {items: [{not: {}}], additionalItems: true}}}, {a: []}, true);

    // Test that the "additionalItems" schema only applies to array indexes not covered by "items".
    schema = {
        properties:
            {a: {items: [{type: "number"}, {type: "string"}], additionalItems: {type: "object"}}}
    };
    assertSchemaMatch(coll, schema, {a: []}, true);
    assertSchemaMatch(coll, schema, {a: [229]}, true);
    assertSchemaMatch(coll, schema, {a: [229, "West 43rd"]}, true);
    assertSchemaMatch(coll, schema, {a: [229, "West 43rd", "Street"]}, false);
    assertSchemaMatch(coll, schema, {a: [229, "West 43rd", {}]}, true);

    // Test that an empty array does not fail against "additionalItems".
    assertSchemaMatch(
        coll, {properties: {a: {items: [{not: {}}], additionalItems: false}}}, {a: []}, true);
    assertSchemaMatch(
        coll, {properties: {a: {items: [{not: {}}], additionalItems: {not: {}}}}}, {a: []}, true);
}());