Skip to content

Commit

Permalink
fix random json from schema bug with enum key
Browse files Browse the repository at this point in the history
random json from schema parser refused to accept schemas
    with "enum" key but not "type" key, even though those are valid
molsonkiko committed Jul 27, 2024
1 parent 4b9f15f commit 4f07750
Showing 7 changed files with 55 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

1. If there would be an `OutOfMemoryException` due to running out of memory while formatting JSON (a likely occurrence when using the `grepper form`), that error is caught and reported with a message box, rather than potentially causing Notepad++ to crash.
2. Ensure that hitting the down key does nothing when the last row of the [error form](/docs/README.md#error-form-and-status-bar) is selected.
3. Fix bug with [random json from schema](/docs/README.md#generating-random-json-from-a-schema) when parsing a schema that has the `enum` key but not the `type` key.

## [8.0.0] - 2024-06-29

14 changes: 7 additions & 7 deletions JsonToolsNppPlugin/JSONTools/RandomJsonFromSchema.cs
Original file line number Diff line number Diff line change
@@ -286,25 +286,25 @@ public static JNode RandomJsonHelper(JNode schema, JObject refs, int minArrayLen
}
if (obj.Length == 0) // the empty schema validates everything
return RandomAnything(new JObject(), new JObject(), minArrayLength, maxArrayLength, extendedAsciiStrings);
if (obj.children.TryGetValue("enum", out JNode enum_))
{
// any type can be an enum; it's just a list of possible values
List<JNode> enumMembers = ((JArray)enum_).children;
return enumMembers[random.Next(enumMembers.Count)].Copy();
}
if (!obj.children.TryGetValue("type", out JNode typeNode))
{
if (!obj.children.TryGetValue("anyOf", out JNode anyOf))
{
if (!obj.children.TryGetValue("$ref", out JNode refnode))
throw new SchemaValidationException("A schema must have an \"anyOf\" keyword or a \"type\" keyword");
throw new SchemaValidationException("A schema must have at least one of the \"type\", \"enum\", \"anyOf\" keywords.");
var refname = ((string)refnode.value).Split('/').Last();
if (!refs.children.TryGetValue(refname, out JNode reference))
throw new SchemaValidationException($"Reference {refname} to an undefined schema");
return RandomJsonHelper(reference, refs, minArrayLength, maxArrayLength, extendedAsciiStrings);
}
return RandomAnyOf(anyOf, refs, minArrayLength, maxArrayLength, extendedAsciiStrings);
}
if (obj.children.TryGetValue("enum", out JNode enum_))
{
// any type can be an enum; it's just a list of possible values
List<JNode> enumMembers = ((JArray)enum_).children;
return enumMembers[random.Next(enumMembers.Count)].Copy();
}
if (typeNode is JArray typeArr)
{
// multiple scalar types possible
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -28,5 +28,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("8.0.0.15")]
[assembly: AssemblyFileVersion("8.0.0.15")]
[assembly: AssemblyVersion("8.0.0.16")]
[assembly: AssemblyFileVersion("8.0.0.16")]
2 changes: 1 addition & 1 deletion JsonToolsNppPlugin/Tests/RandomJsonTests.cs
Original file line number Diff line number Diff line change
@@ -175,7 +175,7 @@ public static bool TestRandomJson()
}
}
// also test a schema that contains keywords that can't be generated randomly, like contains, minContains, minItems, maxItems, maxContains, and $defs/$ref
var kitchenSinkSchemaText = "{\"$defs\":{\"super_fancy\":{\"properties\":{\"b\":{\"anyOf\":[{\"type\": [\"integer\",\"string\"]},{\"contains\":{\"enum\":[1,2,3], \"type\":\"integer\"},\"items\": {\"type\": \"string\", \"minLength\": 3, \"maxLength\": 6},\"maxContains\":2,\"maxItems\":4,\"minContains\":1,\"minItems\":1,\"type\":\"array\"}]},\"c\":{\"type\":[\"integer\",\"null\"]},\"d\": {\"type\": \"boolean\"}},\"required\":[\"b\"],\"type\":\"object\"}},\"$schema\":\"http://json-schema.org/schema#\",\"items\":{\"properties\":{\"a\":{\"type\":\"number\", \"minimum\": -20, \"maximum\": 20},\"b\": {\"items\": {\"properties\": {\"a\": {\"$ref\": \"#/$defs/super_fancy\"}},\"required\":[\"a\"],\"type\":\"object\"},\"type\":\"array\"},\"c\": {\"type\": \"integer\"}},\"required\":[\"a\"],\"type\":\"object\"},\"type\":\"array\"}";
var kitchenSinkSchemaText = "{\"$defs\":{\"super_fancy\":{\"properties\":{\"b\":{\"anyOf\":[{\"type\": [\"integer\",\"string\"]},{\"contains\":{\"enum\":[1,2.5,true,\"\"]},\"items\": {\"type\": \"string\", \"minLength\": 3, \"maxLength\": 6},\"maxContains\":2,\"maxItems\":4,\"minContains\":1,\"minItems\":1,\"type\":\"array\"}]},\"c\":{\"type\":[\"integer\",\"null\"]},\"d\": {\"type\": \"boolean\"}},\"required\":[\"b\"],\"type\":\"object\"}},\"$schema\":\"http://json-schema.org/schema#\",\"items\":{\"properties\":{\"a\":{\"type\":\"number\", \"minimum\": -20, \"maximum\": 20},\"b\": {\"items\": {\"properties\": {\"a\": {\"$ref\": \"#/$defs/super_fancy\"}},\"required\":[\"a\"],\"type\":\"object\"},\"type\":\"array\"},\"c\": {\"type\": \"integer\"}},\"required\":[\"a\"],\"type\":\"object\"},\"type\":\"array\"}";
var kitchenSinkSchema = parser.Parse(kitchenSinkSchemaText);
ii++;
for (int i = 0; i < 200; i++)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -154,6 +154,8 @@ JsonTools infers your preferred language and attempts to translate in the follow

JsonTools only attempts to find translation files once, when Notepad++ is starting up. If you change the UI language of Notepad++ or your operating system's UI culture, you will have to close Notepad++ and reopen it before this change will apply to JsonTools.

To be clear, *JsonTools may not be in the same language of the Notepad++ UI.* The steps described above represent my best effort to automatically translate JsonTools into a language that the user will find useful, without requiring the user to select their language from a list of available languages in the settings form.

To translate JsonTools to another language, just look at [`english.json5` in the translations directory of this repo](https://github.com/molsonkiko/JsonToolsNppPlugin/blob/main/translation/english.json5) and follow the instructions in that file.

Currently JsonTools has been translated into the following languages:
82 changes: 41 additions & 41 deletions most recent errors.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion translation/italian.json5
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@
"titleIfParsing": "Analisi di JSON in corso",
"titleIfReading": "Lettura dei file in corso",
"captionIfParsing": "Lettura dei file completata.\r\nOra sta analizzando {0} documenti con una lunghezza complessiva di circa {1} MB",
"captionIfReading": "Ora sta leggendo {0} file con una lunghezza complessiva di cira {1} MB",
"captionIfReading": "Ora sta leggendo {0} file con una lunghezza complessiva di circa {1} MB",
"progressLabelIfParsing": "0 MB di {0} MB analizzati",
"progressLabelIfReading": "0 di {0} file letti"
}

0 comments on commit 4f07750

Please sign in to comment.