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": {