From 60419cdb4c794ec24e0111f9aae952e2ba8a26e1 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 28 Feb 2025 18:38:22 +0200 Subject: [PATCH 1/4] tbel: new ver 1.2.6 add test for docs: Unmodifiable --- .../service/script/TbelInvokeDocsIoTest.java | 68 ++++++++++++++++++- pom.xml | 2 +- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java index 8c8b82928a..896b7b2261 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java @@ -21,6 +21,7 @@ import org.thingsboard.script.api.tbel.TbDate; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.Collections; import java.util.Comparator; @@ -660,14 +661,13 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { """; decoderStr = """ var list = msg.list; - var listAdd = ["thigsboard", 4, 67]; return { list: list.clone(), length: list.length(), memorySize: list.memorySize(), indOf1: list.indexOf("B", 1), indOf2: list.indexOf(2, 2), - sStr: list.validateClazzInArrayIsOnlyString() + sStr: list.validateClazzInArrayIsOnlyNumber() } """; ArrayList list = new ArrayList<>(List.of(67, 2, 2, 2)); @@ -677,7 +677,7 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { expected.put("memorySize", 32L); expected.put("indOf1", -1); expected.put("indOf2", 2); - expected.put("sStr", false); + expected.put("sStr", true); Object actual = invokeScript(evalScript(decoderStr), msgStr); assertEquals(expected, actual); } @@ -2148,6 +2148,68 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { assertEquals(expected, actual); } + @Test + public void toUnmodifiableExecutionArrayList_Test() throws ExecutionException, InterruptedException { + msgStr = "{}"; + decoderStr = String.format(""" + var original = []; + original.add(0x35); + var unmodifiable = original.toUnmodifiable(); + msg.result = unmodifiable; + return {msg: msg}; + """); + LinkedHashMap expected = new LinkedHashMap<>(); + List expectedList = Arrays.asList(0x35); + LinkedHashMap expectedResult = new LinkedHashMap<>(); + expectedResult.put("result", expectedList); + expected.put("msg", expectedResult); + Object actual = invokeScript(evalScript(decoderStr), msgStr); + assertEquals(expected, actual); + + decoderStr = String.format(""" + var original = []; + original.add(0x67); + var unmodifiable = original.toUnmodifiable(); + unmodifiable.add(0x35); + msg.result = unmodifiable; + return {msg: msg}; + """); + assertThatThrownBy(() -> { + invokeScript(evalScript(decoderStr), msgStr); + }).hasMessageContaining("Error: unmodifiable.add(0x35): List is unmodifiable"); + } + + + @Test + public void toUnmodifiableExecutionHashMap_Test() throws ExecutionException, InterruptedException { + msgStr = "{}"; + decoderStr = String.format(""" + var original = {}; + original.putIfAbsent("entry1", 73); + var unmodifiable = original.toUnmodifiable(); + msg.result = unmodifiable; + return {msg: msg}; + """); + LinkedHashMap expected = new LinkedHashMap<>(); + LinkedHashMap expectedMap = new LinkedHashMap<>(Map.of("entry1", 73)); + LinkedHashMap expectedResult = new LinkedHashMap<>(); + expectedResult.put("result", expectedMap); + expected.put("msg", expectedResult); + Object actual = invokeScript(evalScript(decoderStr), msgStr); + assertEquals(expected, actual); + + decoderStr = String.format(""" + var original = {}; + original.humidity = 73; + var unmodifiable = original.toUnmodifiable(); + unmodifiable.put("temperature1", 96); + msg.result = unmodifiable; + return {msg: msg}; + """); + assertThatThrownBy(() -> { + invokeScript(evalScript(decoderStr), msgStr); + }).hasMessageContaining("Error: unmodifiable.put(\"temperature1\", 96): Map is unmodifiable"); + } private List splice(List oldList, int start, int deleteCount, Object... values) { start = initStartIndex(oldList, start); diff --git a/pom.xml b/pom.xml index 0f26f4f05c..5067582bfd 100755 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.9.2 3.25.5 1.63.0 - 1.2.5 + 1.2.6 1.18.32 1.2.5 1.2.5 From d0a51cdaeb37c9c27769962c455f19ad7db54e95 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 28 Feb 2025 19:50:37 +0200 Subject: [PATCH 2/4] tbel: tbDate docs New Function test --- .../service/script/TbelInvokeDocsIoTest.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java index 896b7b2261..2d043b72ae 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java @@ -2211,6 +2211,94 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { }).hasMessageContaining("Error: unmodifiable.put(\"temperature1\", 96): Map is unmodifiable"); } + @Test + public void tbDateFunction_Test() throws ExecutionException, InterruptedException { + msgStr = "{}"; + decoderStr = String.format(""" + var d = new Date(2024, 1, 1, 10, 0, 0, 0); // TZ => "UTC" + var dIsoY1 = d.toISOString(); // return 2024-01-01T08:00:00Z + d.addYears(1); + var dIsoY2 = d.toISOString(); // return 2025-01-01T08:00:00Z + d.addYears(-2); + var dIsoY3 = d.toISOString(); // return 2023-01-01T08:00:00Z + d.addMonths(2); + var dIsoM1 = d.toISOString(); // return 2023-03-01T08:00:00Z + d.addMonths(10); + var dIsoM2 = d.toISOString(); // return 2024-01-01T08:00:00Z + d.addMonths(-13); + var dIsoM3 = d.toISOString(); // return 2022-12-01T08:00:00Z + d.addWeeks(4); + var dIsoW1 = d.toISOString(); // return 2022-12-29T08:00:00Z + d.addWeeks(-5); + var dIsoW2 = d.toISOString(); // return 2022-11-24T08:00:00Z + d.addDays(6); + var dIsoD1 = d.toISOString(); // return 2022-11-30T08:00:00Z + d.addDays(45); + var dIsoD2 = d.toISOString(); // return 2023-01-14T08:00:00Z + d.addDays(-50); + var dIsoD3 = d.toISOString(); // return 2022-11-25T08:00:00Z + d.addHours(23); + var dIsoH1 = d.toISOString(); // return 2022-11-26T07:00:00Z + d.addHours(-47); + var dIsoH2 = d.toISOString(); // return 2022-11-24T08:00:00Z + d.addMinutes(59); + var dIsoMin1 = d.toISOString(); // return 2022-11-24T08:59:00Z + d.addMinutes(-60); + var dIsoMin2 = d.toISOString(); // return 2022-11-24T07:59:00Z + d.addSeconds(59); + var dIsoS1 = d.toISOString(); // return 2022-11-24T07:59:59Z + d.addSeconds(-60); + var dIsoS2 = d.toISOString(); // return 2022-11-24T07:58:59Z + d.addNanos(999999); + var dIsoN1 = d.toISOString(); // return 2022-11-24T07:58:59.000999999Z + d.addNanos(-1000000); + var dIsoN2 = d.toISOString(); // return 2022-11-24T07:58:58.999999999Z + return { + "dIsoY1": dIsoY1, + "dIsoY2": dIsoY2, + "dIsoY3": dIsoY3, + "dIsoM1": dIsoM1, + "dIsoM2": dIsoM2, + "dIsoM3": dIsoM3, + "dIsoW1": dIsoW1, + "dIsoW2": dIsoW2, + "dIsoD1": dIsoD1, + "dIsoD2": dIsoD2, + "dIsoD3": dIsoD3, + "dIsoH1": dIsoH1, + "dIsoH2": dIsoH2, + "dIsoMin1": dIsoMin1, + "dIsoMin2": dIsoMin2, + "dIsoS1": dIsoS1, + "dIsoS2": dIsoS2, + "dIsoN1": dIsoN1, + "dIsoN2": dIsoN2 + } + """); + LinkedHashMap expected = new LinkedHashMap<>(); + expected.put("dIsoY1", "2024-01-01T08:00:00Z"); + expected.put("dIsoY2", "2025-01-01T08:00:00Z"); + expected.put("dIsoY3", "2023-01-01T08:00:00Z"); + expected.put("dIsoM1", "2023-03-01T08:00:00Z"); + expected.put("dIsoM2", "2024-01-01T08:00:00Z"); + expected.put("dIsoM3", "2022-12-01T08:00:00Z"); + expected.put("dIsoW1", "2022-12-29T08:00:00Z"); + expected.put("dIsoW2", "2022-11-24T08:00:00Z"); + expected.put("dIsoD1", "2022-11-30T08:00:00Z"); + expected.put("dIsoD2", "2023-01-14T08:00:00Z"); + expected.put("dIsoD3", "2022-11-25T08:00:00Z"); + expected.put("dIsoH1", "2022-11-26T07:00:00Z"); + expected.put("dIsoH2", "2022-11-24T08:00:00Z"); + expected.put("dIsoMin1", "2022-11-24T08:59:00Z"); + expected.put("dIsoMin2", "2022-11-24T07:59:00Z"); + expected.put("dIsoS1", "2022-11-24T07:59:59Z"); + expected.put("dIsoS2", "2022-11-24T07:58:59Z"); + expected.put("dIsoN1", "2022-11-24T07:58:59.000999999Z"); + expected.put("dIsoN2", "2022-11-24T07:58:58.999999999Z"); + Object actual = invokeScript(evalScript(decoderStr), msgStr); + assertEquals(expected, actual); + } + private List splice(List oldList, int start, int deleteCount, Object... values) { start = initStartIndex(oldList, start); deleteCount = deleteCount < 0 ? 0 : Math.min(deleteCount, (oldList.size() - start)); From cf8e3aa4cd860e4184382f2321e550db1bc37d6b Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 3 Mar 2025 13:02:29 +0200 Subject: [PATCH 3/4] tbel: Maps docs 'foreach(element : map --- .../service/script/TbelInvokeDocsIoTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java index 2d043b72ae..8b6c739d31 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java @@ -147,6 +147,31 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { assertEquals(expected, actual); } + @Test + public void mapsImplicitIterationWithoutEntrySet() throws ExecutionException, InterruptedException { + msgStr = msgMapStr; + decoderStr = """ + foreach(element : msg){ + if(element.getKey() == null){ + return raiseError("Bad getKey"); + } + if(element.key == null){ + return raiseError("Bad key"); + } + if(element.getValue() == null){ + return raiseError("Bad getValue"); + } + if(element.value == null){ + return raiseError("Bad value"); + } + } + return msg; + """; + LinkedHashMap expected = expectedMap; + Object actual = invokeScript(evalScript(decoderStr), msgStr); + assertEquals(expected, actual); + } + @Test public void mapsGetInfoSize_Test() throws ExecutionException, InterruptedException { msgStr = msgMapStr; From bb5d0233fc3f42fed16d2828cd5363a6a6e25f4e Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 5 Mar 2025 14:57:23 +0200 Subject: [PATCH 4/4] tbel: tbDate test function with TZ => "UTC" --- .../service/script/TbelInvokeDocsIoTest.java | 101 +++++++++++------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java index 8b6c739d31..bf86f98e6e 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java @@ -2238,46 +2238,49 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { @Test public void tbDateFunction_Test() throws ExecutionException, InterruptedException { + String stringDateUTC = "2024-01-01T10:00:00.00Z"; + TbDate d = new TbDate(stringDateUTC); + msgStr = "{}"; decoderStr = String.format(""" - var d = new Date(2024, 1, 1, 10, 0, 0, 0); // TZ => "UTC" - var dIsoY1 = d.toISOString(); // return 2024-01-01T08:00:00Z + var d = new Date("%s"); // TZ => "UTC" + var dIsoY1 = d.toISOString(); // return 2024-01-01T10:00:00Z d.addYears(1); - var dIsoY2 = d.toISOString(); // return 2025-01-01T08:00:00Z + var dIsoY2 = d.toISOString(); // return 2025-01-01T10:00:00Z d.addYears(-2); - var dIsoY3 = d.toISOString(); // return 2023-01-01T08:00:00Z + var dIsoY3 = d.toISOString(); // return 2023-01-01T10:00:00Z d.addMonths(2); - var dIsoM1 = d.toISOString(); // return 2023-03-01T08:00:00Z + var dIsoM1 = d.toISOString(); // return 2023-03-01T10:00:00Z d.addMonths(10); - var dIsoM2 = d.toISOString(); // return 2024-01-01T08:00:00Z + var dIsoM2 = d.toISOString(); // return 2024-01-01T10:00:00Z d.addMonths(-13); - var dIsoM3 = d.toISOString(); // return 2022-12-01T08:00:00Z + var dIsoM3 = d.toISOString(); // return 2022-12-01T10:00:00Z d.addWeeks(4); - var dIsoW1 = d.toISOString(); // return 2022-12-29T08:00:00Z + var dIsoW1 = d.toISOString(); // return 2022-12-29T10:00:00Z d.addWeeks(-5); - var dIsoW2 = d.toISOString(); // return 2022-11-24T08:00:00Z + var dIsoW2 = d.toISOString(); // return 2022-11-24T10:00:00Z d.addDays(6); - var dIsoD1 = d.toISOString(); // return 2022-11-30T08:00:00Z + var dIsoD1 = d.toISOString(); // return 2022-11-30T10:00:00Z d.addDays(45); - var dIsoD2 = d.toISOString(); // return 2023-01-14T08:00:00Z + var dIsoD2 = d.toISOString(); // return 2023-01-14T10:00:00Z d.addDays(-50); - var dIsoD3 = d.toISOString(); // return 2022-11-25T08:00:00Z + var dIsoD3 = d.toISOString(); // return 2022-11-25T10:00:00Z d.addHours(23); - var dIsoH1 = d.toISOString(); // return 2022-11-26T07:00:00Z + var dIsoH1 = d.toISOString(); // return 2022-11-26T09:00:00Z d.addHours(-47); - var dIsoH2 = d.toISOString(); // return 2022-11-24T08:00:00Z + var dIsoH2 = d.toISOString(); // return 2022-11-24T10:00:00Z d.addMinutes(59); - var dIsoMin1 = d.toISOString(); // return 2022-11-24T08:59:00Z + var dIsoMin1 = d.toISOString(); // return 2022-11-24T10:59:00Z d.addMinutes(-60); - var dIsoMin2 = d.toISOString(); // return 2022-11-24T07:59:00Z + var dIsoMin2 = d.toISOString(); // return 2022-11-24T09:59:00Z d.addSeconds(59); - var dIsoS1 = d.toISOString(); // return 2022-11-24T07:59:59Z + var dIsoS1 = d.toISOString(); // return 2022-11-24T09:59:59Z d.addSeconds(-60); - var dIsoS2 = d.toISOString(); // return 2022-11-24T07:58:59Z + var dIsoS2 = d.toISOString(); // return 2022-11-24T09:58:59Z d.addNanos(999999); - var dIsoN1 = d.toISOString(); // return 2022-11-24T07:58:59.000999999Z + var dIsoN1 = d.toISOString(); // return 2022-11-24T09:58:59.000999999Z d.addNanos(-1000000); - var dIsoN2 = d.toISOString(); // return 2022-11-24T07:58:58.999999999Z + var dIsoN2 = d.toISOString(); // return 2022-11-24T09:58:58.999999999Z return { "dIsoY1": dIsoY1, "dIsoY2": dIsoY2, @@ -2299,27 +2302,45 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { "dIsoN1": dIsoN1, "dIsoN2": dIsoN2 } - """); + """, stringDateUTC); LinkedHashMap expected = new LinkedHashMap<>(); - expected.put("dIsoY1", "2024-01-01T08:00:00Z"); - expected.put("dIsoY2", "2025-01-01T08:00:00Z"); - expected.put("dIsoY3", "2023-01-01T08:00:00Z"); - expected.put("dIsoM1", "2023-03-01T08:00:00Z"); - expected.put("dIsoM2", "2024-01-01T08:00:00Z"); - expected.put("dIsoM3", "2022-12-01T08:00:00Z"); - expected.put("dIsoW1", "2022-12-29T08:00:00Z"); - expected.put("dIsoW2", "2022-11-24T08:00:00Z"); - expected.put("dIsoD1", "2022-11-30T08:00:00Z"); - expected.put("dIsoD2", "2023-01-14T08:00:00Z"); - expected.put("dIsoD3", "2022-11-25T08:00:00Z"); - expected.put("dIsoH1", "2022-11-26T07:00:00Z"); - expected.put("dIsoH2", "2022-11-24T08:00:00Z"); - expected.put("dIsoMin1", "2022-11-24T08:59:00Z"); - expected.put("dIsoMin2", "2022-11-24T07:59:00Z"); - expected.put("dIsoS1", "2022-11-24T07:59:59Z"); - expected.put("dIsoS2", "2022-11-24T07:58:59Z"); - expected.put("dIsoN1", "2022-11-24T07:58:59.000999999Z"); - expected.put("dIsoN2", "2022-11-24T07:58:58.999999999Z"); + expected.put("dIsoY1", d.toISOString()); + d.addYears(1); + expected.put("dIsoY2", d.toISOString()); + d.addYears(-2); + expected.put("dIsoY3", d.toISOString()); + d.addMonths(2); + expected.put("dIsoM1", d.toISOString()); + d.addMonths(10); + expected.put("dIsoM2", d.toISOString()); + d.addMonths(-13); + expected.put("dIsoM3", d.toISOString()); + d.addWeeks(4); + expected.put("dIsoW1", d.toISOString()); + d.addWeeks(-5); + expected.put("dIsoW2", d.toISOString()); + d.addDays(6); + expected.put("dIsoD1", d.toISOString()); + d.addDays(45); + expected.put("dIsoD2", d.toISOString()); + d.addDays(-50); + expected.put("dIsoD3", d.toISOString()); + d.addHours(23); + expected.put("dIsoH1", d.toISOString()); + d.addHours(-47); + expected.put("dIsoH2", d.toISOString()); + d.addMinutes(59); + expected.put("dIsoMin1", d.toISOString()); + d.addMinutes(-60); + expected.put("dIsoMin2", d.toISOString()); + d.addSeconds(59); + expected.put("dIsoS1", d.toISOString()); + d.addSeconds(-60); + expected.put("dIsoS2", d.toISOString()); + d.addNanos(999999); + expected.put("dIsoN1", d.toISOString()); + d.addNanos(-1000000); + expected.put("dIsoN2", d.toISOString()); Object actual = invokeScript(evalScript(decoderStr), msgStr); assertEquals(expected, actual); }