From 1fdd1c8f57a1a70420553ea8095c7a81e7464804 Mon Sep 17 00:00:00 2001
From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com>
Date: Mon, 22 Apr 2024 05:37:50 +0200
Subject: [PATCH 1/2] test: add compatibility tests for browser, node and bun
---
.github/workflows/ci.yml | 6 ++
.gitignore | 3 +-
deno.jsonc | 10 ++--
deno.lock | 65 ++++++++++++++++++++-
utils/tests/compatibility/_compatibility.ts | 48 +++++++++++++++
utils/tests/compatibility/_example.mjs | 44 ++++++++++++++
utils/tests/compatibility/browser_test.ts | 31 ++++++++++
utils/tests/compatibility/bun_test.ts | 2 +
utils/tests/compatibility/node_test.ts | 2 +
9 files changed, 205 insertions(+), 6 deletions(-)
create mode 100644 utils/tests/compatibility/_compatibility.ts
create mode 100644 utils/tests/compatibility/_example.mjs
create mode 100644 utils/tests/compatibility/browser_test.ts
create mode 100644 utils/tests/compatibility/bun_test.ts
create mode 100644 utils/tests/compatibility/node_test.ts
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a7c6abae..f45cc5b4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,6 +15,12 @@ jobs:
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x
+ - uses: oven-sh/setup-bun@v1
+ with:
+ bun-version: 1.x
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 20.x
- run: deno task ci
analyze:
diff --git a/.gitignore b/.gitignore
index 26ce540e..fd549bf1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
coverage
-utils/tests/assets/x-*.xml
\ No newline at end of file
+utils/tests/assets/x-*.xml
+utils/tests/compatibility/_example.node.mjs
\ No newline at end of file
diff --git a/deno.jsonc b/deno.jsonc
index 79cea9cf..f09a424e 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -13,16 +13,18 @@
},
"tasks": {
"ci": "deno fmt --check && deno task test && deno task bench",
- "test": "deno fmt && deno test --coverage --doc && deno coverage && deno lint",
- "bench": "deno bench --allow-read --allow-write=utils/tests/assets"
+ "test": "deno fmt && deno test --coverage --doc --allow-read --allow-env --allow-run=node,bun --allow-write=utils/tests && deno coverage && deno lint",
+ "bench": "deno bench --allow-read --allow-write=utils/tests"
},
"lint": {
"rules": {
"exclude": ["no-extra-semi"]
- }
+ },
+ "exclude": ["utils/tests/compatibility/_example.node.mjs"]
},
"fmt": {
"lineWidth": 120,
- "semiColons": false
+ "semiColons": false,
+ "exclude": ["utils/tests/compatibility/_example.node.mjs"]
}
}
diff --git a/deno.lock b/deno.lock
index 8f726b01..b13d9c81 100644
--- a/deno.lock
+++ b/deno.lock
@@ -1,6 +1,38 @@
{
"version": "3",
"remote": {
+ "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
+ "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
+ "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d",
+ "https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9",
+ "https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf",
+ "https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37",
+ "https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
+ "https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
+ "https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b",
+ "https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
+ "https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
+ "https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
+ "https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
+ "https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
+ "https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
+ "https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
+ "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
+ "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
+ "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21",
+ "https://deno.land/std@0.186.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
+ "https://deno.land/std@0.186.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
+ "https://deno.land/std@0.186.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
+ "https://deno.land/std@0.186.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
+ "https://deno.land/std@0.186.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
+ "https://deno.land/std@0.186.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
+ "https://deno.land/std@0.186.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
+ "https://deno.land/std@0.186.0/path/mod.ts": "ee161baec5ded6510ee1d1fb6a75a0f5e4b41f3f3301c92c716ecbdf7dae910d",
+ "https://deno.land/std@0.186.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
+ "https://deno.land/std@0.186.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
+ "https://deno.land/std@0.186.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
+ "https://deno.land/std@0.222.1/encoding/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376",
+ "https://deno.land/std@0.222.1/encoding/base64.ts": "dd59695391584c8ffc5a296ba82bcdba6dd8a84d41a6a539fbee8e5075286eaf",
"https://deno.land/std@0.223.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975",
"https://deno.land/std@0.223.0/assert/_diff.ts": "4bf42969aa8b1a33aaf23eb8e478b011bfaa31b82d85d2ff4b5c4662d8780d2b",
"https://deno.land/std@0.223.0/assert/_format.ts": "0ba808961bf678437fb486b56405b6fefad2cf87b5809667c781ddee8c32aff4",
@@ -16,6 +48,8 @@
"https://deno.land/std@0.223.0/assert/assert_strict_equals.ts": "dbcdcb5b8b74e6c06bce6a9fa43ff4d1089793e7832baff251e514954b9b266b",
"https://deno.land/std@0.223.0/assert/assertion_error.ts": "ba8752bd27ebc51f723702fac2f54d3e94447598f54264a6653d6413738a8917",
"https://deno.land/std@0.223.0/assert/equal.ts": "bddf07bb5fc718e10bb72d5dc2c36c1ce5a8bdd3b647069b6319e07af181ac47",
+ "https://deno.land/std@0.223.0/encoding/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376",
+ "https://deno.land/std@0.223.0/encoding/base64.ts": "dd59695391584c8ffc5a296ba82bcdba6dd8a84d41a6a539fbee8e5075286eaf",
"https://deno.land/std@0.223.0/expect/_assert_equals.ts": "08a5ba74c1c7ca51c4c2c33158509746c560777ad3cb8996a55d85a8d57c351c",
"https://deno.land/std@0.223.0/expect/_assert_not_equals.ts": "f8c56aafbc12b2d49bb5e1478f02a3ae8a6fd884eff18ccbc899a94829eb1510",
"https://deno.land/std@0.223.0/expect/_asymmetric_matchers.ts": "bf2385fc9a943f0600f7870c8dfcbfd0ab5d633fe3c45b84339016e0d8069ac4",
@@ -34,6 +68,35 @@
"https://deno.land/std@0.223.0/expect/_utils.ts": "fc45069227d1c5a04f642b9224f060017eb02923159a4848d79a7a3fcef53c55",
"https://deno.land/std@0.223.0/expect/expect.ts": "474fa2c581c861be43bf4fcf58875d7d28b879bea1d2c671b833b2147ced24ab",
"https://deno.land/std@0.223.0/expect/fn.ts": "2508684de0a3147698b3b162f6fc99f7f9fe424ba3136fc4016f654aaff243cd",
- "https://deno.land/std@0.223.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a"
+ "https://deno.land/std@0.223.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a",
+ "https://deno.land/std@0.223.0/path/_common/from_file_url.ts": "d672bdeebc11bf80e99bf266f886c70963107bdd31134c4e249eef51133ceccf",
+ "https://deno.land/std@0.223.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15",
+ "https://deno.land/std@0.223.0/path/from_file_url.ts": "911833ae4fd10a1c84f6271f36151ab785955849117dc48c6e43b929504ee069",
+ "https://deno.land/std@0.223.0/path/posix/from_file_url.ts": "951aee3a2c46fd0ed488899d024c6352b59154c70552e90885ed0c2ab699bc40",
+ "https://deno.land/std@0.223.0/path/windows/from_file_url.ts": "ced2d587b6dff18f963f269d745c4a599cf82b0c4007356bd957cb4cb52efc01",
+ "https://deno.land/x/deno_cache@0.7.1/auth_tokens.ts": "3cfe2c5e5f07e1f77020be94de1e1196915ccd77c3dfff8480fa8e4a1d1be7e2",
+ "https://deno.land/x/deno_cache@0.7.1/cache.ts": "5632468ad366153fd33eeb15253935fde8a9c95cdbda9cd9841f8f345f55861d",
+ "https://deno.land/x/deno_cache@0.7.1/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0",
+ "https://deno.land/x/deno_cache@0.7.1/deps.ts": "5c819e018228823ebb2ce27733ad3df7f5f0c9e718e81eac4990e3bb03fe5d0d",
+ "https://deno.land/x/deno_cache@0.7.1/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069",
+ "https://deno.land/x/deno_cache@0.7.1/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa",
+ "https://deno.land/x/deno_cache@0.7.1/file_fetcher.ts": "12bba1fd7b187905d10b1e716a7d6f2e39f0afd3223ea59cd029968324132061",
+ "https://deno.land/x/deno_cache@0.7.1/http_cache.ts": "1d7258f2df2aa6bf3f6add033e619efb1dfdbd75f6d2ee3ab40648314357593b",
+ "https://deno.land/x/deno_cache@0.7.1/lib/deno_cache_dir.generated.js": "c1df1611540d9ae4dbbf9c697ce2a5172839f1e08989ad2fa060231cb10a1484",
+ "https://deno.land/x/deno_cache@0.7.1/lib/snippets/deno_cache_dir-23cc6fb6bb1bdfa8/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6",
+ "https://deno.land/x/deno_cache@0.7.1/mod.ts": "a27b683abe029c7f99d852da9811db8ae4bc3064f00d9761611a10580a48fb10",
+ "https://deno.land/x/deno_cache@0.7.1/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2",
+ "https://deno.land/x/deno_graph@0.66.0/deno_graph_wasm.generated.js": "5d3d75f178f23eb927223bd7f493e75e68ff2ecfdf635e3be77d1862033c52e9",
+ "https://deno.land/x/deno_graph@0.66.0/loader.ts": "512a406cb4c449b45110f2b878cd09929a883a4af193060232d2d9fc76a9d4dd",
+ "https://deno.land/x/deno_graph@0.66.0/media_type.ts": "7c1c5c6654e3cf84b8daa53c0d1ffc1b7864849406f559b961eccff859b0a417",
+ "https://deno.land/x/deno_graph@0.66.0/mod.ts": "be92f206bb38138ffc1c81a0b607dc22bb3a1dd9159b05331b2b37200ba25039",
+ "https://deno.land/x/deno_graph@0.66.0/types.ts": "bde84cb2919068c07e6cf4d8bf3054e8da908f2f221623d5302380df29b96320",
+ "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66",
+ "https://deno.land/x/emit@0.39.0/_utils.ts": "98412edc7aa29e77d592b54fbad00bdec1b05d0c25eb772a5f8edc9813e08d88",
+ "https://deno.land/x/emit@0.39.0/emit.generated.js": "dacc24735985c3576cf7d1cdd9bae4b9f5c19149e195ca752200181b74e031cf",
+ "https://deno.land/x/emit@0.39.0/mod.ts": "2fa64c4d220c13b9d752933803056ce7694722367c3e9cb1ee86fe9f81c587f3",
+ "https://deno.land/x/libs@0.4.0/bundle.ts": "8c31d5db3253671f1229c88b2026aae227af41c1d8790b52bf8513fef8f1459d",
+ "https://deno.land/x/wasmbuild@0.15.1/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed",
+ "https://deno.land/x/wasmbuild@0.15.1/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63"
}
}
diff --git a/utils/tests/compatibility/_compatibility.ts b/utils/tests/compatibility/_compatibility.ts
new file mode 100644
index 00000000..a50336f4
--- /dev/null
+++ b/utils/tests/compatibility/_compatibility.ts
@@ -0,0 +1,48 @@
+import { expect } from "https://deno.land/std@0.223.0/expect/expect.ts"
+import { fromFileUrl } from "https://deno.land/std@0.223.0/path/from_file_url.ts"
+import { bundle } from "https://deno.land/x/libs@0.4.0/bundle.ts"
+
+const example = {
+ url: new URL("./_example.mjs", import.meta.url),
+ path: {
+ bun: fromFileUrl(new URL("./_example.mjs", import.meta.url)),
+ node: fromFileUrl(new URL("./_example.node.mjs", import.meta.url)),
+ },
+}
+
+export async function test(runtime: "node" | "bun") {
+ try {
+ const binary = new Deno.Command(runtime)
+ await binary.output()
+ let args = []
+ switch (runtime) {
+ case "node":
+ // We also need to transpile to javascript for node
+ await Deno.writeTextFile(example.path.node, await bundle(example.url))
+ args = [example.path.node]
+ break
+ case "bun":
+ args = ["run", example.path.bun]
+ break
+ default:
+ throw new Error(`Unknown runtime: ${runtime}`)
+ }
+ Deno.test(`compatibility: ${runtime}`, async () => {
+ const command = new Deno.Command(runtime, { args, stdout: "piped", stderr: "piped" })
+ const { code, stdout, stderr, success } = await command.output()
+ if (!success) {
+ console.log(`Command: ${runtime} ${args.join(" ")}`)
+ console.error(`Exit code: ${code}`)
+ console.log(new TextDecoder().decode(stdout))
+ console.error(new TextDecoder().decode(stderr))
+ }
+ expect(code).toBe(0)
+ expect(success).toBe(true)
+ })
+ } catch (error) {
+ if ((!(error instanceof Deno.errors.NotFound)) && (!(error instanceof Deno.errors.PermissionDenied))) {
+ throw error
+ }
+ Deno.test.ignore(`compatibility: ${runtime} (${error})`, () => {})
+ }
+}
diff --git a/utils/tests/compatibility/_example.mjs b/utils/tests/compatibility/_example.mjs
new file mode 100644
index 00000000..eed34d51
--- /dev/null
+++ b/utils/tests/compatibility/_example.mjs
@@ -0,0 +1,44 @@
+/**
+ * This script is used to test the compatibility of the library with other runtime environments.
+ *
+ * Rather than running all the unit tests, it simply checks if the library is able to parse and
+ * stringify the content of some XML files. If it can, then we assume that the remaining unit
+ * tests would succeed as well since there aren't any dependencies or runtime-specific code.
+ */
+import { parse, stringify } from "../../../mod.ts"
+
+for (const file of ["small.xml", "medium.xml"]) {
+ let content = ""
+ for (const _ of ["fetch", "retry"]) {
+ try {
+ content = await fetch(new URL(`../assets/${file}`, import.meta.url)).then((response) => response.text())
+ break
+ } // NODEJS: fetch does not support the file protocol, polyfill it with fs on the fly
+ catch (error) {
+ if ((!(error instanceof TypeError)) || (_ === "retry")) {
+ throw error
+ }
+ const fs = await import("node:fs/promises")
+ // deno-lint-ignore no-global-assign
+ fetch = async (url) => {
+ // Fix the local path on windows
+ url.pathname = url.pathname.replace(/^\/[A-Z]:\//, "/")
+ return new Response(await fs.readFile(url.pathname))
+ }
+ }
+ }
+ content = content.replaceAll("\r\n", "\n").trim()
+ try {
+ if (!content) {
+ throw new Error("Content is empty")
+ }
+ if (stringify(parse(content)) !== content) {
+ throw new Error("The parsed content is not equal to the original content")
+ }
+ } catch (error) {
+ console.error(`${file}: ko`)
+ console.error(error)
+ throw error
+ }
+ console.log(`${file}: ok`)
+}
diff --git a/utils/tests/compatibility/browser_test.ts b/utils/tests/compatibility/browser_test.ts
new file mode 100644
index 00000000..00fafca6
--- /dev/null
+++ b/utils/tests/compatibility/browser_test.ts
@@ -0,0 +1,31 @@
+import { expect } from "https://deno.land/std@0.223.0/expect/expect.ts"
+import { encodeBase64 } from "https://deno.land/std@0.223.0/encoding/base64.ts"
+
+Deno.test("compatibility: browser", async () => {
+ // Simulate browser environment by removing Deno namespace insided worker
+ const mod = new URL("../../../mod.ts", import.meta.url)
+ const worker = new Worker(
+ new URL(`data:application/typescript;base64,${
+ encodeBase64(`
+ delete globalThis.Deno;
+ import { parse, stringify } from "${mod.href}";
+ onmessage = () => {
+ try {
+ parse("")
+ stringify({ root: null })
+ postMessage(true)
+ }
+ catch {
+ postMessage(false)
+ }
+ }
+ `)
+ }`),
+ { type: "module" },
+ )
+ const promise = new Promise((resolve, reject) => {
+ worker.onmessage = ({ data }) => data ? resolve() : reject()
+ })
+ worker.postMessage(null)
+ await expect(promise).not.resolves.toThrow()
+})
diff --git a/utils/tests/compatibility/bun_test.ts b/utils/tests/compatibility/bun_test.ts
new file mode 100644
index 00000000..c533d528
--- /dev/null
+++ b/utils/tests/compatibility/bun_test.ts
@@ -0,0 +1,2 @@
+import { test } from "./_compatibility.ts"
+await test("bun")
diff --git a/utils/tests/compatibility/node_test.ts b/utils/tests/compatibility/node_test.ts
new file mode 100644
index 00000000..4d2721c2
--- /dev/null
+++ b/utils/tests/compatibility/node_test.ts
@@ -0,0 +1,2 @@
+import { test } from "./_compatibility.ts"
+await test("node")
From 74856753342559b00b476e1935da7ffc57cb3875 Mon Sep 17 00:00:00 2001
From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com>
Date: Mon, 22 Apr 2024 05:42:28 +0200
Subject: [PATCH 2/2] Update deno.jsonc
---
deno.jsonc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/deno.jsonc b/deno.jsonc
index f09a424e..a261f4c9 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -13,7 +13,7 @@
},
"tasks": {
"ci": "deno fmt --check && deno task test && deno task bench",
- "test": "deno fmt && deno test --coverage --doc --allow-read --allow-env --allow-run=node,bun --allow-write=utils/tests && deno coverage && deno lint",
+ "test": "deno fmt && deno test --coverage --doc --allow-read --allow-env --allow-run=node,bun --allow-write=utils/tests --allow-net=deno.land && deno coverage && deno lint",
"bench": "deno bench --allow-read --allow-write=utils/tests"
},
"lint": {