From cc22aa342dde541e5c9608ebf6dd51ebba17333f Mon Sep 17 00:00:00 2001 From: Frotty Date: Sun, 16 Aug 2026 14:15:40 +0200 Subject: [PATCH] Bump the pinned standard library, and check its string handling Moves the pin from 16729fa to 98b1140. The library turns multibyte support on by default as of this range, and works the engine's behaviour out at runtime rather than being told: it cuts a character in half to see how a partial slice is represented, and slices a literal byte by byte to enumerate every continuation byte. That rests on a string being a sequence of bytes, which the interpreter now agrees with. Nothing runs the library's own tests, so a bump was otherwise only checked for still compiling. StdLibStringTests covers the part this one turns on: a multibyte length in bytes, a position inside a character reported as not a boundary, and ascii unaffected. The middle one is the detection working end to end, since it only answers that way if slicing produced the partial bytes the library expects to find. --- .../java/tests/wurstscript/tests/StdLib.java | 2 +- .../wurstscript/tests/StdLibStringTests.java | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLibStringTests.java diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLib.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLib.java index c418fe53a..3f224fd21 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLib.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLib.java @@ -24,7 +24,7 @@ public class StdLib { /** * version to use for the tests */ - private final static String version = "16729fa07197bdc331dc5e30eb0f91d444eece85"; + private final static String version = "98b1140803dcb99a4a48cf8f14fc099961ad55f7"; /** * flag so that initialization in only done once diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLibStringTests.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLibStringTests.java new file mode 100644 index 000000000..d4bea0f7c --- /dev/null +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLibStringTests.java @@ -0,0 +1,60 @@ +package tests.wurstscript.tests; + +import org.testng.annotations.Test; + +/** + * The standard library's own string handling, run against the interpreter. + *

+ * {@code String.wurst} enables multibyte support by default and works it out at runtime rather than + * being told: it slices a character in half to see how the engine represents a partial slice, and + * slices a literal byte by byte to enumerate every continuation byte. All of that rests on a string + * being a sequence of bytes, so these check the library reaches the answers it is meant to reach + * rather than quietly falling back to its ascii-only path. + *

+ * Nothing else runs the library's own tests, so a bump of the pinned version is otherwise only + * checked for still compiling. + */ +public class StdLibStringTests extends WurstScriptTest { + + /** Two bytes for the character, and the library counts what the game counts. */ + @Test + public void lengthOfAMultibyteStringIsInBytes() { + test().withStdLib().executeProg().lines( + "package test", + "import String", + "init", + " if \"ä\".length() == 2 and \"aä\".length() == 3", + " testSuccess()" + ); + } + + /** + * The position between the two bytes of a character is not a boundary, and both ends are. This is + * the library's detection working end to end: it only answers this way if slicing produced the + * partial bytes it expected to find. + */ + @Test + public void aPositionInsideACharacterIsNotABoundary() { + test().withStdLib().executeProg().lines( + "package test", + "import String", + "init", + " let s = \"ä\"", + " if s.isCharBoundary(0) and s.isCharBoundary(2) and not s.isCharBoundary(1)", + " testSuccess()" + ); + } + + /** Ascii is unaffected: every position in it starts a character. */ + @Test + public void everyPositionInAnAsciiStringIsABoundary() { + test().withStdLib().executeProg().lines( + "package test", + "import String", + "init", + " let s = \"abc\"", + " if s.isCharBoundary(0) and s.isCharBoundary(1) and s.isCharBoundary(2)", + " testSuccess()" + ); + } +}