From 44bca871723d72ab58fb6ff628ec411f70c5dca6 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 18 Dec 2025 04:49:22 -0300 Subject: [PATCH 1/4] test: refactor tests to use hamcrest matchers --- .../jsonmigration/ClientCallable_ArrayOfJsonObject__V.java | 7 ++++--- .../jsonmigration/ClientCallable_JsonObjectVarargs__V.java | 7 ++++--- .../LegacyClientCallable_ArrayOfJsonObject__V.java | 7 ++++--- .../LegacyClientCallable_JsonObjectVarargs__V.java | 7 ++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java index 6615966..b2398cc 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java @@ -19,18 +19,19 @@ */ package com.flowingcode.vaadin.jsonmigration; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyArray; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import com.vaadin.flow.component.ClientCallable; import elemental.json.JsonObject; -import org.junit.Assert; public class ClientCallable_ArrayOfJsonObject__V extends BaseClientCallable { @ClientCallable public void test(JsonObject[] arg) { - Assert.assertNotNull(arg); - Assert.assertThat(arg, not(emptyArray())); + assertThat(arg, notNullValue()); + assertThat(arg, not(emptyArray())); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java index 2a23c5a..bdb7c9c 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java @@ -19,18 +19,19 @@ */ package com.flowingcode.vaadin.jsonmigration; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyArray; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import com.vaadin.flow.component.ClientCallable; import elemental.json.JsonObject; -import org.junit.Assert; public class ClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @ClientCallable public void test(JsonObject[] arg) { - Assert.assertNotNull(arg); - Assert.assertThat(arg, not(emptyArray())); + assertThat(arg, notNullValue()); + assertThat(arg, not(emptyArray())); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java index 3a8d3d1..1c1054e 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java @@ -19,17 +19,18 @@ */ package com.flowingcode.vaadin.jsonmigration; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyArray; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import elemental.json.JsonObject; -import org.junit.Assert; public class LegacyClientCallable_ArrayOfJsonObject__V extends BaseClientCallable { @LegacyClientCallable public void test(JsonObject[] arg) { - Assert.assertNotNull(arg); - Assert.assertThat(arg, not(emptyArray())); + assertThat(arg, notNullValue()); + assertThat(arg, not(emptyArray())); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java index 5e7ccfe..7bb049d 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java @@ -19,17 +19,18 @@ */ package com.flowingcode.vaadin.jsonmigration; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyArray; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import elemental.json.JsonObject; -import org.junit.Assert; public class LegacyClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @LegacyClientCallable public void test(JsonObject[] arg) { - Assert.assertNotNull(arg); - Assert.assertThat(arg, not(emptyArray())); + assertThat(arg, notNullValue()); + assertThat(arg, not(emptyArray())); trace(); } } From 9fa65168483f0eb55e1bbb74a5c6e631e361c47f Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 18 Dec 2025 04:51:08 -0300 Subject: [PATCH 2/4] fix: convert JsonValue[] arguments Close #26 --- .../ClassInstrumentationUtil.java | 20 ++++++++++++++ .../vaadin/jsonmigration/JsonMigration.java | 26 +++++++++++++++++++ .../ClientCallable_ArrayOfJsonObject__V.java | 2 ++ .../ClientCallable_JsonObjectVarargs__V.java | 2 ++ ...cyClientCallable_ArrayOfJsonObject__V.java | 2 ++ ...cyClientCallable_JsonObjectVarargs__V.java | 2 ++ 6 files changed, 54 insertions(+) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index d089878..90fefe5 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -466,6 +466,26 @@ private void generateMethodOverride( mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(paramType)); } + localVarIndex++; + } else if (hasJsonValueParams && JsonValue[].class.isAssignableFrom(paramType)) { + // Load the JsonNode[] parameter and create target array + mv.visitVarInsn(Opcodes.ALOAD, localVarIndex); + mv.visitInsn(Opcodes.DUP); + mv.visitInsn(Opcodes.ARRAYLENGTH); + mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(paramType.getComponentType())); + + // Stack before: [SourceArray, TargetArray] + // Stack after: [TargetArray, SourceArray, TargetArray] + mv.visitInsn(Opcodes.DUP_X1); + + // Call JsonMigration.convertToJsonValue(JsonNode[], JsonValue[]) + mv.visitMethodInsn( + Opcodes.INVOKESTATIC, + "com/flowingcode/vaadin/jsonmigration/JsonMigration", + "convertToJsonValue", + "([Ljava/lang/Object;[Lelemental/json/JsonValue;)V", + false); + localVarIndex++; } else { localVarIndex += loadParameter(mv, paramType, localVarIndex); diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigration.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigration.java index a63ac25..f671293 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigration.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigration.java @@ -91,6 +91,32 @@ public static JsonValue convertToJsonValue(Object object) { return helper.convertToJsonValue(object); } + /** + * Converts an array of objects into an array of {@code JsonValue} objects. + * + *

+ * This method delegates the conversion to a version-specific helper to handle any differences in + * the serialization process. + * + * @param source the array of objects to convert + * @param target the destination array to be populated with converted {@code JsonValue}s + * @throws NullPointerException if source or target is null + * @throws IllegalArgumentException if the array lengths do not match + * @throws ArrayStoreException if an element in the {@code source} array is converted into a type + * that is not assignable to the runtime component type of the {@code target} array + */ + public static void convertToJsonValue(Object[] source, JsonValue[] target) { + if (source.length != target.length) { + throw new IllegalArgumentException( + String.format("Array length mismatch: source.length=%d, target.length=%d", + source.length, target.length)); + } + + for (int i = 0; i < target.length; i++) { + target[i] = convertToJsonValue(source[i]); + } + } + @SneakyThrows private static Object invoke(Method method, Object instance, Object... args) { return helper.invoke(method, instance, args); diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java index b2398cc..12efb5b 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_ArrayOfJsonObject__V.java @@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.notNullValue; import com.vaadin.flow.component.ClientCallable; import elemental.json.JsonObject; +import org.hamcrest.Matchers; public class ClientCallable_ArrayOfJsonObject__V extends BaseClientCallable { @@ -32,6 +33,7 @@ public class ClientCallable_ArrayOfJsonObject__V extends BaseClientCallable { public void test(JsonObject[] arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); + assertThat(arg, Matchers.instanceOf(JsonObject[].class)); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java index bdb7c9c..3a66bab 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java @@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.notNullValue; import com.vaadin.flow.component.ClientCallable; import elemental.json.JsonObject; +import org.hamcrest.Matchers; public class ClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @@ -32,6 +33,7 @@ public class ClientCallable_JsonObjectVarargs__V extends BaseClientCallable { public void test(JsonObject[] arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); + assertThat(arg, Matchers.instanceOf(JsonObject[].class)); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java index 1c1054e..ac61ee3 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonObject__V.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import elemental.json.JsonObject; +import org.hamcrest.Matchers; public class LegacyClientCallable_ArrayOfJsonObject__V extends BaseClientCallable { @@ -31,6 +32,7 @@ public class LegacyClientCallable_ArrayOfJsonObject__V extends BaseClientCallabl public void test(JsonObject[] arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); + assertThat(arg, Matchers.instanceOf(JsonObject[].class)); trace(); } } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java index 7bb049d..7085522 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import elemental.json.JsonObject; +import org.hamcrest.Matchers; public class LegacyClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @@ -31,6 +32,7 @@ public class LegacyClientCallable_JsonObjectVarargs__V extends BaseClientCallabl public void test(JsonObject[] arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); + assertThat(arg, Matchers.instanceOf(JsonObject[].class)); trace(); } } From 799550d76f2c7cf0d3ed73609f62f0bf0344e077 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 18 Dec 2025 05:23:12 -0300 Subject: [PATCH 3/4] test: correct method signature in varargs tests --- .../jsonmigration/ClientCallable_JsonObjectVarargs__V.java | 2 +- .../LegacyClientCallable_JsonObjectVarargs__V.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java index 3a66bab..aba192b 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObjectVarargs__V.java @@ -30,7 +30,7 @@ public class ClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @ClientCallable - public void test(JsonObject[] arg) { + public void test(JsonObject... arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); assertThat(arg, Matchers.instanceOf(JsonObject[].class)); diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java index 7085522..2f7b562 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObjectVarargs__V.java @@ -29,7 +29,7 @@ public class LegacyClientCallable_JsonObjectVarargs__V extends BaseClientCallable { @LegacyClientCallable - public void test(JsonObject[] arg) { + public void test(JsonObject... arg) { assertThat(arg, notNullValue()); assertThat(arg, not(emptyArray())); assertThat(arg, Matchers.instanceOf(JsonObject[].class)); From 255b8266c859de45ab397d66c1007f510242acc2 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 18 Dec 2025 05:24:01 -0300 Subject: [PATCH 4/4] test: add test for array of JsonString --- ...cyClientCallable_ArrayOfJsonString__V.java | 38 +++++++++++++++++++ .../LegacyClientCallablesTest.java | 11 ++++++ .../LegacyClientCallablesTest24.java | 8 +++- .../LegacyClientCallablesTest25.java | 7 +++- 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonString__V.java diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonString__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonString__V.java new file mode 100644 index 0000000..e07d31c --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_ArrayOfJsonString__V.java @@ -0,0 +1,38 @@ +/*- + * #%L + * Json Migration Helper + * %% + * Copyright (C) 2025 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.flowingcode.vaadin.jsonmigration; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import elemental.json.JsonString; +import org.hamcrest.Matchers; + +public class LegacyClientCallable_ArrayOfJsonString__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonString[] arg) { + assertThat(arg, notNullValue()); + assertThat(arg, not(emptyArray())); + assertThat(arg, Matchers.instanceOf(JsonString[].class)); + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java index 580e17a..56bec9b 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java @@ -79,6 +79,8 @@ private static Object invokeTestMethod(BaseClientCallable instrumented, Object.. protected abstract Object createArrayOfJsonObject(); + protected abstract Object createArrayOfJsonString(); + @Test public void test__V() throws Exception { LegacyClientCallable__V instrumented = @@ -315,6 +317,15 @@ public void test_JsonObject__V() throws Exception { assertTrue(instrumented.hasBeenTraced()); } + @Test + public void test_ArrayOfJsonString__V() throws Exception { + LegacyClientCallable_ArrayOfJsonString__V instrumented = + instrumentClass(LegacyClientCallable_ArrayOfJsonString__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, createArrayOfJsonString()); + assertTrue(instrumented.hasBeenTraced()); + } + @Test public void test_ArrayOfJsonObject__V() throws Exception { LegacyClientCallable_ArrayOfJsonObject__V instrumented = diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java index 2a7c783..812946b 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java @@ -22,6 +22,7 @@ import com.vaadin.flow.component.Component; import elemental.json.Json; import elemental.json.JsonObject; +import elemental.json.JsonString; public class LegacyClientCallablesTest24 extends LegacyClientCallablesTest { @@ -46,7 +47,7 @@ protected Object createJsonNumber() { } @Override - protected Object createJsonString() { + protected JsonString createJsonString() { return Json.create("test"); } @@ -65,4 +66,9 @@ protected Object createArrayOfJsonObject() { return new JsonObject[] {createJsonObject(), createJsonObject()}; } + @Override + protected Object createArrayOfJsonString() { + return new JsonString[] {createJsonString(), createJsonString()}; + } + } diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java index 7464a9a..a2ec99f 100644 --- a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java @@ -52,7 +52,7 @@ protected Object createJsonNumber() { } @Override - protected Object createJsonString() { + protected StringNode createJsonString() { return StringNode.valueOf("test"); } @@ -71,4 +71,9 @@ protected Object createArrayOfJsonObject() { return new ObjectNode[] {createJsonObject(), createJsonObject()}; } + @Override + protected Object createArrayOfJsonString() { + return new StringNode[] {createJsonString(), createJsonString()}; + } + }