From 385f1af0fd9c53ed455434ea353cb7081b2dc9be Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:24:43 -0300 Subject: [PATCH 1/7] test: add unit tests --- .../jsonmigration/BaseClientCallable.java | 17 ++ .../jsonmigration/ClientCallable_D__V.java | 14 + .../jsonmigration/ClientCallable_I__V.java | 14 + .../ClientCallable_JsonArray__V.java | 16 ++ .../ClientCallable_JsonBoolean__V.java | 16 ++ .../ClientCallable_JsonNull__V.java | 16 ++ .../ClientCallable_JsonNumber__V.java | 16 ++ .../ClientCallable_JsonObject__V.java | 16 ++ .../ClientCallable_JsonString__V.java | 16 ++ .../ClientCallable_JsonValue__V.java | 16 ++ .../ClientCallable_String__V.java | 14 + .../jsonmigration/ClientCallable_Z__V.java | 14 + .../jsonmigration/ClientCallable__D.java | 15 + .../jsonmigration/ClientCallable__I.java | 15 + .../ClientCallable__Integer.java | 15 + .../ClientCallable__JsonArray.java | 18 ++ .../ClientCallable__JsonBoolean.java | 18 ++ .../ClientCallable__JsonNull.java | 18 ++ .../ClientCallable__JsonNumber.java | 18 ++ .../ClientCallable__JsonObject.java | 18 ++ .../ClientCallable__JsonString.java | 18 ++ .../ClientCallable__JsonValue.java | 18 ++ .../jsonmigration/ClientCallable__V.java | 14 + .../jsonmigration/ClientCallable__Z.java | 15 + .../jsonmigration/ClientCallablesTest.java | 266 ++++++++++++++++++ .../jsonmigration/ClientCallablesTest24.java | 66 +++++ .../jsonmigration/ClientCallablesTest25.java | 68 +++++ .../LegacyClientCallable_D__V.java | 9 + .../LegacyClientCallable_I__V.java | 9 + .../LegacyClientCallable_JsonArray__V.java | 11 + .../LegacyClientCallable_JsonBoolean__V.java | 11 + .../LegacyClientCallable_JsonNull__V.java | 11 + .../LegacyClientCallable_JsonNumber__V.java | 11 + .../LegacyClientCallable_JsonObject__V.java | 11 + .../LegacyClientCallable_JsonString__V.java | 11 + .../LegacyClientCallable_JsonValue__V.java | 11 + .../LegacyClientCallable_String__V.java | 9 + .../LegacyClientCallable_Z__V.java | 9 + .../LegacyClientCallable__D.java | 10 + .../LegacyClientCallable__I.java | 10 + .../LegacyClientCallable__Integer.java | 10 + .../LegacyClientCallable__JsonArray.java | 13 + .../LegacyClientCallable__JsonBoolean.java | 13 + .../LegacyClientCallable__JsonNull.java | 13 + .../LegacyClientCallable__JsonNumber.java | 13 + .../LegacyClientCallable__JsonObject.java | 13 + .../LegacyClientCallable__JsonString.java | 13 + .../LegacyClientCallable__JsonValue.java | 13 + .../LegacyClientCallable__V.java | 9 + .../LegacyClientCallable__Z.java | 10 + .../LegacyClientCallablesTest.java | 265 +++++++++++++++++ .../LegacyClientCallablesTest24.java | 44 +++ .../LegacyClientCallablesTest25.java | 50 ++++ 53 files changed, 1397 insertions(+) create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/BaseClientCallable.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_D__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_I__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonArray__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonBoolean__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNull__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNumber__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObject__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonString__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonValue__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_String__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_Z__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__D.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__I.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Integer.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonArray.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonBoolean.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNull.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNumber.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonObject.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonString.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonValue.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Z.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_D__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_I__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonArray__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonBoolean__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNull__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNumber__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObject__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonString__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonValue__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_String__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_Z__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__D.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__I.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Integer.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonArray.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonBoolean.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNull.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNumber.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonObject.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonString.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonValue.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__V.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Z.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java create mode 100644 src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/BaseClientCallable.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/BaseClientCallable.java new file mode 100644 index 0000000..a18d1e3 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/BaseClientCallable.java @@ -0,0 +1,17 @@ +package com.flowingcode.vaadin.jsonmigration; + +import com.vaadin.flow.component.html.Div; + +public abstract class BaseClientCallable extends Div { + + private boolean traced; + + protected final void trace() { + traced = true; + } + + public boolean hasBeenTraced() { + return traced; + } + +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_D__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_D__V.java new file mode 100644 index 0000000..200300c --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_D__V.java @@ -0,0 +1,14 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable_D__V extends BaseClientCallable { + + @ClientCallable + public void test(double arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_I__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_I__V.java new file mode 100644 index 0000000..e1c6b64 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_I__V.java @@ -0,0 +1,14 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable_I__V extends BaseClientCallable { + + @ClientCallable + public void test(int arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonArray__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonArray__V.java new file mode 100644 index 0000000..e0a8e4b --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonArray__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonArray; + +public class ClientCallable_JsonArray__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonArray arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonBoolean__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonBoolean__V.java new file mode 100644 index 0000000..5827387 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonBoolean__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonBoolean; + +public class ClientCallable_JsonBoolean__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonBoolean arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNull__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNull__V.java new file mode 100644 index 0000000..76c8e83 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNull__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonNull; + +public class ClientCallable_JsonNull__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonNull arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNumber__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNumber__V.java new file mode 100644 index 0000000..aed624e --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonNumber__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonNumber; + +public class ClientCallable_JsonNumber__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonNumber arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObject__V.java new file mode 100644 index 0000000..bf57234 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonObject__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonObject; + +public class ClientCallable_JsonObject__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonObject arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonString__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonString__V.java new file mode 100644 index 0000000..8ec0a0c --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonString__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonString; + +public class ClientCallable_JsonString__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonString arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonValue__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonValue__V.java new file mode 100644 index 0000000..d67944d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_JsonValue__V.java @@ -0,0 +1,16 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.JsonValue; + +public class ClientCallable_JsonValue__V extends BaseClientCallable { + + @ClientCallable + public void test(JsonValue arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_String__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_String__V.java new file mode 100644 index 0000000..b287f3a --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_String__V.java @@ -0,0 +1,14 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable_String__V extends BaseClientCallable { + + @ClientCallable + public void test(String arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_Z__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_Z__V.java new file mode 100644 index 0000000..ed40c9e --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable_Z__V.java @@ -0,0 +1,14 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable_Z__V extends BaseClientCallable { + + @ClientCallable + public void test(boolean arg) { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__D.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__D.java new file mode 100644 index 0000000..4849317 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__D.java @@ -0,0 +1,15 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable__D extends BaseClientCallable { + + @ClientCallable + public double test() { + trace(); + return 0.0; + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__I.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__I.java new file mode 100644 index 0000000..f6285ed --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__I.java @@ -0,0 +1,15 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable__I extends BaseClientCallable { + + @ClientCallable + public int test() { + trace(); + return 0; + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Integer.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Integer.java new file mode 100644 index 0000000..cc45c7b --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Integer.java @@ -0,0 +1,15 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable__Integer extends BaseClientCallable { + + @ClientCallable + public Integer test() { + trace(); + return 0; + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonArray.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonArray.java new file mode 100644 index 0000000..d44c3fa --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonArray.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonArray; + +public class ClientCallable__JsonArray extends BaseClientCallable { + + @ClientCallable + public JsonArray test() { + trace(); + return Json.createArray(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonBoolean.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonBoolean.java new file mode 100644 index 0000000..75dd3a0 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonBoolean.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonBoolean; + +public class ClientCallable__JsonBoolean extends BaseClientCallable { + + @ClientCallable + public JsonBoolean test() { + trace(); + return Json.create(true); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNull.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNull.java new file mode 100644 index 0000000..7c80c5b --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNull.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonNull; + +public class ClientCallable__JsonNull extends BaseClientCallable { + + @ClientCallable + public JsonNull test() { + trace(); + return Json.createNull(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNumber.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNumber.java new file mode 100644 index 0000000..5771266 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonNumber.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonNumber; + +public class ClientCallable__JsonNumber extends BaseClientCallable { + + @ClientCallable + public JsonNumber test() { + trace(); + return Json.create(0); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonObject.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonObject.java new file mode 100644 index 0000000..4c46549 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonObject.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonObject; + +public class ClientCallable__JsonObject extends BaseClientCallable { + + @ClientCallable + public JsonObject test() { + trace(); + return Json.createObject(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonString.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonString.java new file mode 100644 index 0000000..286999d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonString.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonString; + +public class ClientCallable__JsonString extends BaseClientCallable { + + @ClientCallable + public JsonString test() { + trace(); + return Json.create(""); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonValue.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonValue.java new file mode 100644 index 0000000..67ec848 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__JsonValue.java @@ -0,0 +1,18 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +import elemental.json.Json; +import elemental.json.JsonValue; + +public class ClientCallable__JsonValue extends BaseClientCallable { + + @ClientCallable + public JsonValue test() { + trace(); + return Json.createObject(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__V.java new file mode 100644 index 0000000..dd86972 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__V.java @@ -0,0 +1,14 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable__V extends BaseClientCallable { + + @ClientCallable + public void test() { + trace(); + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Z.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Z.java new file mode 100644 index 0000000..f71235d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallable__Z.java @@ -0,0 +1,15 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import com.vaadin.flow.component.ClientCallable; + +public class ClientCallable__Z extends BaseClientCallable { + + @ClientCallable + public boolean test() { + trace(); + return true; + } +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java new file mode 100644 index 0000000..a8196e5 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest.java @@ -0,0 +1,266 @@ +package com.flowingcode.vaadin.jsonmigration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import com.vaadin.flow.component.ClientCallable; +import com.vaadin.flow.component.Component; +import elemental.json.JsonValue; +import java.lang.reflect.Method; +import org.junit.Test; + +public abstract class ClientCallablesTest { + + protected abstract Class instrumentClass(Class clazz); + + private static final String MESSAGE = "instrumented method is not annotated with @ClientCallable"; + + /** + * Finds the test method declared in the instrumented class that is annotated + * with @ClientCallable. + * + * @param c the instrumented callable instance + * @return the Method if found, null otherwise + */ + protected static Method getClientCallableTestMethod(Class clazz) { + for (Method method : clazz.getDeclaredMethods()) { + if ("test".equals(method.getName()) && method.isAnnotationPresent(ClientCallable.class)) { + return method; + } + } + return null; + } + + /** + * Invokes the test method on the instrumented instance via reflection. + * + * @param instrumented the instrumented instance + * @param args the arguments to pass to the test method + * @return the result of the method invocation + * @throws Exception if invocation fails + */ + private Object invokeTestMethod(BaseClientCallable instrumented, Object... args) + throws Exception { + Method testMethod = getClientCallableTestMethod(instrumented.getClass()); + assertTrue(MESSAGE, testMethod != null); + return testMethod.invoke(instrumented, args); + } + + protected abstract Object createJsonNull(); + + protected abstract Object createJsonBoolean(); + + protected abstract Object createJsonNumber(); + + protected abstract Object createJsonString(); + + protected abstract Object createJsonArray(); + + protected abstract Object createJsonObject(); + + @Test + public void test__V() throws Exception { + ClientCallable__V instrumented = instrumentClass(ClientCallable__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_Z__V() throws Exception { + ClientCallable_Z__V instrumented = instrumentClass(ClientCallable_Z__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, true); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_I__V() throws Exception { + ClientCallable_I__V instrumented = instrumentClass(ClientCallable_I__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, 42); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_D__V() throws Exception { + ClientCallable_D__V instrumented = instrumentClass(ClientCallable_D__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, 3.14); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_String__V() throws Exception { + ClientCallable_String__V instrumented = instrumentClass(ClientCallable_String__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, "test"); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test__Z() throws Exception { + ClientCallable__Z instrumented = instrumentClass(ClientCallable__Z.class).getDeclaredConstructor() + .newInstance(); + ClientCallable__Z nonInstrumented = new ClientCallable__Z(); + boolean result = (boolean) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__I() throws Exception { + ClientCallable__I instrumented = instrumentClass(ClientCallable__I.class).getDeclaredConstructor() + .newInstance(); + ClientCallable__I nonInstrumented = new ClientCallable__I(); + int result = (int) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__D() throws Exception { + ClientCallable__D instrumented = instrumentClass(ClientCallable__D.class).getDeclaredConstructor() + .newInstance(); + ClientCallable__D nonInstrumented = new ClientCallable__D(); + double result = (double) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result, 0.0); + } + + @Test + public void test__Integer() throws Exception { + ClientCallable__Integer instrumented = instrumentClass(ClientCallable__Integer.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__Integer nonInstrumented = new ClientCallable__Integer(); + Integer result = (Integer) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__JsonValue() throws Exception { + ClientCallable__JsonValue instrumented = instrumentClass(ClientCallable__JsonValue.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonValue nonInstrumented = new ClientCallable__JsonValue(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonBoolean() throws Exception { + ClientCallable__JsonBoolean instrumented = instrumentClass(ClientCallable__JsonBoolean.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonBoolean nonInstrumented = new ClientCallable__JsonBoolean(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonNumber() throws Exception { + ClientCallable__JsonNumber instrumented = instrumentClass(ClientCallable__JsonNumber.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonNumber nonInstrumented = new ClientCallable__JsonNumber(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonString() throws Exception { + ClientCallable__JsonString instrumented = instrumentClass(ClientCallable__JsonString.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonString nonInstrumented = new ClientCallable__JsonString(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonNull() throws Exception { + ClientCallable__JsonNull instrumented = instrumentClass(ClientCallable__JsonNull.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonNull nonInstrumented = new ClientCallable__JsonNull(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonArray() throws Exception { + ClientCallable__JsonArray instrumented = instrumentClass(ClientCallable__JsonArray.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonArray nonInstrumented = new ClientCallable__JsonArray(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonObject() throws Exception { + ClientCallable__JsonObject instrumented = instrumentClass(ClientCallable__JsonObject.class) + .getDeclaredConstructor().newInstance(); + ClientCallable__JsonObject nonInstrumented = new ClientCallable__JsonObject(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test_JsonValue__V() throws Exception { + ClientCallable_JsonValue__V instrumented = instrumentClass(ClientCallable_JsonValue__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNull()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonBoolean__V() throws Exception { + ClientCallable_JsonBoolean__V instrumented = instrumentClass(ClientCallable_JsonBoolean__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonBoolean()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonNumber__V() throws Exception { + ClientCallable_JsonNumber__V instrumented = instrumentClass(ClientCallable_JsonNumber__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNumber()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonString__V() throws Exception { + ClientCallable_JsonString__V instrumented = instrumentClass(ClientCallable_JsonString__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonString()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonNull__V() throws Exception { + ClientCallable_JsonNull__V instrumented = instrumentClass(ClientCallable_JsonNull__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNull()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonArray__V() throws Exception { + ClientCallable_JsonArray__V instrumented = instrumentClass(ClientCallable_JsonArray__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonArray()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonObject__V() throws Exception { + ClientCallable_JsonObject__V instrumented = instrumentClass(ClientCallable_JsonObject__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonObject()); + assertTrue(instrumented.hasBeenTraced()); + } + +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java new file mode 100644 index 0000000..221a653 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest24.java @@ -0,0 +1,66 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import com.vaadin.flow.component.Component; +import elemental.json.Json; +import elemental.json.JsonValue; +import org.junit.Rule; +import org.junit.rules.ExpectedException; + +public class ClientCallablesTest24 extends ClientCallablesTest { + + private static final String ERRMSG = "must be annotated with @LegacyClientCallable"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Override + protected Class instrumentClass(Class clazz) { + for (Class arg : getClientCallableTestMethod(clazz).getParameterTypes()) { + if (JsonValue.class.isAssignableFrom(arg)) { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(containsString(ERRMSG)); + break; + } + } + Class instrumentedClazz = new LegacyJsonMigrationHelper().instrumentClass(clazz); + assertEquals(clazz, instrumentedClazz); + return instrumentedClazz; + } + + @Override + protected Object createJsonNull() { + return Json.createNull(); + } + + @Override + protected Object createJsonBoolean() { + return Json.create(true); + } + + @Override + protected Object createJsonNumber() { + return Json.create(42); + } + + @Override + protected Object createJsonString() { + return Json.create("test"); + } + + @Override + protected Object createJsonArray() { + return Json.createArray(); + } + + @Override + protected Object createJsonObject() { + return Json.createObject(); + } + + +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java new file mode 100644 index 0000000..6ba2708 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/ClientCallablesTest25.java @@ -0,0 +1,68 @@ +package com.flowingcode.vaadin.jsonmigration; + + +import static org.hamcrest.Matchers.containsString; +import com.vaadin.flow.component.Component; +import elemental.json.JsonValue; +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; + +public class ClientCallablesTest25 extends ClientCallablesTest { + + private static final String ERRMSG = "must be annotated with @LegacyClientCallable"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Override + protected Class instrumentClass(Class clazz) { + for (Class arg : getClientCallableTestMethod(clazz).getParameterTypes()) { + if (JsonValue.class.isAssignableFrom(arg)) { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(containsString(ERRMSG)); + break; + } + } + return new JsonMigrationHelper25().instrumentClass(clazz); + } + + @Override + protected Object createJsonNull() { + return NullNode.getInstance(); + } + + @Override + protected Object createJsonBoolean() { + return BooleanNode.TRUE; + } + + @Override + protected Object createJsonNumber() { + return DoubleNode.valueOf(42); + } + + @Override + protected Object createJsonString() { + return StringNode.valueOf("test"); + } + + @Override + protected Object createJsonArray() { + return new ArrayNode(JsonNodeFactory.instance); + } + + @Override + protected Object createJsonObject() { + return new ObjectNode(JsonNodeFactory.instance); + } + +} + + diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_D__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_D__V.java new file mode 100644 index 0000000..21b6aef --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_D__V.java @@ -0,0 +1,9 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable_D__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(double arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_I__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_I__V.java new file mode 100644 index 0000000..24db69d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_I__V.java @@ -0,0 +1,9 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable_I__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(int arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonArray__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonArray__V.java new file mode 100644 index 0000000..7bebb78 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonArray__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonArray; + +public class LegacyClientCallable_JsonArray__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonArray arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonBoolean__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonBoolean__V.java new file mode 100644 index 0000000..71f290f --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonBoolean__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonBoolean; + +public class LegacyClientCallable_JsonBoolean__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonBoolean arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNull__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNull__V.java new file mode 100644 index 0000000..8f0be35 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNull__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonNull; + +public class LegacyClientCallable_JsonNull__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonNull arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNumber__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNumber__V.java new file mode 100644 index 0000000..14774e5 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonNumber__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonNumber; + +public class LegacyClientCallable_JsonNumber__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonNumber arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObject__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObject__V.java new file mode 100644 index 0000000..f433f4d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonObject__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonObject; + +public class LegacyClientCallable_JsonObject__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonObject arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonString__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonString__V.java new file mode 100644 index 0000000..4357afd --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonString__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonString; + +public class LegacyClientCallable_JsonString__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonString arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonValue__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonValue__V.java new file mode 100644 index 0000000..e1274a9 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_JsonValue__V.java @@ -0,0 +1,11 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonValue; + +public class LegacyClientCallable_JsonValue__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(JsonValue arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_String__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_String__V.java new file mode 100644 index 0000000..34b8dbf --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_String__V.java @@ -0,0 +1,9 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable_String__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(String arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_Z__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_Z__V.java new file mode 100644 index 0000000..13a3413 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable_Z__V.java @@ -0,0 +1,9 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable_Z__V extends BaseClientCallable { + + @LegacyClientCallable + public void test(boolean arg) { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__D.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__D.java new file mode 100644 index 0000000..5ff6d1f --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__D.java @@ -0,0 +1,10 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable__D extends BaseClientCallable { + + @LegacyClientCallable + public double test() { + trace(); + return 0.0; + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__I.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__I.java new file mode 100644 index 0000000..3dc6375 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__I.java @@ -0,0 +1,10 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable__I extends BaseClientCallable { + + @LegacyClientCallable + public int test() { + trace(); + return 0; + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Integer.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Integer.java new file mode 100644 index 0000000..feeacf1 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Integer.java @@ -0,0 +1,10 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable__Integer extends BaseClientCallable { + + @LegacyClientCallable + public Integer test() { + trace(); + return 0; + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonArray.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonArray.java new file mode 100644 index 0000000..9d5c6fc --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonArray.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonArray; + +public class LegacyClientCallable__JsonArray extends BaseClientCallable { + + @LegacyClientCallable + public JsonArray test() { + trace(); + return Json.createArray(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonBoolean.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonBoolean.java new file mode 100644 index 0000000..f75221e --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonBoolean.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonBoolean; + +public class LegacyClientCallable__JsonBoolean extends BaseClientCallable { + + @LegacyClientCallable + public JsonBoolean test() { + trace(); + return Json.create(true); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNull.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNull.java new file mode 100644 index 0000000..9752510 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNull.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonNull; + +public class LegacyClientCallable__JsonNull extends BaseClientCallable { + + @LegacyClientCallable + public JsonNull test() { + trace(); + return Json.createNull(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNumber.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNumber.java new file mode 100644 index 0000000..7e26cf7 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonNumber.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonNumber; + +public class LegacyClientCallable__JsonNumber extends BaseClientCallable { + + @LegacyClientCallable + public JsonNumber test() { + trace(); + return Json.create(0); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonObject.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonObject.java new file mode 100644 index 0000000..2d91759 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonObject.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonObject; + +public class LegacyClientCallable__JsonObject extends BaseClientCallable { + + @LegacyClientCallable + public JsonObject test() { + trace(); + return Json.createObject(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonString.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonString.java new file mode 100644 index 0000000..bfbd375 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonString.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonString; + +public class LegacyClientCallable__JsonString extends BaseClientCallable { + + @LegacyClientCallable + public JsonString test() { + trace(); + return Json.create(""); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonValue.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonValue.java new file mode 100644 index 0000000..ff00ae3 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__JsonValue.java @@ -0,0 +1,13 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.Json; +import elemental.json.JsonValue; + +public class LegacyClientCallable__JsonValue extends BaseClientCallable { + + @LegacyClientCallable + public JsonValue test() { + trace(); + return Json.createObject(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__V.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__V.java new file mode 100644 index 0000000..d41afcd --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__V.java @@ -0,0 +1,9 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable__V extends BaseClientCallable { + + @LegacyClientCallable + public void test() { + trace(); + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Z.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Z.java new file mode 100644 index 0000000..e53afdf --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallable__Z.java @@ -0,0 +1,10 @@ +package com.flowingcode.vaadin.jsonmigration; + +public class LegacyClientCallable__Z extends BaseClientCallable { + + @LegacyClientCallable + public boolean test() { + trace(); + return true; + } +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java new file mode 100644 index 0000000..c5e7052 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest.java @@ -0,0 +1,265 @@ +package com.flowingcode.vaadin.jsonmigration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import com.vaadin.flow.component.ClientCallable; +import com.vaadin.flow.component.Component; +import elemental.json.JsonValue; +import java.lang.reflect.Method; +import org.junit.Test; + +public abstract class LegacyClientCallablesTest { + + protected abstract Class instrumentClass(Class clazz); + + private static final String MESSAGE = "instrumented method is not annotated with @ClientCallable"; + + /** + * Finds the test method declared in the instrumented class that is annotated + * with @ClientCallable. + * + * @param c the instrumented callable instance + * @return the Method if found, null otherwise + */ + private static Method getClientCallableTestMethod(BaseClientCallable c) { + for (Method method : c.getClass().getDeclaredMethods()) { + if ("test".equals(method.getName()) && method.isAnnotationPresent(ClientCallable.class)) { + return method; + } + } + return null; + } + + /** + * Invokes the test method on the instrumented instance via reflection. + * + * @param instrumented the instrumented instance + * @param args the arguments to pass to the test method + * @return the result of the method invocation + * @throws Exception if invocation fails + */ + private static Object invokeTestMethod(BaseClientCallable instrumented, Object... args) throws Exception { + Method testMethod = getClientCallableTestMethod(instrumented); + assertTrue(MESSAGE, testMethod != null); + return testMethod.invoke(instrumented, args); + } + + protected abstract Object createJsonNull(); + + protected abstract Object createJsonBoolean(); + + protected abstract Object createJsonNumber(); + + protected abstract Object createJsonString(); + + protected abstract Object createJsonArray(); + + protected abstract Object createJsonObject(); + + @Test + public void test__V() throws Exception { + LegacyClientCallable__V instrumented = instrumentClass(LegacyClientCallable__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_Z__V() throws Exception { + LegacyClientCallable_Z__V instrumented = instrumentClass(LegacyClientCallable_Z__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, true); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_I__V() throws Exception { + LegacyClientCallable_I__V instrumented = instrumentClass(LegacyClientCallable_I__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, 42); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_D__V() throws Exception { + LegacyClientCallable_D__V instrumented = instrumentClass(LegacyClientCallable_D__V.class).getDeclaredConstructor() + .newInstance(); + invokeTestMethod(instrumented, 3.14); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_String__V() throws Exception { + LegacyClientCallable_String__V instrumented = instrumentClass(LegacyClientCallable_String__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, "test"); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test__Z() throws Exception { + LegacyClientCallable__Z instrumented = instrumentClass(LegacyClientCallable__Z.class).getDeclaredConstructor() + .newInstance(); + LegacyClientCallable__Z nonInstrumented = new LegacyClientCallable__Z(); + boolean result = (boolean) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__I() throws Exception { + LegacyClientCallable__I instrumented = instrumentClass(LegacyClientCallable__I.class).getDeclaredConstructor() + .newInstance(); + LegacyClientCallable__I nonInstrumented = new LegacyClientCallable__I(); + int result = (int) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__D() throws Exception { + LegacyClientCallable__D instrumented = instrumentClass(LegacyClientCallable__D.class).getDeclaredConstructor() + .newInstance(); + LegacyClientCallable__D nonInstrumented = new LegacyClientCallable__D(); + double result = (double) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result, 0.0); + } + + @Test + public void test__Integer() throws Exception { + LegacyClientCallable__Integer instrumented = instrumentClass(LegacyClientCallable__Integer.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__Integer nonInstrumented = new LegacyClientCallable__Integer(); + Integer result = (Integer) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test(), result); + } + + @Test + public void test__JsonValue() throws Exception { + LegacyClientCallable__JsonValue instrumented = instrumentClass(LegacyClientCallable__JsonValue.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonValue nonInstrumented = new LegacyClientCallable__JsonValue(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonBoolean() throws Exception { + LegacyClientCallable__JsonBoolean instrumented = instrumentClass(LegacyClientCallable__JsonBoolean.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonBoolean nonInstrumented = new LegacyClientCallable__JsonBoolean(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonNumber() throws Exception { + LegacyClientCallable__JsonNumber instrumented = instrumentClass(LegacyClientCallable__JsonNumber.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonNumber nonInstrumented = new LegacyClientCallable__JsonNumber(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonString() throws Exception { + LegacyClientCallable__JsonString instrumented = instrumentClass(LegacyClientCallable__JsonString.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonString nonInstrumented = new LegacyClientCallable__JsonString(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonNull() throws Exception { + LegacyClientCallable__JsonNull instrumented = instrumentClass(LegacyClientCallable__JsonNull.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonNull nonInstrumented = new LegacyClientCallable__JsonNull(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonArray() throws Exception { + LegacyClientCallable__JsonArray instrumented = instrumentClass(LegacyClientCallable__JsonArray.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonArray nonInstrumented = new LegacyClientCallable__JsonArray(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test__JsonObject() throws Exception { + LegacyClientCallable__JsonObject instrumented = instrumentClass(LegacyClientCallable__JsonObject.class) + .getDeclaredConstructor().newInstance(); + LegacyClientCallable__JsonObject nonInstrumented = new LegacyClientCallable__JsonObject(); + JsonValue result = (JsonValue) invokeTestMethod(instrumented); + assertTrue(instrumented.hasBeenTraced()); + assertEquals(nonInstrumented.test().toJson(), result.toJson()); + } + + @Test + public void test_JsonValue__V() throws Exception { + LegacyClientCallable_JsonValue__V instrumented = instrumentClass(LegacyClientCallable_JsonValue__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNull()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonBoolean__V() throws Exception { + LegacyClientCallable_JsonBoolean__V instrumented = instrumentClass(LegacyClientCallable_JsonBoolean__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonBoolean()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonNumber__V() throws Exception { + LegacyClientCallable_JsonNumber__V instrumented = instrumentClass(LegacyClientCallable_JsonNumber__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNumber()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonString__V() throws Exception { + LegacyClientCallable_JsonString__V instrumented = instrumentClass(LegacyClientCallable_JsonString__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonString()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonNull__V() throws Exception { + LegacyClientCallable_JsonNull__V instrumented = instrumentClass(LegacyClientCallable_JsonNull__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonNull()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonArray__V() throws Exception { + LegacyClientCallable_JsonArray__V instrumented = instrumentClass(LegacyClientCallable_JsonArray__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonArray()); + assertTrue(instrumented.hasBeenTraced()); + } + + @Test + public void test_JsonObject__V() throws Exception { + LegacyClientCallable_JsonObject__V instrumented = instrumentClass(LegacyClientCallable_JsonObject__V.class) + .getDeclaredConstructor().newInstance(); + invokeTestMethod(instrumented, createJsonObject()); + assertTrue(instrumented.hasBeenTraced()); + } + +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java new file mode 100644 index 0000000..27c7d21 --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest24.java @@ -0,0 +1,44 @@ +package com.flowingcode.vaadin.jsonmigration; + +import com.vaadin.flow.component.Component; +import elemental.json.Json; + +public class LegacyClientCallablesTest24 extends LegacyClientCallablesTest { + + @Override + protected Class instrumentClass(Class clazz) { + return new LegacyJsonMigrationHelper().instrumentClass(clazz); + } + + @Override + protected Object createJsonNull() { + return Json.createNull(); + } + + @Override + protected Object createJsonBoolean() { + return Json.create(true); + } + + @Override + protected Object createJsonNumber() { + return Json.create(42); + } + + @Override + protected Object createJsonString() { + return Json.create("test"); + } + + @Override + protected Object createJsonArray() { + return Json.createArray(); + } + + @Override + protected Object createJsonObject() { + return Json.createObject(); + } + + +} diff --git a/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java new file mode 100644 index 0000000..0942a3d --- /dev/null +++ b/src/test/java/com/flowingcode/vaadin/jsonmigration/LegacyClientCallablesTest25.java @@ -0,0 +1,50 @@ +package com.flowingcode.vaadin.jsonmigration; + +import com.vaadin.flow.component.Component; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; + +// this test doesn't work as-in because it requires Vaadin 25 in the classpath +public class LegacyClientCallablesTest25 extends LegacyClientCallablesTest { + + @Override + protected Class instrumentClass(Class clazz) { + return new JsonMigrationHelper25().instrumentClass(clazz); + } + + @Override + protected Object createJsonNull() { + return NullNode.getInstance(); + } + + @Override + protected Object createJsonBoolean() { + return BooleanNode.TRUE; + } + + @Override + protected Object createJsonNumber() { + return DoubleNode.valueOf(42); + } + + @Override + protected Object createJsonString() { + return StringNode.valueOf("test"); + } + + @Override + protected Object createJsonArray() { + return new ArrayNode(JsonNodeFactory.instance); + } + + @Override + protected Object createJsonObject() { + return new ObjectNode(JsonNodeFactory.instance); + } + +} From 3d324a3785dc80bb1ea2e410aa5c632edb4f91b5 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sat, 29 Nov 2025 13:55:39 -0300 Subject: [PATCH 2/7] feat: implement toJson in UnsupportedJsonValueImpl --- .../vaadin/jsonmigration/ElementalNullNode.java | 5 +++++ .../vaadin/jsonmigration/ElementalNumberNode.java | 9 +++++++++ .../vaadin/jsonmigration/UnsupportedJsonValueImpl.java | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java index c14ac17..7c70016 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNullNode.java @@ -28,5 +28,10 @@ public ElementalNullNode() { super(); } + @Override + public String toJson() { + return null; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java index 2654b92..67680cf 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ElementalNumberNode.java @@ -28,5 +28,14 @@ public ElementalNumberNode(double value) { super(value); } + @Override + public String toJson() { + double value = doubleValue(); + if (value == (long) value) { + return String.valueOf((long) value); + } else { + return UnsupportedJsonValueImpl.super.toJson(); + } + } } diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java index 25b55f6..591dfcb 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/UnsupportedJsonValueImpl.java @@ -21,6 +21,7 @@ import elemental.json.JsonType; import elemental.json.JsonValue; +import tools.jackson.databind.JsonNode; interface UnsupportedJsonValueImpl extends JsonValue { @@ -46,7 +47,7 @@ default JsonType getType() { @Override default String toJson() { - throw new UnsupportedOperationException(); + return ((JsonNode) this).toString(); } @Override From e71eab3d69c158a4b19f185c35c6c258339685f8 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:24:05 -0300 Subject: [PATCH 3/7] fix: instrument legacy callables in Vaadin 14-24 --- .../ClassInstrumentationUtil.java | 87 ++++++++++++------- .../jsonmigration/JsonMigrationHelper25.java | 4 +- .../LegacyJsonMigrationHelper.java | 6 +- 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index 30cddd5..ee8f86e 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -30,12 +30,12 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; -import lombok.experimental.UtilityClass; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -59,11 +59,15 @@ * * @author Javier Godoy / Flowing Code */ -@UtilityClass final class ClassInstrumentationUtil { - private static final Map classLoaderCache = - new WeakHashMap<>(); + private final int version; + + private static final Map classLoaderCache = new WeakHashMap<>(); + + ClassInstrumentationUtil(int version) { + this.version = version; + } /** * Creates and returns an instance of a dynamically instrumented class that extends the specified @@ -144,34 +148,54 @@ public Class instrumentClass(Class parent) } } - private static boolean needsInstrumentation(Class parent) { + private boolean needsInstrumentation(Class parent) { return !getInstrumentableMethods(parent).isEmpty(); } - private static List getInstrumentableMethods(Class parent) { - List methods = new ArrayList<>(); - for (Method method : parent.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers()) && !Modifier.isPrivate(method.getModifiers())) { + private boolean hasLegacyVaadin() { + return version <= 24; + } + + private static Stream getDeclaredCallables(Class parent) { + return Stream.of(parent.getDeclaredMethods()).filter(method -> { + int modifiers = method.getModifiers(); + if (!Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { boolean isCallable = method.isAnnotationPresent(ClientCallable.class); boolean isLegacyCallable = method.isAnnotationPresent(LegacyClientCallable.class); - if (isCallable || isLegacyCallable) { - boolean hasJsonValueReturn = JsonValue.class.isAssignableFrom(method.getReturnType()); - boolean hasJsonValueParams = hasJsonValueParameters(method); - - if (isCallable && hasJsonValueParams) { - throw new IllegalArgumentException(String.format( - "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable", - method.getName(), method.getDeclaringClass().getName(), - LegacyClientCallable.class.getName())); - } else if (isCallable && hasJsonValueReturn) { - methods.add(method); - } else if (isLegacyCallable) { - methods.add(method); - } + return isCallable || isLegacyCallable; + } + return false; + }); + } + + private List getInstrumentableMethods(Class parent) { + return getDeclaredCallables(parent).filter(method -> { + boolean isCallable = method.isAnnotationPresent(ClientCallable.class); + boolean isLegacyCallable = method.isAnnotationPresent(LegacyClientCallable.class); + + if (hasLegacyVaadin()) { + return isLegacyCallable; + } + + if (isCallable || isLegacyCallable) { + boolean hasJsonValueReturn = JsonValue.class.isAssignableFrom(method.getReturnType()); + boolean hasJsonValueParams = hasJsonValueParameters(method); + + if (isCallable && hasJsonValueParams) { + throw new IllegalArgumentException(String.format( + "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable", + method.getName(), method.getDeclaringClass().getName(), + LegacyClientCallable.class.getName())); + } else if (isCallable && hasJsonValueReturn) { + return true; + } else if (isLegacyCallable) { + return true; } } - } - return methods; + + return false; + + }).collect(Collectors.toList()); } private static boolean hasJsonValueParameters(Method method) { @@ -185,8 +209,7 @@ private static boolean hasJsonValueParameters(Method method) { private Class createInstrumentedClass(Class parent, String className) throws Exception { - InstrumentedClassLoader classLoader = - getOrCreateInstrumentedClassLoader(parent.getClassLoader()); + InstrumentedClassLoader classLoader = getOrCreateInstrumentedClassLoader(parent.getClassLoader()); return classLoader.defineInstrumentedClass(className, parent).asSubclass(parent); } @@ -196,7 +219,7 @@ private InstrumentedClassLoader getOrCreateInstrumentedClassLoader(ClassLoader p } } - private static final class InstrumentedClassLoader extends ClassLoader { + private final class InstrumentedClassLoader extends ClassLoader { private final Map, Class> instrumentedClassCache = new ConcurrentHashMap<>(); @@ -244,8 +267,8 @@ private void generateClientCallableOverrides(ClassWriter cw, Class parent, } private void generateMethodOverride(ClassWriter cw, Method method, String internalParentName) { - boolean hasJsonValueReturn = JsonValue.class.isAssignableFrom(method.getReturnType()); - boolean hasJsonValueParams = hasJsonValueParameters(method); + boolean hasJsonValueReturn = !hasLegacyVaadin() && JsonValue.class.isAssignableFrom(method.getReturnType()); + boolean hasJsonValueParams = !hasLegacyVaadin() && hasJsonValueParameters(method); String overrideDescriptor = getMethodDescriptor(method, hasJsonValueParams); String superDescriptor = getMethodDescriptor(method, false); @@ -300,7 +323,7 @@ private void generateMethodOverride(ClassWriter cw, Method method, String intern false); } - // Return converted result or void + // Return result or void if (method.getReturnType() == Void.TYPE) { mv.visitInsn(Opcodes.RETURN); } else { diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java index 24fc762..e4b0fb9 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/JsonMigrationHelper25.java @@ -42,9 +42,11 @@ @NoArgsConstructor class JsonMigrationHelper25 implements JsonMigrationHelper { + private static final ClassInstrumentationUtil instrumentation = new ClassInstrumentationUtil(25); + @Override public Class instrumentClass(Class clazz) { - return ClassInstrumentationUtil.instrumentClass(clazz); + return instrumentation.instrumentClass(clazz); } @Override diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/LegacyJsonMigrationHelper.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/LegacyJsonMigrationHelper.java index ea5c75a..bc748f5 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/LegacyJsonMigrationHelper.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/LegacyJsonMigrationHelper.java @@ -31,9 +31,11 @@ @NoArgsConstructor class LegacyJsonMigrationHelper implements JsonMigrationHelper { + private static final ClassInstrumentationUtil instrumentation = new ClassInstrumentationUtil(24); + @Override - public Class instrumentClass(Class clazz) { - return clazz; + public Class instrumentClass(Class clazz) { + return instrumentation.instrumentClass(clazz); } @Override From 596f7c5d7ab6f86f2e67ceaca78dd217b83e6d63 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:24:32 -0300 Subject: [PATCH 4/7] fix: correct use of return opcodes --- .../vaadin/jsonmigration/ClassInstrumentationUtil.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index ee8f86e..2377d74 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -326,6 +326,16 @@ private void generateMethodOverride(ClassWriter cw, Method method, String intern // Return result or void if (method.getReturnType() == Void.TYPE) { mv.visitInsn(Opcodes.RETURN); + } else if (method.getReturnType().isPrimitive()) { + if (method.getReturnType() == Long.TYPE) { + mv.visitInsn(Opcodes.LRETURN); + } else if (method.getReturnType() == Float.TYPE) { + mv.visitInsn(Opcodes.FRETURN); + } else if (method.getReturnType() == Double.TYPE) { + mv.visitInsn(Opcodes.DRETURN); + } else { + mv.visitInsn(Opcodes.IRETURN); + } } else { mv.visitInsn(Opcodes.ARETURN); } From 9c101ace6d4d4f320db037d8511d1bb5510d901e Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sat, 29 Nov 2025 12:40:12 -0300 Subject: [PATCH 5/7] fix: extract Jackson type mapping to helper class --- .../ClassInstrumentationJacksonHelper.java | 36 ++++++++++++++++++ .../ClassInstrumentationUtil.java | 37 +++++++------------ 2 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java new file mode 100644 index 0000000..3de4924 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationJacksonHelper.java @@ -0,0 +1,36 @@ +package com.flowingcode.vaadin.jsonmigration; + +import elemental.json.JsonArray; +import elemental.json.JsonBoolean; +import elemental.json.JsonNumber; +import elemental.json.JsonObject; +import elemental.json.JsonString; +import elemental.json.JsonValue; +import org.objectweb.asm.Type; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; + +class ClassInstrumentationJacksonHelper { + + public static String getConvertedTypeDescriptor(Class type) { + if (type == JsonObject.class) { + return Type.getDescriptor(ObjectNode.class); + } else if (type == JsonArray.class) { + return Type.getDescriptor(ArrayNode.class); + } else if (type == JsonBoolean.class) { + return Type.getDescriptor(BooleanNode.class); + } else if (type == JsonNumber.class) { + return Type.getDescriptor(DoubleNode.class); + } else if (type == JsonString.class) { + return Type.getDescriptor(StringNode.class); + } else if (JsonValue.class.isAssignableFrom(type)) { + return Type.getDescriptor(JsonNode.class); + } + return Type.getDescriptor(type); + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index 2377d74..f68dd5b 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -21,12 +21,10 @@ import com.vaadin.flow.component.ClientCallable; import com.vaadin.flow.component.Component; -import elemental.json.JsonArray; -import elemental.json.JsonBoolean; -import elemental.json.JsonNumber; -import elemental.json.JsonObject; -import elemental.json.JsonString; import elemental.json.JsonValue; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -36,16 +34,11 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.SneakyThrows; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import tools.jackson.databind.JsonNode; -import tools.jackson.databind.node.ArrayNode; -import tools.jackson.databind.node.BooleanNode; -import tools.jackson.databind.node.DoubleNode; -import tools.jackson.databind.node.ObjectNode; -import tools.jackson.databind.node.StringNode; /** * Utility class for instrumenting classes at runtime. @@ -377,21 +370,17 @@ private String getMethodDescriptor(Method method, boolean convertJsonValueParams return sb.toString(); } + private MethodHandle getConvertedTypeDescriptor; + + @SneakyThrows private String getConvertedTypeDescriptor(Class type) { - if (type == JsonObject.class) { - return Type.getDescriptor(ObjectNode.class); - } else if (type == JsonArray.class) { - return Type.getDescriptor(ArrayNode.class); - } else if (type == JsonBoolean.class) { - return Type.getDescriptor(BooleanNode.class); - } else if (type == JsonNumber.class) { - return Type.getDescriptor(DoubleNode.class); - } else if (type == JsonString.class) { - return Type.getDescriptor(StringNode.class); - } else if (JsonValue.class.isAssignableFrom(type)) { - return Type.getDescriptor(JsonNode.class); + if (getConvertedTypeDescriptor == null) { + Class helper = Class.forName("com.flowingcode.vaadin.jsonmigration.ClassInstrumentationJacksonHelper"); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType methodType = MethodType.methodType(String.class, Class.class); + getConvertedTypeDescriptor = lookup.findStatic(helper, "getConvertedTypeDescriptor", methodType); } - return Type.getDescriptor(type); + return (String) getConvertedTypeDescriptor.invokeExact(type); } private String[] getExceptionInternalNames(Class[] exceptionTypes) { From 954619b14f64f2c7cc00c327982e1b5090a4325d Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Sun, 30 Nov 2025 22:33:44 -0300 Subject: [PATCH 6/7] fix: check use of annotations in legacy framework versions --- .../ClassInstrumentationUtil.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index f68dd5b..cf5c261 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -165,21 +165,23 @@ private List getInstrumentableMethods(Class parent) { return getDeclaredCallables(parent).filter(method -> { boolean isCallable = method.isAnnotationPresent(ClientCallable.class); boolean isLegacyCallable = method.isAnnotationPresent(LegacyClientCallable.class); + boolean hasJsonValueReturn = JsonValue.class.isAssignableFrom(method.getReturnType()); + boolean hasJsonValueParams = hasJsonValueParameters(method); + + if (isCallable && hasJsonValueParams) { + throw new IllegalArgumentException(String.format( + "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable", + method.getName(), method.getDeclaringClass(), + LegacyClientCallable.class.getSimpleName())); + } if (hasLegacyVaadin()) { return isLegacyCallable; } if (isCallable || isLegacyCallable) { - boolean hasJsonValueReturn = JsonValue.class.isAssignableFrom(method.getReturnType()); - boolean hasJsonValueParams = hasJsonValueParameters(method); - - if (isCallable && hasJsonValueParams) { - throw new IllegalArgumentException(String.format( - "Instrumented method '%s' in class '%s' has JsonValue arguments and must be annotated with @%s instead of @ClientCallable", - method.getName(), method.getDeclaringClass().getName(), - LegacyClientCallable.class.getName())); - } else if (isCallable && hasJsonValueReturn) { + + if (isCallable && hasJsonValueReturn) { return true; } else if (isLegacyCallable) { return true; From b1003d2fcfac352eb818ed480a36ceb64829e2c5 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:33:13 -0300 Subject: [PATCH 7/7] fix: make classloader cache non-static --- .../vaadin/jsonmigration/ClassInstrumentationUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java index cf5c261..82a9153 100644 --- a/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java +++ b/src/main/java/com/flowingcode/vaadin/jsonmigration/ClassInstrumentationUtil.java @@ -56,7 +56,7 @@ final class ClassInstrumentationUtil { private final int version; - private static final Map classLoaderCache = new WeakHashMap<>(); + private final Map classLoaderCache = new WeakHashMap<>(); ClassInstrumentationUtil(int version) { this.version = version;