aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-ecosystem/.gitignore3
-rw-r--r--packages/bun-ecosystem/README.md7
-rwxr-xr-xpackages/bun-ecosystem/bun.lockbbin0 -> 8536 bytes
-rw-r--r--packages/bun-ecosystem/package.json14
-rw-r--r--packages/bun-ecosystem/src/packages.ts69
-rw-r--r--packages/bun-ecosystem/src/runner.ts92
-rw-r--r--packages/bun-ecosystem/tsconfig.json16
7 files changed, 201 insertions, 0 deletions
diff --git a/packages/bun-ecosystem/.gitignore b/packages/bun-ecosystem/.gitignore
new file mode 100644
index 000000000..2817d4e0b
--- /dev/null
+++ b/packages/bun-ecosystem/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+tmp
diff --git a/packages/bun-ecosystem/README.md b/packages/bun-ecosystem/README.md
new file mode 100644
index 000000000..2ed8df0c7
--- /dev/null
+++ b/packages/bun-ecosystem/README.md
@@ -0,0 +1,7 @@
+# bun-ecosystem
+
+A registry to test `npm` packages using Bun. This can be used as a tool to find bugs in Bun by running the test suites of these packages. In the future, we will run theses tests to catch regressions between releases.
+
+```sh
+bun run test
+```
diff --git a/packages/bun-ecosystem/bun.lockb b/packages/bun-ecosystem/bun.lockb
new file mode 100755
index 000000000..45d0385c1
--- /dev/null
+++ b/packages/bun-ecosystem/bun.lockb
Binary files differ
diff --git a/packages/bun-ecosystem/package.json b/packages/bun-ecosystem/package.json
new file mode 100644
index 000000000..1899684cd
--- /dev/null
+++ b/packages/bun-ecosystem/package.json
@@ -0,0 +1,14 @@
+{
+ "private": true,
+ "dependencies": {
+ "globby": "^13.1.3"
+ },
+ "devDependencies": {
+ "bun-types": "canary",
+ "prettier": "^2.8.2"
+ },
+ "scripts": {
+ "format": "prettier --write src",
+ "test": "bun run src/runner.ts"
+ }
+} \ No newline at end of file
diff --git a/packages/bun-ecosystem/src/packages.ts b/packages/bun-ecosystem/src/packages.ts
new file mode 100644
index 000000000..677bfdf16
--- /dev/null
+++ b/packages/bun-ecosystem/src/packages.ts
@@ -0,0 +1,69 @@
+export type Package = {
+ readonly name: string;
+ readonly repository: string;
+ readonly cwd?: string;
+ readonly tests?: {
+ readonly style: "jest" | "ava" | "tape" | "custom";
+ readonly include: string[];
+ readonly exclude?: string[];
+ readonly disabled?: boolean;
+ };
+};
+
+export const packages: Package[] = [
+ {
+ name: "lodash",
+ repository: github("lodash/lodash"),
+ tests: {
+ style: "jest",
+ include: ["test/*.js"],
+ exclude: [
+ "debounce.test.js", // hangs runner
+ "size.test.js", // require('vm').runInNewContext()
+ "merge.test.js", // failing
+ ],
+ },
+ },
+ {
+ name: "chalk",
+ repository: github("chalk/chalk"),
+ tests: {
+ style: "ava",
+ include: ["test/*.js"],
+ },
+ },
+ {
+ name: "request",
+ repository: github("request/request"),
+ tests: {
+ style: "tape",
+ include: ["tests/*.js"],
+ },
+ },
+ {
+ name: "commander",
+ repository: github("tj/commander.js"),
+ tests: {
+ style: "jest",
+ include: ["tests/*.js"],
+ },
+ },
+ {
+ name: "express",
+ repository: github("expressjs/express"),
+ tests: {
+ style: "jest",
+ include: ["test/**/*.js"],
+ exclude: [
+ "test/res.sendStatus.js", // https://github.com/oven-sh/bun/issues/887
+ "test/Route.js", // https://github.com/oven-sh/bun/issues/2030
+ ],
+ // Most tests fail due to lack of "http2"
+ disabled: true,
+ },
+ },
+];
+
+function github(repository: string): string {
+ return `git@github.com:${repository}.git`;
+}
diff --git a/packages/bun-ecosystem/src/runner.ts b/packages/bun-ecosystem/src/runner.ts
new file mode 100644
index 000000000..8b4e42aa7
--- /dev/null
+++ b/packages/bun-ecosystem/src/runner.ts
@@ -0,0 +1,92 @@
+import type { Package } from "./packages";
+import { packages } from "./packages";
+import { existsSync, copyFileSync } from "node:fs";
+import { dirname, join } from "node:path";
+import { globby } from "globby";
+
+for (const pkg of packages) {
+ try {
+ await loadPackage(pkg, "tmp");
+ } catch (error) {
+ console.error(pkg.name, error);
+ }
+}
+
+async function loadPackage(pkg: Package, cwd?: string): Promise<void> {
+ await gitClone({
+ cwd,
+ repository: pkg.repository,
+ name: pkg.name,
+ });
+ const dir = join(cwd ?? "", pkg.name, pkg.cwd ?? "");
+ await spawn({
+ cwd: dir,
+ cmd: ["bun", "install"],
+ });
+ if (!pkg.tests || pkg.tests.style !== "jest") {
+ return;
+ }
+ const files = await globby(pkg.tests.include, {
+ cwd: dir,
+ ignore: pkg.tests.exclude ?? [crypto.randomUUID()],
+ onlyFiles: true,
+ caseSensitiveMatch: false,
+ });
+ if (!files.length) {
+ throw new Error("No tests found");
+ }
+ for (const file of files) {
+ let path = file;
+ if (!file.includes(".test.")) {
+ const ext = path.lastIndexOf(".");
+ path = file.substring(0, ext) + ".test" + file.substring(ext);
+ copyFileSync(join(dir, file), join(dir, path));
+ }
+ await spawn({
+ cwd: dir,
+ cmd: ["bun", "wiptest", path],
+ });
+ }
+}
+
+type GitCloneOptions = {
+ repository: string;
+ cwd?: string;
+ name?: string;
+};
+
+async function gitClone(options: GitCloneOptions): Promise<void> {
+ const name = options.name ?? dirname(options.repository);
+ const cwd = options.cwd ?? process.cwd();
+ const path = join(cwd, name);
+ if (existsSync(path)) {
+ await spawn({
+ cwd: path,
+ cmd: ["git", "pull"],
+ });
+ } else {
+ const url = `${options.repository}`;
+ await spawn({
+ cwd,
+ cmd: ["git", "clone", "--single-branch", "--depth", "1", url, name],
+ });
+ }
+}
+
+type SpawnOptions = {
+ cwd: string;
+ cmd: string[];
+};
+
+async function spawn({ cwd, cmd }: SpawnOptions) {
+ const { exited } = await Bun.spawn({
+ cwd,
+ cmd,
+ stdout: "inherit",
+ stderr: "inherit",
+ });
+ const exitCode = await exited;
+ if (exitCode !== 0) {
+ throw new Error(`"${cmd.join(" ")}" exited with ${exitCode}`);
+ }
+}
diff --git a/packages/bun-ecosystem/tsconfig.json b/packages/bun-ecosystem/tsconfig.json
new file mode 100644
index 000000000..1b2f41220
--- /dev/null
+++ b/packages/bun-ecosystem/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "lib": ["ESNext"],
+ "module": "ESNext",
+ "target": "ESNext",
+ "moduleResolution": "node",
+ "types": ["bun-types"],
+ "esModuleInterop": true,
+ "allowJs": true,
+ "strict": true,
+ "resolveJsonModule": true
+ },
+ "include": [
+ "src"
+ ]
+}