aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/text-encoder.test.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/bun.js/text-encoder.test.js')
-rw-r--r--test/bun.js/text-encoder.test.js212
1 files changed, 212 insertions, 0 deletions
diff --git a/test/bun.js/text-encoder.test.js b/test/bun.js/text-encoder.test.js
new file mode 100644
index 000000000..5687e0222
--- /dev/null
+++ b/test/bun.js/text-encoder.test.js
@@ -0,0 +1,212 @@
+import { expect, it, describe } from "bun:test";
+import { gc as gcTrace } from "./gc";
+
+const getByteLength = (str) => {
+ // returns the byte length of an utf8 string
+ var s = str.length;
+ for (var i = str.length - 1; i >= 0; i--) {
+ var code = str.charCodeAt(i);
+ if (code > 0x7f && code <= 0x7ff) s++;
+ else if (code > 0x7ff && code <= 0xffff) s += 2;
+ if (code >= 0xdc00 && code <= 0xdfff) i--; //trail surrogate
+ }
+ return s;
+};
+
+describe("TextDecoder", () => {
+ it("should decode ascii text", () => {
+ const decoder = new TextDecoder("latin1");
+ gcTrace(true);
+ expect(decoder.encoding).toBe("windows-1252");
+ gcTrace(true);
+ expect(decoder.decode(new Uint8Array([0x41, 0x42, 0x43]))).toBe("ABC");
+ gcTrace(true);
+ const result = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33];
+ gcTrace(true);
+ expect(decoder.decode(Uint8Array.from(result))).toBe(
+ String.fromCharCode(...result)
+ );
+ gcTrace(true);
+ });
+
+ it("should decode unicode text", () => {
+ const decoder = new TextDecoder();
+ gcTrace(true);
+ var text = `❤️ Red Heart`;
+
+ const bytes = [
+ 226, 157, 164, 239, 184, 143, 32, 82, 101, 100, 32, 72, 101, 97, 114, 116,
+ ];
+ const decoded = decoder.decode(Uint8Array.from(bytes));
+ expect(decoder.encoding).toBe("utf-8");
+
+ gcTrace(true);
+
+ for (let i = 0; i < text.length; i++) {
+ expect(decoded.charCodeAt(i)).toBe(text.charCodeAt(i));
+ }
+ expect(decoded).toHaveLength(text.length);
+ gcTrace(true);
+ });
+
+ it("should decode unicode text with multiple consecutive emoji", () => {
+ const decoder = new TextDecoder();
+ const encoder = new TextEncoder();
+ gcTrace(true);
+ var text = `❤️❤️❤️❤️❤️❤️ Red Heart`;
+
+ text += ` ✨ Sparkles 🔥 Fire 😀 😃 😄 😁 😆 😅 😂 🤣 🥲 ☺️ 😊 😇 🙂 🙃 😉 😌 😍 🥰 😘 😗 😙 😚 😋 😛 😝 😜 🤪 🤨 🧐 🤓 😎 🥸 🤩 🥳 😏 😒 😞 😔 😟 😕 🙁 ☹️ 😣 😖 😫 😩 🥺 😢 😭 😤 😠 😡 🤬 🤯 😳 🥵 🥶 😱 😨 😰`;
+ gcTrace(true);
+ expect(decoder.decode(encoder.encode(text))).toBe(text);
+ gcTrace(true);
+ const bytes = new Uint8Array(getByteLength(text) * 8);
+ gcTrace(true);
+ const amount = encoder.encodeInto(text, bytes);
+ gcTrace(true);
+ expect(decoder.decode(bytes.subarray(0, amount.written))).toBe(text);
+ gcTrace(true);
+ });
+});
+
+describe("TextEncoder", () => {
+ it("should encode latin1 text", () => {
+ gcTrace(true);
+ const text = "Hello World!";
+ const encoder = new TextEncoder();
+ gcTrace(true);
+ const encoded = encoder.encode(text);
+ gcTrace(true);
+ expect(encoded instanceof Uint8Array).toBe(true);
+ expect(encoded.length).toBe(text.length);
+ gcTrace(true);
+ const result = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33];
+ for (let i = 0; i < result.length; i++) {
+ expect(encoded[i]).toBe(result[i]);
+ }
+ });
+
+ it("should encode long latin1 text", async () => {
+ const text = "Hello World!".repeat(1000);
+ const encoder = new TextEncoder();
+ gcTrace(true);
+ const encoded = encoder.encode(text);
+ gcTrace(true);
+ expect(encoded instanceof Uint8Array).toBe(true);
+ expect(encoded.length).toBe(text.length);
+ gcTrace(true);
+ const decoded = new TextDecoder().decode(encoded);
+ expect(decoded).toBe(text);
+ gcTrace();
+ await new Promise((resolve) => setTimeout(resolve, 1));
+ gcTrace();
+ expect(decoded).toBe(text);
+ });
+
+ it("should encode latin1 rope text", () => {
+ var text = "Hello";
+ text += " ";
+ text += "World!";
+
+ gcTrace(true);
+ const encoder = new TextEncoder();
+ const encoded = encoder.encode(text);
+ gcTrace(true);
+ const into = new Uint8Array(100);
+ const out = encoder.encodeInto(text, into);
+ gcTrace(true);
+ expect(out.read).toBe(text.length);
+ expect(out.written).toBe(encoded.length);
+
+ expect(encoded instanceof Uint8Array).toBe(true);
+ const result = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33];
+ for (let i = 0; i < result.length; i++) {
+ expect(encoded[i]).toBe(result[i]);
+ expect(encoded[i]).toBe(into[i]);
+ }
+ expect(encoded.length).toBe(getByteLength(text));
+ });
+
+ it("should encode utf-16 text", () => {
+ var text = `❤️ Red Heart
+ ✨ Sparkles
+ 🔥 Fire
+ `;
+ var encoder = new TextEncoder();
+ var decoder = new TextDecoder();
+ gcTrace(true);
+ expect(decoder.decode(encoder.encode(text))).toBe(text);
+ gcTrace(true);
+ });
+
+ // this test is from a web platform test in WebKit
+ describe("should use a unicode replacement character for invalid surrogate pairs", () => {
+ var bad = [
+ {
+ encoding: "utf-16le",
+ input: [0x00, 0xd8],
+ expected: "\uFFFD",
+ name: "lone surrogate lead",
+ },
+ {
+ encoding: "utf-16le",
+ input: [0x00, 0xdc],
+ expected: "\uFFFD",
+ name: "lone surrogate trail",
+ },
+ {
+ encoding: "utf-16le",
+ input: [0x00, 0xd8, 0x00, 0x00],
+ expected: "\uFFFD\u0000",
+ name: "unmatched surrogate lead",
+ },
+ {
+ encoding: "utf-16le",
+ input: [0x00, 0xdc, 0x00, 0x00],
+ expected: "\uFFFD\u0000",
+ name: "unmatched surrogate trail",
+ },
+ {
+ encoding: "utf-16le",
+ input: [0x00, 0xdc, 0x00, 0xd8],
+ expected: "\uFFFD\uFFFD",
+ name: "swapped surrogate pair",
+ },
+ ];
+
+ bad.forEach(function (t) {
+ it(t.encoding + " - " + t.name, () => {
+ gcTrace(true);
+ expect(
+ new TextDecoder(t.encoding).decode(new Uint8Array(t.input))
+ ).toBe(t.expected);
+ expect(
+ new TextDecoder(t.encoding).decode(
+ new Uint16Array(new Uint8Array(t.input).buffer)
+ )
+ ).toBe(t.expected);
+ gcTrace(true);
+ });
+ // test(function () {
+ // assert_throws_js(TypeError, function () {
+ // new TextDecoder(t.encoding, { fatal: true }).decode(
+ // new Uint8Array(t.input)
+ // );
+ // });
+ // }, t.encoding + " - " + t.name + " (fatal flag set)");
+ });
+ });
+
+ it("should encode utf-16 rope text", () => {
+ gcTrace(true);
+ var textReal = `❤️ Red Heart ✨ Sparkles 🔥 Fire`;
+
+ var a = textReal.split("");
+ var text = "";
+ for (let j of a) {
+ text += j;
+ }
+
+ var encoder = new TextEncoder();
+ expect(new TextDecoder().decode(encoder.encode(text))).toBe(textReal);
+ });
+});