From 6c4eaebd8f6b8031e216ec068a98b4e211efbd15 Mon Sep 17 00:00:00 2001 From: The-Lum <86879521+The-Lum@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:52:11 +0000 Subject: [PATCH] fix: add `int` and `string` management on `%json_add` That fixes: - https://github.com/plantuml/plantuml/issues/328#issuecomment-2071079413 Here is a fix for `int` and `string`, in order to manage: ```puml %json_add({"age" : 30}, name, 123) '=> {"age":30,"name":123} ``` ```puml %json_add({"age" : 30}, name, Sally) '=> {"age":30,"name":"Sally"} ``` [FYI @philCryoport] Reagrds, Th. --- .../plantuml/tim/expression/TValue.java | 10 ++++ .../plantuml/tim/stdlib/JsonAdd.java | 14 +++-- .../plantuml/tim/TimTestUtils.java | 14 +++++ .../plantuml/tim/stdlib/JsonAddTest.java | 51 ++++++++++++++++++- 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/net/sourceforge/plantuml/tim/expression/TValue.java b/src/net/sourceforge/plantuml/tim/expression/TValue.java index 21aee1009..4647741a0 100644 --- a/src/net/sourceforge/plantuml/tim/expression/TValue.java +++ b/src/net/sourceforge/plantuml/tim/expression/TValue.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.expression; import java.util.Objects; +import net.sourceforge.plantuml.json.Json; import net.sourceforge.plantuml.json.JsonValue; public final class TValue { @@ -221,4 +222,13 @@ public final class TValue { return jsonValue; } + public JsonValue toJsonValue() { + if (isNumber()) { + return Json.value(this.intValue); + } + if (isString()) { + return Json.value(this.stringValue); + } + return this.jsonValue; + } } diff --git a/src/net/sourceforge/plantuml/tim/stdlib/JsonAdd.java b/src/net/sourceforge/plantuml/tim/stdlib/JsonAdd.java index 21d9d77fe..44ea8bb89 100644 --- a/src/net/sourceforge/plantuml/tim/stdlib/JsonAdd.java +++ b/src/net/sourceforge/plantuml/tim/stdlib/JsonAdd.java @@ -72,17 +72,15 @@ public class JsonAdd extends SimpleReturnFunction { if (!json.isArray() && !json.isObject()) return data; if (json.isArray()) { - final JsonValue value = values.get(1).toJson(); - final JsonArray array = (JsonArray) json; - array.add(value); - return TValue.fromJson(array); + final JsonValue value = values.get(1).toJsonValue(); + json.asArray().add(value); + return TValue.fromJson(json); } if (json.isObject()) { final String name = values.get(1).toString(); - final JsonValue value = values.get(2).toJson(); - final JsonObject object = (JsonObject) json; - object.add(name, value); - return TValue.fromJson(object); + final JsonValue value = values.get(2).toJsonValue(); + json.asObject().add(name, value); + return TValue.fromJson(json); } throw new EaterException("Bad JSON type", location); } diff --git a/test/net/sourceforge/plantuml/tim/TimTestUtils.java b/test/net/sourceforge/plantuml/tim/TimTestUtils.java index 0083f63fe..7a48c1086 100644 --- a/test/net/sourceforge/plantuml/tim/TimTestUtils.java +++ b/test/net/sourceforge/plantuml/tim/TimTestUtils.java @@ -83,4 +83,18 @@ public class TimTestUtils { assertEquals(expected, tValue.toString()); } + // Tfunc: (JsonValue, String, String) -> (String) + public static void assertTimExpectedOutputFromInput(TFunction func, JsonValue input1, String input2, String input3, String expected) throws EaterException { + final List values = Arrays.asList(TValue.fromJson(input1), TValue.fromString(input2), TValue.fromString(input3)); + final TValue tValue = func.executeReturnFunction(null, null, null, values, null); + assertEquals(expected, tValue.toString()); + } + + // Tfunc: (JsonValue, String, Int) -> (String) + public static void assertTimExpectedOutputFromInput(TFunction func, JsonValue input1, String input2, Integer input3, String expected) throws EaterException { + final List values = Arrays.asList(TValue.fromJson(input1), TValue.fromString(input2), TValue.fromInt(input3)); + final TValue tValue = func.executeReturnFunction(null, null, null, values, null); + assertEquals(expected, tValue.toString()); + } + } \ No newline at end of file diff --git a/test/net/sourceforge/plantuml/tim/stdlib/JsonAddTest.java b/test/net/sourceforge/plantuml/tim/stdlib/JsonAddTest.java index 141f09b4b..54c3f7eef 100644 --- a/test/net/sourceforge/plantuml/tim/stdlib/JsonAddTest.java +++ b/test/net/sourceforge/plantuml/tim/stdlib/JsonAddTest.java @@ -38,7 +38,35 @@ class JsonAddTest { void Test_with_Array_Json(@ConvertWith(StringJsonConverter.class) JsonValue input1, @ConvertWith(StringJsonConverter.class) JsonValue input2, String expected) throws EaterException { assertTimExpectedOutputFromInput(cut, input1, input2, expected); } - + + @ParameterizedTest(name = paramTestName) + @CsvSource(value = { + " [], -1, '[\"-1\"]' ", + " [], 1, '[\"1\"]' ", + " [0], 123, '[0,\"123\"]' ", + " [0], a, '[0,\"a\"]' ", + " [0], \"a\", '[0,\"\\\"a\\\"\"]' ", + " [0], a b c, '[0,\"a b c\"]' ", + " [0], \"a b c\", '[0,\"\\\"a b c\\\"\"]' ", + " '[{\"a\":[1, 2]}]', 1, '[{\"a\":[1,2]},\"1\"]' ", + " '[{\"a\":[1, 2]}]', a, '[{\"a\":[1,2]},\"a\"]' ", + }) + void Test_with_Array_Json_add_Str(@ConvertWith(StringJsonConverter.class) JsonValue input1, String input2, String expected) throws EaterException { + assertTimExpectedOutputFromInput(cut, input1, input2, expected); + } + + @ParameterizedTest(name = paramTestName) + @CsvSource(value = { + " [], -1, [-1]", + " [], 1, [1]", + " [0], 123, '[0,123]' ", + " '[{\"a\":[1, 2]}]', 1, '[{\"a\":[1,2]},1]' ", + " '[{\"a\":[1, 2]}]', 123, '[{\"a\":[1,2]},123]' ", + }) + void Test_with_Array_Json_add_Int(@ConvertWith(StringJsonConverter.class) JsonValue input1, Integer input2, String expected) throws EaterException { + assertTimExpectedOutputFromInput(cut, input1, input2, expected); + } + @ParameterizedTest(name = "[{index}] " + cutName + "({0}, {1}, {2}) = {3}") @CsvSource(value = { " {}, a, 1, {\"a\":1}", @@ -57,6 +85,27 @@ class JsonAddTest { assertTimExpectedOutputFromInput(cut, input1, input2, input3, expected); } + @ParameterizedTest(name = "[{index}] " + cutName + "({0}, {1}, {2}) = {3}") + @CsvSource(value = { + " {}, a, 1, {\"a\":\"1\"}", + " {}, a, 'abc', '{\"a\":\"abc\"}'", + " {}, a, 'a b c', '{\"a\":\"a b c\"}'", + " {\"age\" : 30}, name, Sally, '{\"age\":30,\"name\":\"Sally\"}'", + }) + void Test_with_Object_Json_add_Str(@ConvertWith(StringJsonConverter.class) JsonValue input1, String input2, String input3, String expected) throws EaterException { + assertTimExpectedOutputFromInput(cut, input1, input2, input3, expected); + } + + @ParameterizedTest(name = "[{index}] " + cutName + "({0}, {1}, {2}) = {3}") + @CsvSource(value = { + " {}, a, 1, {\"a\":1}", + " {}, a, 123, '{\"a\":123}'", + " {\"age\" : 30}, name, 123, '{\"age\":30,\"name\":123}'", + }) + void Test_with_Object_Json_add_Int(@ConvertWith(StringJsonConverter.class) JsonValue input1, String input2, Integer input3, String expected) throws EaterException { + assertTimExpectedOutputFromInput(cut, input1, input2, input3, expected); + } + @Nested class Not_Nominal_Test { @ParameterizedTest(name = paramTestName)