From 7b48f84439f7448386c87eee3030a90bbeecadac Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:50:36 +0300 Subject: [PATCH 01/12] Update skript_repo_ref to 2.15.0-pre1 and remove obsolete scripts (#15) * Update skript_repo_ref to version 2.15.0-pre1 * Delete scripts/libs/pdc.sk * Delete tests/working/libs/pdc.test.sk * Delete tests/working/libs/routines.test.sk * Delete scripts/libs/routines.sk * Delete docs/pdc.md --- .github/workflows/test-skripts.yml | 2 +- docs/pdc.md | 136 ------------------- scripts/libs/pdc.sk | 210 ----------------------------- tests/working/libs/pdc.test.sk | 115 ---------------- 4 files changed, 1 insertion(+), 462 deletions(-) delete mode 100644 docs/pdc.md delete mode 100644 scripts/libs/pdc.sk delete mode 100644 tests/working/libs/pdc.test.sk diff --git a/.github/workflows/test-skripts.yml b/.github/workflows/test-skripts.yml index 2181fa8..aaf0a0a 100644 --- a/.github/workflows/test-skripts.yml +++ b/.github/workflows/test-skripts.yml @@ -88,7 +88,7 @@ jobs: test_script_directory: tests # Skript version or ref (tag, branch, or commit) - skript_repo_ref: 2.14.3 + skript_repo_ref: 2.15.0-pre1 # directory containing addon/plugin jars (relative to repo root) extra_plugins_directory: build/libs diff --git a/docs/pdc.md b/docs/pdc.md deleted file mode 100644 index 689d457..0000000 --- a/docs/pdc.md +++ /dev/null @@ -1,136 +0,0 @@ -# Persistent Data Container (PDC) Utility Expressions for Skript - ---- - -## Overview - -This document describes a set of Skript expressions and helpers for interacting with Bukkit's `PersistentDataContainer` (PDC). - -It supports: - -- Native `PersistentDataType` (PDT) values -- Arbitrary object storage via Java serialization into `BYTE_ARRAY` - ---- - -## Requirements - -- Paper server -- Skript -- skript-reflect - ---- - -## Key Features - -### 1. Unified `key … in pdc` Expression - -- Read, write, and delete PDC entries using a single expression -- Automatically resolves: - - `PersistentDataHolder` → `PersistentDataContainer` - ---- - -### 2. Native and Arbitrary Object Storage - -- When a `PersistentDataType` is provided: - → Values are stored natively using that PDT -- When omitted: - → Values are serialized and stored as `PersistentDataType.BYTE_ARRAY` - ---- - -### 3. Built-in NamespacedKey Handling - -There is **no standalone NamespacedKey expression**. - -Instead, namespaced keys are handled directly by the main expression using string input. - -Key strings must be in the form: - -``` - -namespace:key - -```` - -Example: - -```skript -"minecraft:foo" -"myplugin:data" -```` - ---- - -### 4. Safety and Validation - -* Runtime validation ensures correct types for: - - * Key string - * Container / holder - * PersistentDataType (if provided) -* Invalid expressions fail silently to avoid hard Skript errors - ---- - -## Serialization Notes - -* Arbitrary objects are serialized using `BukkitObjectOutputStream` -* Data is stored directly as `byte[]` via `PersistentDataType.BYTE_ARRAY` -* Objects **must** implement `java.io.Serializable` - ---- - -## Syntax Summary - -### Core Expression - -```skript -expression [devdinc] [namespaced]( |-)key %string% [with]in %pdcholder/pdc% [for %-pdt%] -``` - ---- - -### Reading - -```skript -set {_value} to key "plugin:test" within player's pdc -set {_value} to key "plugin:test" in player's pdc for pdt string -``` - ---- - -### Writing - -```skript -set key "plugin:test" within player's pdc to {_object} -set key "plugin:test" in player's pdc for pdt integer to 5 -``` - ---- - -### Deleting - -```skript -delete key "plugin:test" within player's pdc -``` - ---- - -## Behavior Notes - -* If no `PersistentDataType` is specified, `BYTE_ARRAY` storage is used -* Setting a key to `null` removes the entry -* Deleting a key removes it regardless of storage type - ---- - -## Caveats - -* Deserialization failures will propagate runtime errors -* Class definition changes may break previously serialized data -* Stored objects must remain compatible with Java serialization - ---- - diff --git a/scripts/libs/pdc.sk b/scripts/libs/pdc.sk deleted file mode 100644 index b101372..0000000 --- a/scripts/libs/pdc.sk +++ /dev/null @@ -1,210 +0,0 @@ -import: - org.bukkit.NamespacedKey - org.bukkit.persistence.PersistentDataContainer - org.bukkit.persistence.PersistentDataHolder - org.bukkit.persistence.PersistentDataType - java.io.ByteArrayInputStream - java.io.ByteArrayOutputStream - org.bukkit.util.io.BukkitObjectInputStream - org.bukkit.util.io.BukkitObjectOutputStream - ch.njol.skript.lang.Variable - java.lang.Byte - java.lang.Short - java.lang.Integer - java.lang.Long - java.lang.Float - java.lang.Double - java.lang.Boolean - -on load: - set scoped {-primitives::pdt::*} to PersistentDataType.BOOLEAN, PersistentDataType.BYTE, PersistentDataType.SHORT, PersistentDataType.INTEGER, PersistentDataType.LONG, PersistentDataType.FLOAT, PersistentDataType.DOUBLE, PersistentDataType.STRING, PersistentDataType.TAG_CONTAINER - set scoped {-primitives::str::*} to "bool", "byte", "short", "int", "long", "float", "double", "str", "pdc" - set scoped {-primitives::int::*} to 8, 6, 7, 2, 3, 4, 5, 1, 9 - -local function validate_pdcexpr(key: object, pdc: object, pdt: object) :: boolean: - if all: - {_pdt} is set - {_pdt} is not an instance of PersistentDataType - then: - return false - if any: - {_key} is not an instance of NamespacedKey - {_pdc} is not an instance of PersistentDataContainer - then: - return false - return true - - -local function coerce_pdt_value(pdt: object, value: object) :: object: - if {_value} is not set: - return {_none} - - if {_pdt} is PersistentDataType.INTEGER: - return try new Integer({_value}) if {_value} is an integer - - else if {_pdt} is PersistentDataType.BYTE: - return try new Byte({_value}) if {_value} is an integer - - else if {_pdt} is PersistentDataType.SHORT: - return try new Short({_value}) if {_value} is an integer - - else if {_pdt} is PersistentDataType.LONG: - return try new Long({_value}) if {_value} is an integer - - else if {_pdt} is PersistentDataType.FLOAT: - return try new Float({_value}) - - else if {_pdt} is PersistentDataType.DOUBLE: - return try new Double({_value}) - - else if {_pdt} is PersistentDataType.STRING: - return {_value} if {_value} is a text - - else if {_pdt} is PersistentDataType.BOOLEAN: - return {_value} if {_value} is a boolean - - else if {_pdt} is PersistentDataType.TAG_CONTAINER: - return {_value} if {_value} is an instance of PersistentDataContainer - - else if {_pdt} is PersistentDataType.BYTE_ARRAY: - return {_value} - - return {_none} - - -expression [devdinc] [namespaced]( |-)key %string% [with]in %object%[ for %-object%]: - parse: - set {_pdt} to expr-3 - - if any: - "%{_pdt}%" contains "[devdinc] (pdt|[persistent data ]type)" - "%{_pdt}%" contains "PersistentDataType" - {_pdt} is instance of Variable - {_pdt} is not set - then: - continue - - get: - set {_key} to NamespacedKey.fromString(expr-1, null) - set {_pdc} to expr-2.getPersistentDataContainer() if expr-2 is instance of PersistentDataHolder else expr-2 - set {_pdt} to expr-3 - - stop if validate_pdcexpr({_key}, {_pdc}, {_pdt}) is false - - if {_pdt} is not set: - set {_typeKey} to NamespacedKey.fromString("%{_key}%..type", null) - - if {_pdc}.has({_typeKey}, PersistentDataType.STRING): - set {_typeId} to {_pdc}.get({_typeKey}, PersistentDataType.STRING) - - set {_i} to 1 - loop scoped {-primitives::str::*}: - if {_typeId} is loop-value: - set {_pdt} to {_i}th element of scoped {-primitives::pdt::*} - return try {_pdc}.get({_key}, {_pdt}) # try is used for if the key does not exist - add 1 to {_i} - - else: - if {_pdc}.has({_key}, PersistentDataType.BYTE_ARRAY) is false: - return {_none} - - set {_bytes} to {_pdc}.get({_key}, PersistentDataType.BYTE_ARRAY) - set {_in} to new BukkitObjectInputStream(new ByteArrayInputStream({_bytes})) - set {_obj} to {_in}.readObject() - {_in}.close() - return {_obj} - else: - return {_pdc}.get({_key}, {_pdt}) - - set: - set {_key} to NamespacedKey.fromString(expr-1, null) - set {_pdc} to expr-2.getPersistentDataContainer() if expr-2 is instance of PersistentDataHolder else expr-2 - set {_pdt} to expr-3 - - stop if validate_pdcexpr({_key}, {_pdc}, {_pdt}) is false - - set {_value} to change value - - if any: - {_value} is null - {_value} is not set - then: - {_pdc}.remove({_key}) - stop - - if {_pdt} is not set: - set {_typeKey} to NamespacedKey.fromString("%{_key}%..type", null) - - set {_i} to 1 - loop scoped {-primitives::pdt::*}: - set {_try} to coerce_pdt_value(loop-value, {_value}) - - if {_try} is set: - {_pdc}.set({_key}, loop-value, {_try}) - {_pdc}.set({_typeKey}, PersistentDataType.STRING, {_i}th element of scoped {-primitives::str::*}) - - stop - - add 1 to {_i} - - set {_baos} to new ByteArrayOutputStream() - set {_out} to new BukkitObjectOutputStream({_baos}) - {_out}.writeObject({_value}) - {_out}.close() - - set {_boxedBytes::*} to ...{_baos}.toByteArray() - set {_bytes} to new byte[size of {_boxedBytes::*}] - loop {_boxedBytes::*}: - set {_bytes}[loop-index parsed as number - 1] to loop-value - - {_pdc}.set({_key}, PersistentDataType.BYTE_ARRAY, {_bytes}) - - else: - set {_coerced} to coerce_pdt_value({_pdt}, {_value}) - {_pdc}.set({_key}, {_pdt}, {_coerced}) - - - delete: - set {_key} to NamespacedKey.fromString(expr-1, null) - set {_pdc} to expr-2.getPersistentDataContainer() if expr-2 is instance of PersistentDataHolder else expr-2 - set {_pdt} to expr-3 - - stop if validate_pdcexpr({_key}, {_pdc}, {_pdt}) is false - - set {_typeKey} to NamespacedKey.fromString("%{_key}%..type", null) - {_pdc}.remove({_typeKey}) - {_pdc}.remove({_key}) - - -object property p[ersistent ]d[ata ]c[ontainer]: - parse: - continue - get: - return expr-1.getPersistentDataContainer() - - -expression [devdinc] new p[ersistent ]d[ata ]c[ontainer] from %object%: - parse: - continue - get: - set {_src} to expr-1 - - if {_src} is instance of PersistentDataHolder: - set {_ctx} to {_src}.getPersistentDataContainer().getAdapterContext() - return {_ctx}.newPersistentDataContainer() - - if {_src} is instance of PersistentDataContainer: - set {_ctx} to {_src}.getAdapterContext() - return {_ctx}.newPersistentDataContainer() - - return {_none} - - -expression [devdinc] (pdt|[persistent data ]type) [of] (1:str[ing]|2:int[eger]|3:long|4:float|5:double|6:byte|7:short|8:bool[ean]|9:container): - parse: - continue - get: - set {_l::*} to scoped {-primitives::int::*} - set {_i} to {_l::%parse mark%} - return {_i}th element of scoped {-primitives::pdt::*} - diff --git a/tests/working/libs/pdc.test.sk b/tests/working/libs/pdc.test.sk deleted file mode 100644 index aad6eb4..0000000 --- a/tests/working/libs/pdc.test.sk +++ /dev/null @@ -1,115 +0,0 @@ -import: - java.util.HashMap - -on load: - set scoped {-key} to "plugin:test_pdt" - -after each test: - event-script is current script - delete namespaced-key scoped {-key} within test-world if scoped {-key} is set - -# since we use after each test we have to use devdinc test pattern here - -devdinc test "pdc basic set/get with typed pdt": - - set namespaced-key scoped {-key} within test-world for pdt integer to 42 - assert namespaced-key scoped {-key} within test-world for pdt integer is 42 with "typed pdt get failed" - -devdinc test "pdc overwrite typed value": - - set namespaced-key scoped {-key} within test-world for pdt string to "a" - set namespaced-key scoped {-key} within test-world for pdt string to "b" - - assert namespaced-key scoped {-key} within test-world for pdt string is "b" with "overwrite failed" - -devdinc test "pdc delete typed value": - set namespaced-key scoped {-key} within test-world for pdt long to 100 - delete namespaced-key scoped {-key} within test-world for pdt long - - assert namespaced-key scoped {-key} within test-world for pdt long is not set with "delete failed" - -devdinc test "pdc object serialization (byte_array implicit)": - - set {_obj} to new HashMap() - {_obj}.put("a", 1) - {_obj}.put("b", 2) - - set namespaced-key scoped {-key} within test-world to {_obj} - - set {_out} to namespaced-key scoped {-key} within test-world - assert {_out}.get("a") is 1 with "object deserialize failed (a)" - assert {_out}.get("b") is 2 with "object deserialize failed (b)" - -devdinc test "pdc remove object via null": - - set namespaced-key scoped {-key} within test-world to "temp" - set namespaced-key scoped {-key} within test-world to null - - assert namespaced-key scoped {-key} within test-world is not set with "object remove via null failed" - -devdinc test "pdc holder vs direct pdc equivalence": - set {_pdc} to test-world's pdc - - set namespaced-key scoped {-key} within test-world for pdt byte to 7 - assert namespaced-key scoped {-key} within {_pdc} for pdt byte is 7 with "direct pdc access failed" - -devdinc test "pdc boolean pdt": - - set namespaced-key scoped {-key} within test-world for pdt boolean to true - assert namespaced-key scoped {-key} within test-world for pdt boolean is true with "boolean pdt failed" - -devdinc test "pdc default object missing returns none": - - assert namespaced-key scoped {-key} within test-world is not set with "missing object did not return none" - -devdinc test "pdc unspecified pdt boolean": - - set namespaced-key scoped {-key} within test-world to true - assert namespaced-key scoped {-key} within test-world is true with "unspecified boolean failed" - -devdinc test "pdc unspecified pdt byte": - - set namespaced-key scoped {-key} within test-world to 5 - assert namespaced-key scoped {-key} within test-world is 5 with "unspecified byte failed" - -devdinc test "pdc unspecified pdt short": - - set namespaced-key scoped {-key} within test-world to 12 - assert namespaced-key scoped {-key} within test-world is 12 with "unspecified short failed" - -devdinc test "pdc unspecified pdt integer": - - set namespaced-key scoped {-key} within test-world to 123 - assert namespaced-key scoped {-key} within test-world is 123 with "unspecified integer failed" - -devdinc test "pdc unspecified pdt long": - - set namespaced-key scoped {-key} within test-world to 123 - assert namespaced-key scoped {-key} within test-world is 123 with "unspecified long failed" - -devdinc test "pdc unspecified pdt float": - - set namespaced-key scoped {-key} within test-world to 1.5 - assert namespaced-key scoped {-key} within test-world is 1.5 with "unspecified float failed" - -devdinc test "pdc unspecified pdt double": - - set namespaced-key scoped {-key} within test-world to 2.75 - assert namespaced-key scoped {-key} within test-world is 2.75 with "unspecified double failed" - - -devdinc test "pdc unspecified pdt string": - - set namespaced-key scoped {-key} within test-world to "hello" - assert namespaced-key scoped {-key} within test-world is "hello" with "unspecified string failed" - -devdinc test "pdc unspecified pdt tag_container": - - set {_inner-pdc} to new pdc from test-world - set {_inner-key} to "plugin:inner_key" - set namespaced-key {_inner-key} within {_inner-pdc} for pdt integer to 9 - - set namespaced-key scoped {-key} within test-world to {_inner-pdc} - - set {_out-pdc} to namespaced-key scoped {-key} within test-world - assert namespaced-key {_inner-key} within {_out-pdc} for pdt integer is 9 with "unspecified tag_container failed" From da44c10cbfcaf8834f3141c17477d9d8dd9be97a Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:13:49 +0300 Subject: [PATCH 02/12] Update test action and Skript version in workflow --- .github/workflows/test-skripts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-skripts.yml b/.github/workflows/test-skripts.yml index aaf0a0a..fefc307 100644 --- a/.github/workflows/test-skripts.yml +++ b/.github/workflows/test-skripts.yml @@ -81,14 +81,14 @@ jobs: EOF - name: Run tests - uses: devdinc/skript-test-action@v1.3 + uses: SkriptLang/skript-test-action@v1.3 with: skript_repo_url: https://github.com/SkriptLang/Skript.git # directory where your test scripts are located (relative to repo root) test_script_directory: tests # Skript version or ref (tag, branch, or commit) - skript_repo_ref: 2.15.0-pre1 + skript_repo_ref: 2.15.0 # directory containing addon/plugin jars (relative to repo root) extra_plugins_directory: build/libs From 20d88481c50b3823363208986c3f40d650615470 Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 17:30:03 +0300 Subject: [PATCH 03/12] Refactor key assignment for SectionNode instances --- scripts/libs/functionsv2.sk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/libs/functionsv2.sk b/scripts/libs/functionsv2.sk index 5551d1e..c3136cf 100644 --- a/scripts/libs/functionsv2.sk +++ b/scripts/libs/functionsv2.sk @@ -150,7 +150,8 @@ condition set %object% to [new] lambda[ %-objects%](1:|2:-|3:+): loop {_functionsv2.sk::ctx::nodes::*}: set {_functionsv2.sk::ctx::indent} to loop-value.[Node]getIndentation().substring(length of {_functionsv2.sk::ctx::originindent} + 4) if {_functionsv2.sk::ctx::originindent} starts with " " else loop-value.[Node]getIndentation().substring(length of {_functionsv2.sk::ctx::originindent} + 1) set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::indent}%%loop-value.getKey()%" - set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::key}%:" if loop-value is instance of SectionNode + if loop-value is instance of SectionNode: + set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::key}%:" add {_functionsv2.sk::ctx::key} to {_functionsv2.sk::ctx::expr::*} {_functionsv2.sk::ctx::key}.trim() starts with "return" set {_functionsv2.sk::ctx::noreturn} to false if parse mark is 1 @@ -176,7 +177,8 @@ condition set %object% to [new] (1:supplier|1:getter|2:runnable|2:runner|3:consu loop {_functionsv2.sk::ctx::nodes::*}: set {_functionsv2.sk::ctx::indent} to loop-value.[Node]getIndentation().substring(length of {_functionsv2.sk::ctx::originindent} + 4) if {_functionsv2.sk::ctx::originindent} starts with " " else loop-value.[Node]getIndentation().substring(length of {_functionsv2.sk::ctx::originindent} + 1) set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::indent}%%loop-value.getKey()%" - set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::key}%:" if loop-value is instance of SectionNode + if loop-value is instance of SectionNode: + set {_functionsv2.sk::ctx::key} to "%{_functionsv2.sk::ctx::key}%:" add {_functionsv2.sk::ctx::key} to {_functionsv2.sk::ctx::expr::*} set {_functionsv2.sk::ctx::args::*} to FextractArgs({_functionsv2.sk::ctx::vars}) From eda036fbfb380c2402944231b5b2017655a16018 Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 17:40:51 +0300 Subject: [PATCH 04/12] Include current script in test failure tracking --- scripts/utils/testframework.sk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/utils/testframework.sk b/scripts/utils/testframework.sk index 8006d69..130e5e6 100644 --- a/scripts/utils/testframework.sk +++ b/scripts/utils/testframework.sk @@ -210,7 +210,7 @@ effect: then: if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", expr-1 - TestTracker.testFailed(expr-1) + TestTracker.testFailed(expr-1, current script) add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect @@ -223,7 +223,7 @@ effect (3:|4:(no|without) (halt[ing]|fail[(-| )](safe|fast)|abort[ing])) fail te set {_script} to event.getEventValue("script") if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" failed", expr-1 - TestTracker.testFailed(expr-1) + TestTracker.testFailed(expr-1, current script) add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect From f34dc3059867e4b2e347ce4d1daafa370f6326e1 Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 17:51:18 +0300 Subject: [PATCH 05/12] Improve error reporting in test framework --- scripts/utils/testframework.sk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/utils/testframework.sk b/scripts/utils/testframework.sk index 130e5e6..43bd1f6 100644 --- a/scripts/utils/testframework.sk +++ b/scripts/utils/testframework.sk @@ -210,8 +210,8 @@ effect: then: if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", expr-1 - TestTracker.testFailed(expr-1, current script) - add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} + TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) + add "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect @@ -223,8 +223,8 @@ effect (3:|4:(no|without) (halt[ing]|fail[(-| )](safe|fast)|abort[ing])) fail te set {_script} to event.getEventValue("script") if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" failed", expr-1 - TestTracker.testFailed(expr-1, current script) - add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} + TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) + add "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect From 435add607abd18ac0a20638c5ebdde07f4589c9c Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:00:29 +0300 Subject: [PATCH 06/12] Revert error specification in test framework --- scripts/utils/testframework.sk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/utils/testframework.sk b/scripts/utils/testframework.sk index 43bd1f6..d07c31d 100644 --- a/scripts/utils/testframework.sk +++ b/scripts/utils/testframework.sk @@ -211,7 +211,7 @@ effect: if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", expr-1 TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) - add "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} + add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect @@ -224,7 +224,7 @@ effect (3:|4:(no|without) (halt[ing]|fail[(-| )](safe|fast)|abort[ing])) fail te if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" failed", expr-1 TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) - add "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} + add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect From 6b256722de0f2287b9596a177351836f42bcb77b Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:01:33 +0300 Subject: [PATCH 07/12] Trying to understand why last parse logs don't work --- tests/working/utils/testframework.test.sk | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/working/utils/testframework.test.sk b/tests/working/utils/testframework.test.sk index 84dc0ec..b08c12e 100644 --- a/tests/working/utils/testframework.test.sk +++ b/tests/working/utils/testframework.test.sk @@ -94,6 +94,7 @@ devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 test-block is temporary B": devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 parse section": parse: no errors: abc # just an internal stuff to make sure test.sk loads without errors + broadcast "abcde: %last parse logs%" assert last parse logs contains "Can't understand this condition/effect: no errors: abc" devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 last test result A": From 90855497e45ba91bf97acc5630fd76599daa95ba Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:11:33 +0300 Subject: [PATCH 08/12] Fix test failure message formatting in testframework.sk --- scripts/utils/testframework.sk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/utils/testframework.sk b/scripts/utils/testframework.sk index d07c31d..a5e6d14 100644 --- a/scripts/utils/testframework.sk +++ b/scripts/utils/testframework.sk @@ -210,7 +210,7 @@ effect: then: if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", expr-1 - TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) + TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%", {_script}) add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect @@ -223,7 +223,7 @@ effect (3:|4:(no|without) (halt[ing]|fail[(-| )](safe|fast)|abort[ing])) fail te set {_script} to event.getEventValue("script") if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" failed", expr-1 - TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%expr-1%", current script) + TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", {_script}) add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect @@ -277,7 +277,7 @@ condition parse: {_logger}.close() {_parser}.reset() -plural expression last parse logs: +plural expression (last|latest) parse logs: usable in: custom event "skriptTest" get: From 65d65f7c9f08ce6e7eeb2f8207a8af5965e7a4ef Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:12:44 +0300 Subject: [PATCH 09/12] Try to understand once again. --- tests/working/utils/testframework.test.sk | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/working/utils/testframework.test.sk b/tests/working/utils/testframework.test.sk index b08c12e..703fd27 100644 --- a/tests/working/utils/testframework.test.sk +++ b/tests/working/utils/testframework.test.sk @@ -93,6 +93,7 @@ devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 test-block is temporary B": devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 parse section": parse: + abc no errors: abc # just an internal stuff to make sure test.sk loads without errors broadcast "abcde: %last parse logs%" assert last parse logs contains "Can't understand this condition/effect: no errors: abc" From dae5243d0bccad0a9fb2b31aaded1ba3f35999ee Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:18:14 +0300 Subject: [PATCH 10/12] Fix invalid % --- scripts/utils/testframework.sk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/utils/testframework.sk b/scripts/utils/testframework.sk index a5e6d14..c44b58b 100644 --- a/scripts/utils/testframework.sk +++ b/scripts/utils/testframework.sk @@ -210,7 +210,7 @@ effect: then: if parse tags does not contain "5": sendTestFailMessage "Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", expr-1 - TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed%", {_script}) + TestTracker.testFailed("Test ""%{_test}%"" with condition '%{_label}%: %{_raw}%' failed", {_script}) add "%expr-1%" to {-test.sk::errors::%{_script}%.%{_test}%::*} if parse tags contains "3": delay effect From c3e1bab44cc3aad373e80c47e99349354b15867b Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:20:22 +0300 Subject: [PATCH 11/12] Remove last parse logs test --- tests/working/utils/testframework.test.sk | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/working/utils/testframework.test.sk b/tests/working/utils/testframework.test.sk index 703fd27..6dd744a 100644 --- a/tests/working/utils/testframework.test.sk +++ b/tests/working/utils/testframework.test.sk @@ -1,7 +1,3 @@ -local effect no errors\: <.+>: - trigger: - stop - devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 assert true passes": assert true: {_none} is not set @@ -13,7 +9,6 @@ devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 framework internal consistenc without halting assert true: "%current script%" is set assert true: size of test errors is 0 - devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 assert true failure is recorded": without halting assert true with no error message: {_none} is set assert true: size of test errors is 1 @@ -90,13 +85,6 @@ devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 test-block is temporary A": devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 test-block is temporary B": assert true: {-test.sk::temptestblocka} is test-block's type assert true: {-test.sk::temptestblocka} is not {-test.sk::temptestblockb} - -devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 parse section": - parse: - abc - no errors: abc # just an internal stuff to make sure test.sk loads without errors - broadcast "abcde: %last parse logs%" - assert last parse logs contains "Can't understand this condition/effect: no errors: abc" devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 last test result A": fail test with no error message From 8e740b37134f5daa8fda60e3e4c2dde334c0f471 Mon Sep 17 00:00:00 2001 From: devdinc <234956748+devdinc@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:22:54 +0300 Subject: [PATCH 12/12] Add back the test case for last parse logs, but only in the workflow --- .github/workflows/test-skripts.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test-skripts.yml b/.github/workflows/test-skripts.yml index fefc307..ee8e326 100644 --- a/.github/workflows/test-skripts.yml +++ b/.github/workflows/test-skripts.yml @@ -78,6 +78,11 @@ jobs: set {_tests::*} to all tests autorun {_tests::*} + + devdinc test "f39f0f4a-31ee-4b71-87e9-38ddba3a2313 parse section": + parse: + abc + assert last parse logs contains "Can't understand this condition/effect: abc" EOF - name: Run tests