diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonLikePsiWalker.java b/json/src/com/jetbrains/jsonSchema/extension/JsonLikePsiWalker.java index 72f232f44bb2..f2d2a410dbef 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonLikePsiWalker.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonLikePsiWalker.java @@ -53,6 +53,8 @@ public interface JsonLikePsiWalker { return element.getTextRange(); } + default boolean acceptsEmptyRoot() { return false; } + @Nullable static JsonLikePsiWalker getWalker(@NotNull final PsiElement element, JsonSchemaObject schemaObject) { if (JSON_ORIGINAL_PSI_WALKER.handles(element)) return JSON_ORIGINAL_PSI_WALKER; diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonLikeSyntaxAdapter.java b/json/src/com/jetbrains/jsonSchema/extension/JsonLikeSyntaxAdapter.java index 5f0cf91424d1..ee3628084b72 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonLikeSyntaxAdapter.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonLikeSyntaxAdapter.java @@ -2,6 +2,8 @@ package com.jetbrains.jsonSchema.extension; import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.jetbrains.jsonSchema.impl.JsonSchemaType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -9,8 +11,11 @@ public interface JsonLikeSyntaxAdapter { @Nullable PsiElement getPropertyValue(PsiElement property); @NotNull default PsiElement adjustValue(@NotNull PsiElement value) { return value; } @Nullable String getPropertyName(PsiElement property); - @NotNull PsiElement createProperty(@NotNull final String name, @NotNull final String value); - boolean ensureComma(PsiElement backward, PsiElement self, PsiElement newElement); + @NotNull PsiElement createProperty(@NotNull final String name, @NotNull final String value, PsiElement element); + boolean ensureComma(PsiElement self, PsiElement newElement); void removeIfComma(PsiElement forward); boolean fixWhitespaceBefore(PsiElement initialElement, PsiElement element); + @NotNull String getDefaultValueFromType(@Nullable JsonSchemaType type); + PsiElement adjustNewProperty(PsiElement element); + PsiElement adjustPropertyAnchor(LeafPsiElement element); } diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonOriginalPsiWalker.java b/json/src/com/jetbrains/jsonSchema/impl/JsonOriginalPsiWalker.java index 401ce69b37d3..f956e530be63 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonOriginalPsiWalker.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonOriginalPsiWalker.java @@ -12,6 +12,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.ThreeState; import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker; import com.jetbrains.jsonSchema.extension.JsonLikeSyntaxAdapter; @@ -193,14 +194,14 @@ public class JsonOriginalPsiWalker implements JsonLikePsiWalker { @NotNull @Override - public PsiElement createProperty(@NotNull String name, @NotNull String value) { + public PsiElement createProperty(@NotNull String name, @NotNull String value, PsiElement element) { return myGenerator.createProperty(name, value); } @Override - public boolean ensureComma(PsiElement backward, PsiElement self, PsiElement newElement) { - if (backward instanceof JsonProperty) { - self.addAfter(myGenerator.createComma(), backward); + public boolean ensureComma(PsiElement self, PsiElement newElement) { + if (newElement instanceof JsonProperty && self instanceof JsonProperty) { + self.getParent().addAfter(myGenerator.createComma(), self); return true; } return false; @@ -217,6 +218,22 @@ public class JsonOriginalPsiWalker implements JsonLikePsiWalker { public boolean fixWhitespaceBefore(PsiElement initialElement, PsiElement element) { return true; } + + @NotNull + @Override + public String getDefaultValueFromType(@Nullable JsonSchemaType type) { + return type == null ? "" : type.getDefaultValue(); + } + + @Override + public PsiElement adjustNewProperty(PsiElement element) { + return element; + } + + @Override + public PsiElement adjustPropertyAnchor(LeafPsiElement element) { + throw new IncorrectOperationException("Shouldn't use leafs for insertion in pure JSON!"); + } }; } diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaAnnotatorChecker.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaAnnotatorChecker.java index 8d5aa28fc7aa..5580a2cfc506 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaAnnotatorChecker.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaAnnotatorChecker.java @@ -300,7 +300,7 @@ class JsonSchemaAnnotatorChecker { if (object.shouldCheckIntegralRequirements()) { final Set required = schema.getRequired(); if (required != null) { - HashSet requiredNames = ContainerUtil.newHashSet(required); + HashSet requiredNames = ContainerUtil.newLinkedHashSet(required); requiredNames.removeAll(set); if (!requiredNames.isEmpty()) { JsonValidationError.MissingMultiplePropsIssueData data = createMissingPropertiesData(schema, requiredNames); diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java index 11a9e1795581..06ff66f53123 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaComplianceChecker.java @@ -131,7 +131,7 @@ public class JsonSchemaComplianceChecker { myHolder.registerProblem(psiElement, range, value); } else { - myHolder.registerProblem(psiElement, range, value, fix); + myHolder.registerProblem(range.isEmpty() ? psiElement.getContainingFile() : psiElement, range, value, fix); } } @@ -142,7 +142,7 @@ public class JsonSchemaComplianceChecker { if (!isTop) ref.set(el); return isTop; }); - return ref.isNull() ? null : walker.createValueAdapter(ref.get()); + return ref.isNull() ? (walker.acceptsEmptyRoot() ? walker.createValueAdapter(element) : null) : walker.createValueAdapter(ref.get()); } private boolean checkIfAlreadyProcessed(@NotNull PsiElement property) { diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java index c93c65c06031..c4d9637add0d 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java @@ -408,9 +408,9 @@ public class JsonSchemaReader { private static MyReader createRequired() { return (element, object, queue) -> { if (element instanceof JsonArray) { - object.setRequired(((JsonArray)element).getValueList().stream() + object.setRequired(ContainerUtil.newLinkedHashSet(((JsonArray)element).getValueList().stream() .filter(notEmptyString()) - .map(el -> StringUtil.unquoteString(el.getText())).collect(Collectors.toSet())); + .map(el -> StringUtil.unquoteString(el.getText())).collect(Collectors.toList()))); } }; } diff --git a/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java b/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java index 7214d1463076..6eaba37593f1 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java +++ b/json/src/com/jetbrains/jsonSchema/impl/fixes/AddMissingPropertyFix.java @@ -19,12 +19,14 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.DocumentUtil; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.jsonSchema.extension.JsonLikeSyntaxAdapter; -import com.jetbrains.jsonSchema.impl.JsonSchemaType; import com.jetbrains.jsonSchema.impl.JsonValidationError; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -60,12 +62,13 @@ public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix hadComma = Ref.create(false); + VirtualFile file = element.getContainingFile().getVirtualFile(); PsiElement newElement = performFix(element, hadComma); // if we have more than one property, don't expand templates and don't move the caret if (newElement == null) return; PsiElement value = myQuickFixAdapter.getPropertyValue(newElement); - FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(element.getContainingFile().getVirtualFile()); + FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(file); EditorEx editor = EditorUtil.getEditorEx(fileEditor); assert editor != null; if (value == null) { @@ -83,7 +86,12 @@ public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix { Template template = builder.buildInlineTemplate(); template.setToReformat(true); @@ -92,23 +100,43 @@ public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix hadComma) { - if (element == null) return null; + public PsiElement performFix(@Nullable PsiElement node, @NotNull Ref hadComma) { + if (node == null) return null; + PsiElement element = node instanceof PsiFile ? node.getFirstChild() : node; Ref newElementRef = Ref.create(null); WriteAction.run(() -> { boolean isSingle = myData.myMissingPropertyIssues.size() == 1; - for (JsonValidationError.MissingPropertyIssueData issue: myData.myMissingPropertyIssues) { + PsiElement processedElement = element; + List reverseOrder + = ContainerUtil.reverse(ContainerUtil.newArrayList(myData.myMissingPropertyIssues)); + for (JsonValidationError.MissingPropertyIssueData issue: reverseOrder) { Object defaultValueObject = issue.defaultValue; String defaultValue = defaultValueObject instanceof String ? StringUtil.wrapWithDoubleQuote(defaultValueObject.toString()) : null; - PsiElement newElement = element - .addBefore( - myQuickFixAdapter.createProperty(issue.propertyName, defaultValue == null ? getDefaultValueFromType(issue) : defaultValue), - element.getLastChild()); - PsiElement backward = PsiTreeUtil.skipWhitespacesBackward(newElement); - hadComma.set(myQuickFixAdapter.ensureComma(backward, element, newElement)); + PsiElement property = myQuickFixAdapter.createProperty(issue.propertyName, defaultValue == null + ? myQuickFixAdapter + .getDefaultValueFromType(issue.propertyType) + : defaultValue, element); + PsiElement newElement; + if (processedElement instanceof LeafPsiElement) { + newElement = myQuickFixAdapter.adjustPropertyAnchor((LeafPsiElement)processedElement).addBefore(property, null); + } + else { + if (processedElement == element) { + newElement = processedElement.addBefore(property, processedElement.getLastChild()); + } + else { + newElement = processedElement.getParent().addBefore(property, processedElement); + } + } + PsiElement adjusted = myQuickFixAdapter.adjustNewProperty(newElement); + hadComma.set(myQuickFixAdapter.ensureComma(adjusted, PsiTreeUtil.skipWhitespacesForward(newElement))); + if (!hadComma.get()) { + hadComma.set(processedElement == element && myQuickFixAdapter.ensureComma(PsiTreeUtil.skipWhitespacesBackward(newElement), adjusted)); + } + processedElement = adjusted; if (isSingle) { - newElementRef.set(newElement); + newElementRef.set(adjusted); } } }); @@ -116,12 +144,6 @@ public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix getPropertyList() { + return ContainerUtil.emptyList(); + } + + @Override + public boolean isNull() { + return false; + } + + @NotNull + @Override + public PsiElement getDelegate() { + return myElement; + } + + @Nullable + @Override + public JsonObjectValueAdapter getAsObject() { + return this; + } + + @Nullable + @Override + public JsonArrayValueAdapter getAsArray() { + return null; + } +} diff --git a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonPsiWalker.java b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonPsiWalker.java index 22b554af66b9..7833f92d27d9 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonPsiWalker.java +++ b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonPsiWalker.java @@ -12,11 +12,13 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ThreeState; import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker; import com.jetbrains.jsonSchema.extension.JsonLikeSyntaxAdapter; import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter; import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter; +import com.jetbrains.jsonSchema.impl.JsonSchemaType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.YAMLElementGenerator; @@ -67,6 +69,11 @@ public class YamlJsonPsiWalker implements JsonLikePsiWalker { return element instanceof YAMLFile || element instanceof YAMLDocument; } + @Override + public boolean acceptsEmptyRoot() { + return true; + } + @Override public PsiElement findElementToCheck(@NotNull PsiElement element) { PsiElement current = element; @@ -87,7 +94,8 @@ public class YamlJsonPsiWalker implements JsonLikePsiWalker { @Nullable @Override public JsonValueAdapter createValueAdapter(@NotNull PsiElement element) { - return element instanceof YAMLValue ? YamlPropertyAdapter.createValueAdapterByType((YAMLValue)element) : null; + return element instanceof YAMLValue ? YamlPropertyAdapter.createValueAdapterByType((YAMLValue)element) + : (element instanceof YAMLDocument ? new YamlEmptyObjectAdapter(element) : null); } @Override @@ -229,7 +237,7 @@ public class YamlJsonPsiWalker implements JsonLikePsiWalker { assert property instanceof YAMLKeyValue; YAMLValue value = ((YAMLKeyValue)property).getValue(); if (value == null) return null; - return adjustValue(property); + return adjustValue(value); } @NotNull @@ -249,16 +257,30 @@ public class YamlJsonPsiWalker implements JsonLikePsiWalker { return ((YAMLKeyValue)property).getName(); } + private YAMLKeyValue findPrecedingKeyValueWithNoValue(PsiElement element) { + if (PsiUtilCore.getElementType(element) == YAMLTokenTypes.INDENT) { + PsiElement prev = element.getPrevSibling(); + prev = prev == null ? null : prev.getPrevSibling(); + if (prev instanceof YAMLKeyValue && ((YAMLKeyValue)prev).getValue() == null) { + return (YAMLKeyValue)prev; + } + } + return null; + } + @NotNull @Override - public PsiElement createProperty(@NotNull String name, @NotNull String value) { - return myGenerator.createYamlKeyValue(name, StringUtil.unquoteString(value)); + public PsiElement createProperty(@NotNull String name, @NotNull String value, PsiElement element) { + YAMLKeyValue keyValue = myGenerator.createYamlKeyValue(name, StringUtil.unquoteString(value)); + return element instanceof YAMLDocument || findPrecedingKeyValueWithNoValue(element) != null + ? myGenerator.createDummyYamlWithText(keyValue.getText()).getDocuments().get(0).getFirstChild() + : keyValue; } @Override - public boolean ensureComma(PsiElement backward, PsiElement self, PsiElement newElement) { - if (newElement instanceof YAMLKeyValue) { - newElement.getParent().addAfter(myGenerator.createEol(), newElement); + public boolean ensureComma(PsiElement self, PsiElement newElement) { + if (newElement instanceof YAMLKeyValue && self instanceof YAMLKeyValue) { + self.getParent().addAfter(myGenerator.createEol(), self); } return false; } @@ -279,6 +301,33 @@ public class YamlJsonPsiWalker implements JsonLikePsiWalker { public boolean fixWhitespaceBefore(PsiElement initialElement, PsiElement element) { return initialElement instanceof YAMLValue && initialElement != element; } + + @NotNull + @Override + public String getDefaultValueFromType(@Nullable JsonSchemaType type) { + if (type == null) return ""; + if (type == JsonSchemaType._object) return " "; + if (type == JsonSchemaType._array) return " - "; + return type.getDefaultValue(); + } + + @Override + public PsiElement adjustNewProperty(PsiElement element) { + if (element instanceof YAMLMapping) return element.getFirstChild(); + return element; + } + + @Override + public PsiElement adjustPropertyAnchor(LeafPsiElement element) { + YAMLKeyValue keyValue = findPrecedingKeyValueWithNoValue(element); + assert keyValue != null: "Should come here only for YAMLKeyValue with no value and a following indent"; + keyValue.addBefore(myGenerator.createEol(), null); + keyValue.addBefore(myGenerator.createIndent(element.getTextLength()), null); + PsiElement prev = element.getPrevSibling(); + if (prev != null) prev.delete(); + element.delete(); + return keyValue; + } }; } diff --git a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonSchemaHighlightingInspection.java b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonSchemaHighlightingInspection.java index a3a3733b3f6c..f996ca0b9b1d 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonSchemaHighlightingInspection.java +++ b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlJsonSchemaHighlightingInspection.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.YAMLBundle; import org.jetbrains.yaml.psi.YAMLDocument; import org.jetbrains.yaml.psi.YAMLFile; +import org.jetbrains.yaml.psi.YAMLValue; import org.jetbrains.yaml.psi.YamlPsiElementVisitor; import javax.swing.*; @@ -54,9 +55,9 @@ public class YamlJsonSchemaHighlightingInspection extends LocalInspectionTool { List documents = ((YAMLFile)file).getDocuments(); if (documents.size() != 1) return PsiElementVisitor.EMPTY_VISITOR; - PsiElement root = documents.get(0).getTopLevelValue(); - if (root == null) return PsiElementVisitor.EMPTY_VISITOR; - + YAMLDocument document = documents.get(0); + YAMLValue topLevelValue = document.getTopLevelValue(); + PsiElement root = topLevelValue == null ? document : topLevelValue; JsonSchemaService service = JsonSchemaService.Impl.get(file.getProject()); VirtualFile virtualFile = file.getViewProvider().getVirtualFile(); if (!service.isApplicableToFile(virtualFile)) return PsiElementVisitor.EMPTY_VISITOR; diff --git a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlPropertyAdapter.java b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlPropertyAdapter.java index 37cff82c2f01..32b022d564ea 100644 --- a/plugins/yaml/src/org/jetbrains/yaml/schema/YamlPropertyAdapter.java +++ b/plugins/yaml/src/org/jetbrains/yaml/schema/YamlPropertyAdapter.java @@ -4,6 +4,7 @@ package org.jetbrains.yaml.schema; import com.intellij.openapi.util.RecursionManager; import com.intellij.psi.PsiElement; import com.intellij.psi.TokenType; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter; @@ -11,6 +12,7 @@ import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter; import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.yaml.YAMLTokenTypes; import org.jetbrains.yaml.psi.*; import java.util.Collection; @@ -71,6 +73,16 @@ public class YamlPropertyAdapter implements JsonPropertyAdapter { @Nullable public static JsonValueAdapter createEmptyValueAdapter(@NotNull PsiElement context, boolean pinSelf) { + if (context instanceof YAMLKeyValue && ((YAMLKeyValue)context).getValue() == null) { + PsiElement next = PsiTreeUtil.skipWhitespacesForward(context); + if (PsiUtilCore.getElementType(next) == YAMLTokenTypes.EOL) { + next = PsiTreeUtil.skipWhitespacesForward(next); + if (PsiUtilCore.getElementType(next) == YAMLTokenTypes.INDENT && !(PsiTreeUtil.skipWhitespacesForward(next) instanceof YAMLKeyValue)) { + // potentially empty object after newline+indent + return new YamlEmptyObjectAdapter(next); + } + } + } PsiElement nextSibling = context.getNextSibling(); PsiElement nodeToHighlight = PsiUtilCore.getElementType(nextSibling) == TokenType.WHITE_SPACE ? nextSibling diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaHighlightingTest.java b/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaHighlightingTest.java index a2d719c676de..3c47234d86d0 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaHighlightingTest.java +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaHighlightingTest.java @@ -844,4 +844,45 @@ public class YamlByJsonSchemaHighlightingTest extends JsonSchemaHighlightingTest " -\n" + " - a"); } + + public void testEmptyFile() throws Exception { + doTest("{\n" + + " \"type\": \"object\",\n" + + "\n" + + " \"properties\": {\n" + + " \"versionAsStringArray\": {\n" + + " \"type\": \"array\"\n" + + " }\n" + + " },\n" + + " \"required\": [\"versionAsStringArray\"]\n" + + "}", ""); + } + + public void testEmptyValueBetweenProps() throws Exception { + doTest("{\n" + + " \"type\": \"object\",\n" + + "\n" + + " \"properties\": {\n" + + " \"versionAsStringArray\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"xxx\": {\n" + + " \"type\": \"number\"\n" + + " },\n" + + " \"yyy\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"zzz\": {\n" + + " \"type\": \"number\"\n" + + " }\n" + + " },\n" + + " \"required\": [\"xxx\", \"yyy\", \"zzz\"]\n" + + " }\n" + + " },\n" + + " \"required\": [\"versionAsStringArray\"]\n" + + "}", "versionAsStringArray:\n" + + " zzz: 0\n" + + " yyy: \n" + + " xxx: 0"); + } } diff --git a/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaQuickFixTest.java b/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaQuickFixTest.java index 9a67307ea70e..c8e08ca150aa 100644 --- a/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaQuickFixTest.java +++ b/plugins/yaml/testSrc/org/jetbrains/yaml/schema/YamlByJsonSchemaQuickFixTest.java @@ -48,4 +48,69 @@ public class YamlByJsonSchemaQuickFixTest extends JsonSchemaQuickFixTestBase { "}", "a: 5\nb: 6\nc: 7", "Remove prohibited property 'b'", "a: 5\n" + "c: 7"); } + + public void testEmptyFile() throws Exception { + doTest("{\n" + + " \"type\": \"object\",\n" + + "\n" + + " \"properties\": {\n" + + " \"versionAsStringArray\": {\n" + + " \"type\": \"array\"\n" + + " }\n" + + " },\n" + + " \"required\": [\"versionAsStringArray\"]\n" + + "}", "", "Add missing property 'versionAsStringArray'", "versionAsStringArray:\n" + + " - "); + } + + public void testEmptyObject() throws Exception { + doTest("{\n" + + " \"type\": \"object\",\n" + + "\n" + + " \"properties\": {\n" + + " \"versionAsStringArray\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"xxx\": {\n" + + " \"type\": \"array\"\n" + + " }\n" + + " },\n" + + " \"required\": [\"xxx\"]\n" + + " }\n" + + " },\n" + + " \"required\": [\"versionAsStringArray\"]\n" + + "}", "versionAsStringArray:\n" + + " ", "Add missing property 'xxx'", "versionAsStringArray:\n" + + " xxx:\n" + + " - "); + } + + public void testEmptyObjectMultipleProps() throws Exception { + doTest("{\n" + + " \"type\": \"object\",\n" + + "\n" + + " \"properties\": {\n" + + " \"versionAsStringArray\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"xxx\": {\n" + + " \"type\": \"number\"\n" + + " },\n" + + " \"yyy\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"zzz\": {\n" + + " \"type\": \"number\"\n" + + " }\n" + + " },\n" + + " \"required\": [\"xxx\", \"yyy\", \"zzz\"]\n" + + " }\n" + + " },\n" + + " \"required\": [\"versionAsStringArray\"]\n" + + "}", "versionAsStringArray:\n" + + " ","Add missing properties 'xxx', 'yyy', 'zzz'", "versionAsStringArray:\n" + + " xxx: 0\n" + + " yyy:\n" + + " zzz: 0"); + } }