mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
1300 lines
46 KiB
Java
1300 lines
46 KiB
Java
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
|
package com.jetbrains.jsonSchema;
|
|
|
|
import com.intellij.codeInspection.InspectionProfileEntry;
|
|
import com.intellij.json.JsonLanguage;
|
|
import com.intellij.openapi.fileTypes.LanguageFileType;
|
|
import com.intellij.openapi.util.io.FileUtil;
|
|
import com.intellij.openapi.util.text.StringUtil;
|
|
import com.intellij.openapi.vfs.VirtualFile;
|
|
import com.intellij.testFramework.PlatformTestUtil;
|
|
import com.jetbrains.jsonSchema.impl.inspections.JsonSchemaComplianceInspection;
|
|
import com.jetbrains.jsonSchema.impl.inspections.JsonSchemaDeprecationInspection;
|
|
import org.intellij.lang.annotations.Language;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.function.Predicate;
|
|
|
|
public class JsonSchemaHighlightingTest extends JsonSchemaHighlightingTestBase {
|
|
@NotNull
|
|
@Override
|
|
protected String getTestDataPath() {
|
|
return PlatformTestUtil.getCommunityPath() + "/json/tests/testData/jsonSchema/highlighting";
|
|
}
|
|
|
|
@Override
|
|
protected String getTestFileName() {
|
|
return "config.json";
|
|
}
|
|
|
|
@Override
|
|
protected InspectionProfileEntry getInspectionProfile() {
|
|
return new JsonSchemaComplianceInspection();
|
|
}
|
|
|
|
@Override
|
|
protected Predicate<VirtualFile> getAvailabilityPredicate() {
|
|
return file -> file.getFileType() instanceof LanguageFileType && ((LanguageFileType)file.getFileType()).getLanguage().isKindOf(
|
|
JsonLanguage.INSTANCE);
|
|
}
|
|
|
|
public void testNumberMultipleWrong() {
|
|
doTest("{ \"properties\": { \"prop\": {\"type\": \"number\", \"multipleOf\": 2}}}",
|
|
"{ \"prop\": <warning descr=\"Is not multiple of 2\">3</warning>}");
|
|
}
|
|
|
|
public void testNumberMultipleCorrect() {
|
|
doTest("{ \"properties\": { \"prop\": {\"type\": \"number\", \"multipleOf\": 2}}}", "{ \"prop\": 4}");
|
|
}
|
|
|
|
public void testNumberMinMax() {
|
|
doTest("""
|
|
{ "properties": { "prop": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 100,
|
|
"exclusiveMaximum": true
|
|
}}}""", "{ \"prop\": 14}");
|
|
}
|
|
|
|
public void testEnum() {
|
|
@Language("JSON") final String schema = "{\"properties\": {\"prop\": {\"enum\": [1,2,3,\"18\"]}}}";
|
|
doTest(schema, "{\"prop\": <warning descr=\"Value should be one of: 1, 2, 3, \\\"18\\\"\">18</warning>}");
|
|
doTest(schema, "{\"prop\": 2}");
|
|
doTest(schema, "{\"prop\": \"18\"}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Value should be one of: 1, 2, 3, \\\"18\\\"\">\"2\"</warning>}");
|
|
}
|
|
|
|
public void testSimpleString() {
|
|
@Language("JSON") final String schema = "{\"properties\": {\"prop\": {\"type\": \"string\", \"minLength\": 2, \"maxLength\": 3}}}";
|
|
doTest(schema, "{\"prop\": <warning descr=\"String is shorter than 2\">\"s\"</warning>}");
|
|
doTest(schema, "{\"prop\": \"sh\"}");
|
|
doTest(schema, "{\"prop\": \"sho\"}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"String is longer than 3\">\"shor\"</warning>}");
|
|
}
|
|
|
|
public void testArray() {
|
|
@Language("JSON") final String schema = schema("""
|
|
{
|
|
"type": "array",
|
|
"items": {
|
|
"type": "number", "minimum": 18 }
|
|
}""");
|
|
doTest(schema, "{\"prop\": [101, 102]}");
|
|
doTest(schema, "{\"prop\": [<warning descr=\"Less than the minimum 18\">16</warning>]}");
|
|
doTest(schema, "{\"prop\": [<warning descr=\"Incompatible types.\n Required: number. Actual: string.\">\"test\"</warning>]}");
|
|
}
|
|
|
|
public void testTopLevelArray() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"type": "array",
|
|
"items": {
|
|
"type": "number", "minimum": 18 }
|
|
}""";
|
|
doTest(schema, "[101, 102]");
|
|
}
|
|
|
|
public void testTopLevelObjectArray() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object", "properties": {"a": {"type": "number"}} }
|
|
}""";
|
|
doTest(schema, "[{\"a\": <warning descr=\"Incompatible types.\n Required: number. Actual: boolean.\">true</warning>}]");
|
|
doTest(schema, "[{\"a\": 18}]");
|
|
}
|
|
|
|
public void testArrayTuples1() {
|
|
@Language("JSON") final String schema = schema("""
|
|
{
|
|
"type": "array",
|
|
"items": [{
|
|
"type": "number", "minimum": 18 }, {"type" : "string"}]
|
|
}""");
|
|
doTest(schema, "{\"prop\": [101, <warning descr=\"Incompatible types.\n Required: string. Actual: integer.\">102</warning>]}");
|
|
doTest(schema, "{\"prop\": [101, \"102\"]}");
|
|
doTest(schema, "{\"prop\": [101, \"102\", \"additional\"]}");
|
|
}
|
|
|
|
public void testArrayTuples2() {
|
|
@Language("JSON") final String schema2 = schema("""
|
|
{
|
|
"type": "array",
|
|
"items": [{
|
|
"type": "number", "minimum": 18 }, {"type" : "string"}],
|
|
"additionalItems": false}""");
|
|
doTest(schema2, "{\"prop\": [101, \"102\", <warning descr=\"Additional items are not allowed\">\"additional\"</warning>]}");
|
|
}
|
|
|
|
public void testArrayLength() {
|
|
@Language("JSON") final String schema = schema("{\"type\": \"array\", \"minItems\": 2, \"maxItems\": 3}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Array is shorter than 2\">[]</warning>}");
|
|
doTest(schema, "{\"prop\": [1,2]}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Array is longer than 3\">[1,2,3,4]</warning>}");
|
|
}
|
|
|
|
public void testArrayUnique() {
|
|
@Language("JSON") final String schema = schema("{\"type\": \"array\", \"uniqueItems\": true}");
|
|
doTest(schema, "{\"prop\": [1,2]}");
|
|
doTest(schema, "{\"prop\": [<warning descr=\"Item is not unique\">1</warning>,2, \"test\", <warning descr=\"Item is not unique\">1</warning>]}");
|
|
}
|
|
|
|
public void testMetadataIsOk() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"title" : "Match anything",
|
|
"description" : "This is a schema that matches anything.",
|
|
"default" : "Default value"
|
|
}""";
|
|
doTest(schema, "{\"anything\": 1}");
|
|
}
|
|
|
|
public void testRequiredField() {
|
|
@Language("JSON") final String schema = "{\"type\": \"object\", \"properties\": {\"a\": {}, \"b\": {}}, \"required\": [\"a\"]}";
|
|
doTest(schema, "{\"a\": 11}");
|
|
doTest(schema, "{\"a\": 1, \"b\": true}");
|
|
doTest(schema, "{<warning descr=\"Missing required property 'a'\" textAttributesKey=\"WARNING_ATTRIBUTES\">\"b\": \"alarm\"</warning>}");
|
|
}
|
|
|
|
public void testInnerRequired() {
|
|
@Language("JSON") final String schema = schema("{\"type\": \"object\", \"properties\": {\"a\": {}, \"b\": {}}, \"required\": [\"a\"]}");
|
|
doTest(schema, "{\"prop\": {\"a\": 11}}");
|
|
doTest(schema, "{\"prop\": {\"a\": 1, \"b\": true}}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Missing required property 'a'\">{\"b\": \"alarm\"}</warning>}");
|
|
}
|
|
|
|
public void testUseDefinition() {
|
|
@Language("JSON") final String schema = "{\"definitions\": {\"address\": {\"type\": \"object\", \"properties\": {\"street\": {\"type\": \"string\"}," +
|
|
"\"house\": {\"type\": \"integer\"}}}}," +
|
|
"\"type\": \"object\", \"properties\": {" +
|
|
"\"home\": {\"$ref\": \"#/definitions/address\"}, " +
|
|
"\"office\": {\"$ref\": \"#/definitions/address\"}" +
|
|
"}}";
|
|
doTest(schema, "{\"home\": {\"street\": \"Broadway\", \"house\": 11}}");
|
|
doTest(schema, """
|
|
{"home": {"street": "Broadway", "house": <warning descr="Incompatible types.
|
|
Required: integer. Actual: string.">"unknown"</warning>},"office": {"street": <warning descr="Incompatible types.
|
|
Required: string. Actual: integer.">5</warning>}}""");
|
|
}
|
|
|
|
public void testAdditionalPropertiesAllowed() {
|
|
@Language("JSON") final String schema = schema("{}");
|
|
doTest(schema, "{\"prop\": {}, \"someStuff\": 20}");
|
|
}
|
|
|
|
public void testAdditionalPropertiesDisabled() {
|
|
@Language("JSON") final String schema = "{\"type\": \"object\", \"properties\": {\"prop\": {}}, \"additionalProperties\": false}";
|
|
// not sure abt inner object
|
|
doTest(schema, "{\"prop\": {}, <warning descr=\"Property 'someStuff' is not allowed\">\"someStuff\"</warning>: 20}");
|
|
}
|
|
|
|
public void testAdditionalPropertiesSchema() {
|
|
@Language("JSON") final String schema = "{\"type\": \"object\", \"properties\": {\"a\": {}}," +
|
|
"\"additionalProperties\": {\"type\": \"string\"}}";
|
|
doTest(schema, "{\"a\" : 18, \"b\": \"wall\", \"c\": <warning descr=\"Incompatible types.\n Required: string. Actual: integer.\">11</warning>}");
|
|
}
|
|
|
|
public void testMinMaxProperties() {
|
|
@Language("JSON") final String schema = "{\"type\": \"object\", \"minProperties\": 1, \"maxProperties\": 2}";
|
|
doTest(schema, "<warning descr=\"Number of properties is less than 1\">{}</warning>");
|
|
doTest(schema, "{\"a\": 1}");
|
|
doTest(schema, "{<warning descr=\"Number of properties is greater than 2\" textAttributesKey=\"WARNING_ATTRIBUTES\">\"a\": 1</warning>, \"b\": 22, \"c\": 33}");
|
|
}
|
|
|
|
public void testOneOf() {
|
|
final List<String> subSchemas = new ArrayList<>();
|
|
subSchemas.add("{\"type\": \"string\"}");
|
|
subSchemas.add("{\"type\": \"boolean\"}");
|
|
@Language("JSON") final String schema = schema("{\"oneOf\": [" + StringUtil.join(subSchemas, ", ") + "]}");
|
|
doTest(schema, "{\"prop\": \"abc\"}");
|
|
doTest(schema, "{\"prop\": true}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Incompatible types.\n Required one of: boolean, string. Actual: integer.\">11</warning>}");
|
|
}
|
|
|
|
public void testOneOfForTwoMatches() {
|
|
final List<String> subSchemas = new ArrayList<>();
|
|
subSchemas.add("{\"type\": \"string\", \"enum\": [\"a\", \"b\"]}");
|
|
subSchemas.add("{\"type\": \"string\", \"enum\": [\"a\", \"c\"]}");
|
|
@Language("JSON") final String schema = schema("{\"oneOf\": [" + StringUtil.join(subSchemas, ", ") + "]}");
|
|
doTest(schema, "{\"prop\": \"b\"}");
|
|
doTest(schema, "{\"prop\": \"c\"}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Validates to more than one variant\">\"a\"</warning>}");
|
|
}
|
|
|
|
public void testOneOfSelectError() {
|
|
final List<String> subSchemas = new ArrayList<>();
|
|
subSchemas.add("""
|
|
{"type": "string",
|
|
"enum": [
|
|
"off", "warn", "error"
|
|
]}""");
|
|
subSchemas.add("{\"type\": \"integer\"}");
|
|
@Language("JSON") final String schema = schema("{\"oneOf\": [" + StringUtil.join(subSchemas, ", ") + "]}");
|
|
doTest(schema, "{\"prop\": \"off\"}");
|
|
doTest(schema, "{\"prop\": 12}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Value should be one of: \\\"off\\\", \\\"warn\\\", \\\"error\\\"\">\"wrong\"</warning>}");
|
|
}
|
|
|
|
public void testAnyOf() {
|
|
final List<String> subSchemas = new ArrayList<>();
|
|
subSchemas.add("{\"type\": \"string\", \"enum\": [\"a\", \"b\"]}");
|
|
subSchemas.add("{\"type\": \"string\", \"enum\": [\"a\", \"c\"]}");
|
|
@Language("JSON") final String schema = schema("{\"anyOf\": [" + StringUtil.join(subSchemas, ", ") + "]}");
|
|
doTest(schema, "{\"prop\": \"b\"}");
|
|
doTest(schema, "{\"prop\": \"c\"}");
|
|
doTest(schema, "{\"prop\": \"a\"}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Value should be one of: \\\"a\\\", \\\"b\\\", \\\"c\\\"\">\"d\"</warning>}");
|
|
}
|
|
|
|
public void testAllOf() {
|
|
final List<String> subSchemas = new ArrayList<>();
|
|
subSchemas.add("{\"type\": \"integer\", \"multipleOf\": 2}");
|
|
subSchemas.add("{\"enum\": [1,2,3]}");
|
|
@Language("JSON") final String schema = schema("{\"allOf\": [" + StringUtil.join(subSchemas, ", ") + "]}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Is not multiple of 2\">1</warning>}");
|
|
doTest(schema, "{\"prop\": <warning descr=\"Value should be one of: 1, 2, 3\">4</warning>}");
|
|
doTest(schema, "{\"prop\": 2}");
|
|
}
|
|
|
|
public void testObjectInArray() {
|
|
@Language("JSON") final String schema = schema("{\"type\": \"array\", \"items\": {\"type\": \"object\"," +
|
|
"\"properties\": {" +
|
|
"\"innerType\":{}, \"innerValue\":{}" +
|
|
"}, \"additionalProperties\": false" +
|
|
"}}");
|
|
doTest(schema, "{\"prop\": [{\"innerType\":{}, <warning descr=\"Property 'alien' is not allowed\">\"alien\"</warning>:{}}]}");
|
|
}
|
|
|
|
public void testObjectDeeperInArray() {
|
|
final String innerTypeSchema = "{\"properties\": {\"only\": {}}, \"additionalProperties\": false}";
|
|
@Language("JSON") final String schema = schema("{\"type\": \"array\", \"items\": {\"type\": \"object\"," +
|
|
"\"properties\": {" +
|
|
"\"innerType\":" + innerTypeSchema +
|
|
"}, \"additionalProperties\": false" +
|
|
"}}");
|
|
doTest(schema,
|
|
"{\"prop\": [{\"innerType\":{\"only\": true, <warning descr=\"Property 'hidden' is not allowed\">\"hidden\"</warning>: false}}]}");
|
|
}
|
|
|
|
public void testInnerObjectPropValueInArray() {
|
|
@Language("JSON") final String schema = "{\"properties\": {\"prop\": {\"type\": \"array\", \"items\": {\"enum\": [1,2,3]}}}}";
|
|
doTest(schema, "{\"prop\": [1,3]}");
|
|
doTest(schema, "{\"prop\": [<warning descr=\"Value should be one of: 1, 2, 3\">\"out\"</warning>]}");
|
|
}
|
|
|
|
public void testAllOfProperties() {
|
|
@Language("JSON") final String schema = "{\"allOf\": [{\"type\": \"object\", \"properties\": {\"first\": {}}}," +
|
|
" {\"properties\": {\"second\": {\"enum\": [33,44]}}}], \"additionalProperties\": false}";
|
|
doTest(schema, "{\"first\": {}, \"second\": <warning descr=\"Value should be one of: 33, 44\">null</warning>}");
|
|
doTest(schema, "{\"first\": {}, \"second\": 44, <warning descr=\"Property 'other' is not allowed\">\"other\"</warning>: 15}");
|
|
doTest(schema, "{\"first\": {}, \"second\": <warning descr=\"Value should be one of: 33, 44\">12</warning>}");
|
|
}
|
|
|
|
public void testWithWaySelection() {
|
|
final String subSchema1 = "{\"enum\": [1,2,3,4,5]}";
|
|
final String subSchema2 = "{\"type\": \"array\", \"items\": {\"properties\": {\"kilo\": {}}, \"additionalProperties\": false}}";
|
|
@Language("JSON") final String schema = "{\"properties\": {\"prop\": {\"oneOf\": [" + subSchema1 + ", " + subSchema2 + "]}}}";
|
|
//doTest(schema, "{\"prop\": [{\"kilo\": 20}]}");
|
|
//doTest(schema, "{\"prop\": 5}");
|
|
doTest(schema, "{\"prop\": [{<warning descr=\"Property 'foxtrot' is not allowed\">\"foxtrot\"</warning>: 15, \"kilo\": 20}]}");
|
|
}
|
|
|
|
public void testIntegerTypeWithMinMax() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/integerTypeWithMinMax_schema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/integerTypeWithMinMax.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testOneOf1() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOfSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOf1.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testOneOf2() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOfSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOf2.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testAnyOnePropertySelection() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/anyOnePropertySelectionSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/anyOnePropertySelection.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testAnyOneTypeSelection() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/anyOneTypeSelectionSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/anyOneTypeSelection.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testOneOfWithEmptyPropertyValue() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOfSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOfWithEmptyPropertyValue.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testCycledSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/cycledSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/testCycledSchema.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testWithRootRefCycledSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/cycledWithRootRefSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/testCycledWithRootRefSchema.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testCycledWithRootRefInNotSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/cycledWithRootRefInNotSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/testCycledWithRootRefInNotSchema.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testPatternPropertiesHighlighting() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"patternProperties": {
|
|
"^A" : {
|
|
"type": "number"
|
|
},
|
|
"B": {
|
|
"type": "boolean"
|
|
},
|
|
"C": {
|
|
"enum": ["test", "em"]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, """
|
|
{
|
|
"Abezjana": 2,
|
|
"Auto": <warning descr="Incompatible types.
|
|
Required: number. Actual: string.">"no"</warning>,
|
|
"BAe": <warning descr="Incompatible types.
|
|
Required: boolean. Actual: integer.">22</warning>,
|
|
"Boloto": <warning descr="Incompatible types.
|
|
Required: boolean. Actual: integer.">2</warning>,
|
|
"Cyan": <warning descr="Value should be one of: \\"test\\", \\"em\\"">"me"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testPatternPropertiesFromIssue() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"patternProperties": {
|
|
"p[0-9]": {
|
|
"type": "string"
|
|
},
|
|
"a[0-9]": {
|
|
"enum": ["auto!"]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, """
|
|
{
|
|
"p1": <warning descr="Incompatible types.
|
|
Required: string. Actual: integer.">1</warning>,
|
|
"p2": "3",
|
|
"a2": "auto!",
|
|
"a1": <warning descr="Value should be one of: \\"auto!\\"">"moto!"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testPatternForPropertyValue() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"properties": {
|
|
"withPattern": {
|
|
"pattern": "p[0-9]"
|
|
}
|
|
}
|
|
}""";
|
|
final String correctText = """
|
|
{
|
|
"withPattern": "p1"
|
|
}""";
|
|
final String wrongText = """
|
|
{
|
|
"withPattern": <warning descr="String violates the pattern: 'p[0-9]'">"wrong"</warning>
|
|
}""";
|
|
doTest(schema, correctText);
|
|
doTest(schema, wrongText);
|
|
}
|
|
|
|
public void testPatternWithSpecialEscapedSymbols() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"properties": {
|
|
"withPattern": {
|
|
"pattern": "^\\\\d{4}\\\\-(0?[1-9]|1[012])\\\\-(0?[1-9]|[12][0-9]|3[01])$"
|
|
}
|
|
}
|
|
}""";
|
|
@Language("JSON") final String correctText = """
|
|
{
|
|
"withPattern": "1234-11-11"
|
|
}""";
|
|
final String wrongText = """
|
|
{
|
|
"withPattern": <warning descr="String violates the pattern: '^\\d{4}\\-(0?[1-9]|1[012])\\-(0?[1-9]|[12][0-9]|3[01])$'">"wrong"</warning>
|
|
}""";
|
|
doTest(schema, correctText);
|
|
doTest(schema, wrongText);
|
|
}
|
|
|
|
public void testRootObjectRedefinedAdditionalPropertiesForbidden() {
|
|
doTest(rootObjectRedefinedSchema(), "{<warning descr=\"Property 'a' is not allowed\">\"a\"</warning>: true," +
|
|
"\"r1\": \"allowed!\"}");
|
|
}
|
|
|
|
public void testNumberOfSameNamedPropertiesCorrectlyChecked() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"properties": {
|
|
"size": {
|
|
"type": "object",
|
|
"minProperties": 2,
|
|
"maxProperties": 3,
|
|
"properties": {
|
|
"a": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, """
|
|
{
|
|
"size": {
|
|
"a": <warning descr="Incompatible types.
|
|
Required: boolean. Actual: integer.">1</warning>, "b":3, "c": 4, "a": <warning descr="Incompatible types.
|
|
Required: boolean. Actual: integer.">5</warning>
|
|
}
|
|
}""");
|
|
doTest(schema, """
|
|
{
|
|
"size": <warning descr="Number of properties is greater than 3">{
|
|
"a": true, "b":3, "c": 4, "a": false
|
|
}</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testManyDuplicatesInArray() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"properties": {
|
|
"array":{
|
|
"type": "array",
|
|
"uniqueItems": true
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, "{\"array\": [<warning descr=\"Item is not unique\">1</warning>," +
|
|
"<warning descr=\"Item is not unique\">1</warning>," +
|
|
"<warning descr=\"Item is not unique\">1</warning>," +
|
|
"<warning descr=\"Item is not unique\">2</warning>," +
|
|
"<warning descr=\"Item is not unique\">2</warning>," +
|
|
"5," +
|
|
"<warning descr=\"Item is not unique\">3</warning>," +
|
|
"<warning descr=\"Item is not unique\">3</warning>]}");
|
|
}
|
|
|
|
public void testPropertyValueAlsoHighlightedIfPatternIsInvalid() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"properties": {
|
|
"withPattern": {
|
|
"pattern": "^[]$"
|
|
}
|
|
}
|
|
}""";
|
|
final String text = """
|
|
{"withPattern": <warning descr="Cannot check the string by pattern because of an error: Unclosed character class near index 3
|
|
^[]$
|
|
^">"(124)555-4216"</warning>}""";
|
|
doTest(schema, text);
|
|
}
|
|
|
|
public void testNotSchema() {
|
|
@Language("JSON") final String schema = """
|
|
{"properties": {
|
|
"not_type": { "not": { "type": "string" } }
|
|
}}""";
|
|
doTest(schema, "{\"not_type\": <warning descr=\"Validates against 'not' schema\">\"wrong\"</warning>}");
|
|
}
|
|
|
|
public void testNotSchemaCombinedWithNormal() {
|
|
@Language("JSON") final String schema = """
|
|
{"properties": {
|
|
"not_type": {
|
|
"pattern": "^[a-z]*[0-5]*$",
|
|
"not": { "pattern": "^[a-z]{1}[0-5]$" }
|
|
}
|
|
}}""";
|
|
doTest(schema, "{\"not_type\": \"va4\"}");
|
|
doTest(schema, "{\"not_type\": <warning descr=\"Validates against 'not' schema\">\"a4\"</warning>}");
|
|
doTest(schema, "{\"not_type\": <warning descr=\"String violates the pattern: '^[a-z]*[0-5]*$'\">\"4a4\"</warning>}");
|
|
}
|
|
|
|
public void testDoNotMarkOneOfThatDiffersWithFormat() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
|
|
"properties": {
|
|
"withFormat": {
|
|
"type": "string", "oneOf": [
|
|
{
|
|
"format":"hostname"
|
|
},
|
|
{
|
|
"format": "ip4"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, "{\"withFormat\": \"localhost\"}");
|
|
}
|
|
|
|
public void testAcceptSchemaWithoutType() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
|
|
"properties": {
|
|
"withFormat": {
|
|
"oneOf": [
|
|
{
|
|
"format":"hostname"
|
|
},
|
|
{
|
|
"format": "ip4"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, "{\"withFormat\": \"localhost\"}");
|
|
}
|
|
|
|
public void testArrayItemReference() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"items": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"$ref": "#/items/0"
|
|
}
|
|
]
|
|
}""";
|
|
doTest(schema, "[1, 2]");
|
|
doTest(schema, "[1, <warning>\"foo\"</warning>]");
|
|
}
|
|
|
|
public void testArrayReference() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"definitions": {
|
|
"options": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "number"
|
|
}
|
|
}
|
|
},
|
|
"items":{
|
|
"$ref": "#/definitions/options/items"
|
|
}
|
|
\s
|
|
}""";
|
|
doTest(schema, "[2, 3 ,4]");
|
|
doTest(schema, "[2, <warning>\"3\"</warning>]");
|
|
}
|
|
|
|
public void testSelfArrayReferenceDoesNotThrowSOE() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"items": [
|
|
{
|
|
"$ref": "#/items/0"
|
|
}
|
|
]
|
|
}""";
|
|
doTest(schema, "[]");
|
|
}
|
|
|
|
public void testValidateAdditionalItems() {
|
|
@Language("JSON") final String schema = """
|
|
{
|
|
"definitions": {
|
|
"options": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "number"
|
|
}
|
|
}
|
|
},
|
|
"items": [
|
|
{
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"type": "boolean"
|
|
}
|
|
],
|
|
"additionalItems": {
|
|
"$ref": "#/definitions/options/items"
|
|
}
|
|
}""";
|
|
doTest(schema, "[true, true]");
|
|
doTest(schema, "[true, true, 1, 2, 3]");
|
|
doTest(schema, "[true, true, 1, <warning>\"2\"</warning>]");
|
|
}
|
|
|
|
public static String rootObjectRedefinedSchema() {
|
|
return """
|
|
{
|
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
"type": "object",
|
|
"$ref" : "#/definitions/root",
|
|
"definitions": {
|
|
"root" : {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"r1": {
|
|
"type": "string"
|
|
},
|
|
"r2": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
}
|
|
|
|
static String schema(final String s) {
|
|
return "{\"type\": \"object\", \"properties\": {\"prop\": " + s + "}}";
|
|
}
|
|
|
|
public void testExclusiveMinMaxV6_1() {
|
|
@Language("JSON") String exclusiveMinSchema = "{\"properties\": {\"prop\": {\"exclusiveMinimum\": 3}}}";
|
|
doTest(exclusiveMinSchema, "{\"prop\": <warning>2</warning>}");
|
|
doTest(exclusiveMinSchema, "{\"prop\": <warning>3</warning>}");
|
|
doTest(exclusiveMinSchema, "{\"prop\": 4}");
|
|
}
|
|
|
|
public void testExclusiveMinMaxV6_2() {
|
|
@Language("JSON") String exclusiveMaxSchema = "{\"properties\": {\"prop\": {\"exclusiveMaximum\": 3}}}";
|
|
doTest(exclusiveMaxSchema, "{\"prop\": 2}");
|
|
doTest(exclusiveMaxSchema, "{\"prop\": <warning>3</warning>}");
|
|
doTest(exclusiveMaxSchema, "{\"prop\": <warning>4</warning>}");
|
|
}
|
|
|
|
public void testPropertyNamesV6_1() {
|
|
doTest("{\"propertyNames\": {\"minLength\": 7}}", "{<warning>\"prop\"</warning>: 2}");
|
|
}
|
|
|
|
public void testPropertyNamesV6_2() {
|
|
doTest("{\"properties\": {\"prop\": {\"propertyNames\": {\"minLength\": 7}}}}", "{\"prop\": {<warning>\"qq\"</warning>: 7}}");
|
|
}
|
|
|
|
public void testContainsV6() {
|
|
@Language("JSON") String schema = "{\"properties\": {\"prop\": {\"type\": \"array\", \"contains\": {\"type\": \"number\"}}}}";
|
|
doTest(schema, "{\"prop\": <warning>[{}, \"a\", true]</warning>}");
|
|
doTest(schema, "{\"prop\": [{}, \"a\", 1, true]}");
|
|
}
|
|
|
|
public void testConstV6() {
|
|
@Language("JSON") String schema = "{\"properties\": {\"prop\": {\"type\": \"string\", \"const\": \"foo\"}}}";
|
|
doTest(schema, "{\"prop\": <warning>\"a\"</warning>}");
|
|
doTest(schema, "{\"prop\": <warning>5</warning>}");
|
|
doTest(schema, "{\"prop\": \"foo\"}");
|
|
}
|
|
|
|
public void testIfThenElseV7() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"if": {
|
|
"properties": {
|
|
"a": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": ["a"]
|
|
},
|
|
"then": {
|
|
"properties": {
|
|
"b": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"required": ["b"]
|
|
},
|
|
"else": {
|
|
"properties": {
|
|
"c": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
"required": ["c"]
|
|
}
|
|
}""";
|
|
doTest(schema, "<warning>{}</warning>");
|
|
doTest(schema, "{\"c\": <warning descr=\"Incompatible types.\n Required: boolean. Actual: integer.\">5</warning>}");
|
|
doTest(schema, "{\"c\": true}");
|
|
doTest(schema, "{<warning descr=\"Missing required property 'c'\" textAttributesKey=\"WARNING_ATTRIBUTES\">\"a\": 5</warning>, \"b\": 5}");
|
|
doTest(schema, "{\"a\": 5, \"c\": <warning>5</warning>}");
|
|
doTest(schema, "{\"a\": 5, \"c\": true}");
|
|
doTest(schema, "{<warning descr=\"Missing required property 'b'\" textAttributesKey=\"WARNING_ATTRIBUTES\">\"a\": \"a\"</warning>, \"c\": true}");
|
|
doTest(schema, "{\"a\": \"a\", \"b\": <warning>true</warning>}");
|
|
doTest(schema, "{\"a\": \"a\", \"b\": 5}");
|
|
}
|
|
|
|
public void testNestedOneOf() {
|
|
@Language("JSON") String schema = """
|
|
{"type":"object",
|
|
"oneOf": [
|
|
{
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"oneOf": [
|
|
{
|
|
"pattern": "(good)"
|
|
},
|
|
{
|
|
"pattern": "(ok)"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"pattern": "^(fine)"
|
|
},
|
|
"extra": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": ["type", "extra"]
|
|
}
|
|
]}""";
|
|
|
|
doTest(schema, "{\"type\": \"good\"}");
|
|
doTest(schema, "{\"type\": \"ok\"}");
|
|
doTest(schema, "{\"type\": <warning>\"doog\"</warning>}");
|
|
doTest(schema, "{\"type\": <warning>\"ko\"</warning>}");
|
|
}
|
|
|
|
public void testArrayRefs() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"myDefs": {
|
|
"myArray": [
|
|
{
|
|
"type": "number"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"type": "array",
|
|
"items": [
|
|
{
|
|
"$ref": "#/myDefs/myArray/0"
|
|
},
|
|
{
|
|
"$ref": "#/myDefs/myArray/1"
|
|
}
|
|
]
|
|
}""";
|
|
|
|
doTest(schema, "[1, <warning>2</warning>]");
|
|
doTest(schema, "[<warning>\"1\"</warning>, <warning>2</warning>]");
|
|
doTest(schema, "[<warning>\"1\"</warning>, \"2\"]");
|
|
doTest(schema, "[1, \"2\"]");
|
|
}
|
|
|
|
public void testOneOfInsideAllOf() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"properties": {
|
|
"foo": {
|
|
"allOf": [
|
|
{
|
|
"type": "object"
|
|
}, {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"provider": {
|
|
"enum": ["script"]
|
|
},
|
|
"foo21": {}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"provider": {
|
|
"enum": ["npm"]
|
|
},
|
|
"foo11": {}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}""";
|
|
|
|
doTest(schema, """
|
|
{
|
|
"foo": {
|
|
"provider": "npm"
|
|
}
|
|
}""");
|
|
|
|
doTest(schema, """
|
|
{
|
|
"foo": {
|
|
"provider": "script"
|
|
}
|
|
}""");
|
|
|
|
doTest(schema, """
|
|
{
|
|
"foo": {
|
|
"provider": <warning>"etwasanderes"</warning>
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testOneOfBestChoiceSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/oneOfBestChoiceSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
"results": [
|
|
<warning descr="Missing required properties 'dateOfBirth', 'name'">{
|
|
"type": "person"
|
|
}</warning>
|
|
]
|
|
}""");
|
|
}
|
|
|
|
public void testAnyOfBestChoiceSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/anyOfBestChoiceSchema.json"));
|
|
doTest(schemaText, """
|
|
[
|
|
{
|
|
"directory": "/test",
|
|
"arguments": [
|
|
"a"
|
|
],
|
|
"file": <warning>""</warning>
|
|
}
|
|
]\s""");
|
|
}
|
|
|
|
public void testComplexOneOfSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/complexOneOfSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
"indentation": "tab"
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"indentation": <warning>"ttab"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testEnumCasing() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
"name": { "type": "string", "enum": ["aa", "bb"] }
|
|
}
|
|
}""";
|
|
doTest(schema, """
|
|
{
|
|
"name": "aa"
|
|
}""");
|
|
doTest(schema, """
|
|
{
|
|
"name": <warning>"aA"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testEnumArrayValue() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"properties": {
|
|
"foo": {
|
|
"enum": [ [{"x": 5}, [true], "q"] ]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, "{\"foo\": <warning>5</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>[ ]</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>[{\"x\": 5}]</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>[{\"x\": 5}, true]</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>[{\"x\": 5}, [true]]</warning>}");
|
|
doTest(schema, "{\"foo\": [ { \"x\" : 5 } , [ true ] , \"q\" ]}");
|
|
}
|
|
|
|
public void testEnumObjectValue() {
|
|
@Language("JSON") String schema = """
|
|
{
|
|
"properties": {
|
|
"foo": {
|
|
"enum": [ {"x": 5} ]
|
|
}
|
|
}
|
|
}""";
|
|
doTest(schema, "{\"foo\": <warning>{}</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>{\"x\": 4}</warning>}");
|
|
doTest(schema, "{\"foo\": <warning>{\"x\": true}</warning>}");
|
|
doTest(schema, "{\"foo\": { \r \"x\" : \t 5 \n }}");
|
|
}
|
|
|
|
public void testIntersectingHighlightingRanges() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/avroSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
<warning descr="Missing required property 'items'" textAttributesKey="WARNING_ATTRIBUTES">"type": "array"</warning>
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"type": <warning descr="Value should be one of: \\"array\\", \\"enum\\", \\"fixed\\", \\"map\\", \\"record\\"">"array2"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testMissingMultipleAltPropertySets() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/avroSchema.json"));
|
|
doTest(schemaText, """
|
|
<warning descr="One of the following property sets is required: properties 'type' = record, 'fields', 'name', properties 'type' = enum, 'name', 'symbols', properties 'type' = array, 'items', properties 'type' = map, 'values', or properties 'type' = fixed, 'name', 'size'">{
|
|
\s
|
|
}</warning>""");
|
|
}
|
|
|
|
public void testValidateEnumVsPattern() {
|
|
doTest("""
|
|
{
|
|
"oneOf": [
|
|
{
|
|
"properties": {
|
|
"type": {
|
|
"enum": ["library"],
|
|
"pattern": ".*"
|
|
}
|
|
},
|
|
"required": ["type", "name", "description"]
|
|
},
|
|
{
|
|
"properties": {
|
|
"type": {
|
|
"not": {
|
|
"enum": ["library"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}""", """
|
|
{
|
|
"type": "project",
|
|
"name": "asd",
|
|
"description": "asdasdqwdqw"
|
|
}""");
|
|
}
|
|
|
|
public void testJsonPointerEscapes() {
|
|
doTest("""
|
|
{
|
|
"properties": {
|
|
"q~q/q": {
|
|
"type": "string"
|
|
},
|
|
"a": {
|
|
"$ref": "#/properties/q~0q~1q"
|
|
}
|
|
}
|
|
}""", """
|
|
{
|
|
"a": <warning>1</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testOneOfMultipleBranches() {
|
|
doTest("""
|
|
{
|
|
\t"$schema": "http://json-schema.org/draft-04/schema#",
|
|
|
|
\t"type": "object",
|
|
\t"oneOf": [
|
|
\t\t{
|
|
\t\t\t"properties": {
|
|
\t\t\t\t"startTime": {
|
|
\t\t\t\t\t"type": "string"
|
|
\t\t\t\t}
|
|
\t\t\t}
|
|
\t\t},
|
|
\t\t{
|
|
\t\t\t"properties": {
|
|
\t\t\t\t"startTime": {
|
|
\t\t\t\t\t"type": "number"
|
|
\t\t\t\t}
|
|
\t\t\t}
|
|
\t\t}
|
|
\t]
|
|
}""", """
|
|
{
|
|
"startTime": <warning descr="Incompatible types.
|
|
Required one of: number, string. Actual: null.">null</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testReferenceById() {
|
|
doTest("""
|
|
{
|
|
"$schema": "https://json-schema.org/draft-07/schema",
|
|
"type": "object",
|
|
|
|
"properties": {
|
|
"a": {
|
|
"$id": "#aa",
|
|
"type": "object"
|
|
}
|
|
},
|
|
"patternProperties": {
|
|
"aa": {
|
|
"type": "object"
|
|
},
|
|
"bb": {
|
|
"$ref": "#aa"
|
|
}
|
|
}
|
|
}""", """
|
|
{
|
|
"aa": {
|
|
"type": "string"
|
|
},
|
|
"bb": <warning>578</warning>
|
|
}
|
|
|
|
""");
|
|
}
|
|
|
|
public void testComplicatedConditions() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/complicatedConditions_schema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/complicatedConditions.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testExoticProps() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/exoticPropsSchema.json"));
|
|
String inputText = FileUtil.loadFile(new File(getTestDataPath() + "/exoticProps.json"));
|
|
doTest(schemaText, inputText);
|
|
}
|
|
|
|
public void testLargeInt() {
|
|
// currently we limit it by Java Long range, should be sufficient as per RFC 7159
|
|
doTest("""
|
|
{
|
|
"properties": {
|
|
"x": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
}""", """
|
|
{
|
|
"x": 9223372036854775807
|
|
}""");
|
|
}
|
|
|
|
public void testMultipleIfThenElse() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/multipleIfThenElseSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "1600 Pennsylvania Avenue NW",
|
|
"country": "United States of America",
|
|
"postal_code": "20500"
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "1600 Pennsylvania Avenue NW",
|
|
"country": "Netherlands",
|
|
"postal_code": <warning descr="String violates the pattern: '[0-9]{4} [A-Z]{2}'">"20500"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testDeprecation() throws IOException {
|
|
myFixture.enableInspections(JsonSchemaDeprecationInspection.class);
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/deprecation.json"));
|
|
configureInitially(schemaText,
|
|
"""
|
|
{
|
|
"framework": "vue",
|
|
<weak_warning descr="Property 'directProperty' is deprecated: Baz">"directProperty"</weak_warning>: <warning descr="Incompatible types.
|
|
Required: number. Actual: string.">"foo"</warning>,
|
|
<weak_warning descr="Property 'vue-modifiers' is deprecated: Contribute Vue directives to /contributions/html/vue-directives">"vue-modifiers"</weak_warning>: [{
|
|
"name": "foo"
|
|
}],
|
|
<weak_warning descr="Property 'description-markup' is deprecated: Use top-level property.">"description-markup"</weak_warning>: "html"
|
|
}\
|
|
""", "json");
|
|
myFixture.checkHighlighting(true, false, true);
|
|
}
|
|
|
|
public void testIfThenElseFlat() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/ifThenElseFlatSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "24 Sussex Drive",
|
|
"country": "Canada",
|
|
"postal_code": "K1M 1M4"\s
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "24 Sussex Drive",
|
|
"country": "Canada",
|
|
"postal_code": <warning descr="String violates the pattern: '[A-Z][0-9][A-Z] [0-9][A-Z][0-9]'">"1K1M1M4"</warning>\s
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "24 Madison Cube Garden NYC",
|
|
"country": "United States of America",
|
|
"postal_code": "11222-1111-1111"
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"street_address": "24 Madison Cube Garden NYC",
|
|
"country": "United States of America",
|
|
"postal_code": <warning descr="String violates the pattern: '[0-9]{5}(-[0-9]{4})?'">"1-1111-1111"</warning>
|
|
}""");
|
|
}
|
|
|
|
public void testProhibitAdditionalPropsAlternateBranches() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/prohibitedAlternateBranchesSchema.json"));
|
|
doTest(schemaText, """
|
|
{
|
|
"subject": {
|
|
"discriminator": "first",
|
|
"first": false,
|
|
<warning descr="Property 'second' is not allowed">"second"</warning>: false
|
|
}
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"subject": {
|
|
"discriminator": "second",
|
|
<warning descr="Property 'first' is not allowed">"first"</warning>: false,
|
|
"second": false
|
|
}
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"subject": {
|
|
"discriminator": "second",
|
|
"second": false
|
|
}
|
|
}""");
|
|
doTest(schemaText, """
|
|
{
|
|
"subject": {
|
|
"discriminator": "first",
|
|
"first": false
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testPropertyNamesRef() {
|
|
doTest("""
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"definitions": {
|
|
"Ref": {
|
|
"enum": ["a", "b", "c"]
|
|
}
|
|
},
|
|
"patternProperties": {
|
|
".*": {
|
|
"propertyNames": {
|
|
"$ref": "#/definitions/Ref"
|
|
}
|
|
}
|
|
}
|
|
}""", """
|
|
{
|
|
"Name": {
|
|
<warning>"d"</warning>: "a"
|
|
}
|
|
}""");
|
|
}
|
|
|
|
public void testCaseInsensitive() {
|
|
doTest("""
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"additionalProperties": {
|
|
"x-intellij-case-insensitive": true,
|
|
"enum": ["aa", "bb"]
|
|
}
|
|
}""", "{\"q\": \"aA\", \"r\": \"Bb\", \"s\": <warning>\"aB\"</warning>}");
|
|
}
|
|
|
|
public void testFunctionSchema() throws Exception {
|
|
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/functionSchema.json"));
|
|
doTest(schemaText, "{\"bindings\": [\"queueTrigger\"]}");
|
|
}
|
|
|
|
public void testLargeInteger() {
|
|
doTest("""
|
|
{
|
|
"properties": {
|
|
"sampled": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
}""", """
|
|
{
|
|
"sampled": 15123456789\s
|
|
}
|
|
""");
|
|
}
|
|
|
|
public void testReducedTopLevelRangeHighlighting() {
|
|
doTest("{ \"required\": [\"test3\"]}",
|
|
"{ <warning descr=\"Missing required property 'test3'\">\"test1\": 123</warning>, \"test2\": 456}");
|
|
}
|
|
|
|
public void testTopLevelRangeHighlighting() {
|
|
doTest("{ \"required\": [\"test3\"]}",
|
|
"<warning descr=\"Missing required property 'test3'\">{}</warning>");
|
|
}
|
|
}
|