Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,38 @@ $ rake build:download_prebuilt
# Build Ruby (if you need to build Ruby by yourself)
$ rake build:head-wasm32-unknown-wasip1-full

# Build npm package
# Build and test the WASI Preview 1 npm package
$ rake npm:ruby-head-wasm-wasi:build
$ rake npm:ruby-head-wasm-wasi:check

# Build and test the WASI Preview 2 npm package
$ rake npm:ruby-head-wasm-wasip2:build
# Test npm package
$ rake npm:ruby-head-wasm-wasip2:check
```

If you need to re-build Ruby, please clean `./rubies` directory, and run `rake npm:ruby-head-wasm-wasi` again.

### npm package test structure

The `ruby-wasm-wasi` package contains the shared JavaScript bindings and test suites, but it does not contain a Ruby WebAssembly binary. Version-specific packages provide the binary and invoke the shared tests with `RUBY_NPM_PACKAGE_ROOT`:

```text
ruby-head-wasm-wasi
└─ test
├─ ruby-wasm-wasi:test:run
└─ ruby-wasm-wasi:test:node-examples

ruby-4.0-wasm-wasi, ruby-3.x-wasm-wasi
└─ test
└─ ruby-wasm-wasi:test:run

ruby-head-wasm-wasip2
└─ test
└─ ruby-wasm-wasi:test:run
```

The shared `test:run` script runs the unit, Vitest, and browser E2E suites. The `test:node-examples` script is invoked separately and only by `ruby-head-wasm-wasi` because the Node.js examples use `@ruby/head-wasm-wasi`.

## Building CRuby from source

If you want to build CRuby for WebAssembly from source yourself, follow the below instructions.
Expand Down
2 changes: 1 addition & 1 deletion packages/npm-packages/ruby-head-wasm-wasi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"README.md"
],
"scripts": {
"test": "RUBY_NPM_PACKAGE_ROOT=../ruby-head-wasm-wasi npm -C ../ruby-wasm-wasi run test:run",
"test": "RUBY_NPM_PACKAGE_ROOT=../ruby-head-wasm-wasi npm -C ../ruby-wasm-wasi run test:run && RUBY_NPM_PACKAGE_ROOT=../ruby-head-wasm-wasi npm -C ../ruby-wasm-wasi run test:node-examples",
"build:deps": "cd ../ruby-wasm-wasi && npm run build",
"build:static:files": "../ruby-wasm-wasi/tools/pack-static-files.sh ./dist",
"build:static:compat": "../ruby-wasm-wasi/tools/pack-compat-shim.mjs --dist=./dist --pkg=ruby-head-wasm-wasi",
Expand Down
1 change: 1 addition & 0 deletions packages/npm-packages/ruby-wasm-wasi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"test:run": "npm run test:unit && npm run test:vitest -- --run && npm run test:e2e",
"test:vitest": "vitest ./test/",
"test:unit": "./tools/run-test-unit.mjs",
"test:node-examples": "vitest ./test-node-examples/ --run",
"test:e2e": "playwright install && npm run test:e2e:examples && npm run test:e2e:integrations",
"test:e2e:examples": "playwright test -c test-e2e/playwright.examples.config.ts",
"test:e2e:integrations": "playwright test -c test-e2e/playwright.integrations.config.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { afterEach, beforeEach, describe, expect, test } from "vitest";
import { setupNodeExampleTest } from "./support.js";

describe("Node.js examples", () => {
let context;

beforeEach(async () => {
context = await setupNodeExampleTest();
});

afterEach(async () => {
await context?.cleanup();
});

test("index.node.js is healthy", async () => {
const { stdout } = await context.run("index.node.js");

expect(stdout).toMatch(/ruby .* \[wasm32-wasi\]/);
expect(stdout).toContain("NoMethodError");
expect(stdout).toContain("RuntimeError");
}, 70_000);
});
41 changes: 41 additions & 0 deletions packages/npm-packages/ruby-wasm-wasi/test-node-examples/support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { execFile } from "child_process";
import fs from "fs/promises";
import os from "os";
import path from "path";
import { promisify } from "util";
import { fileURLToPath } from "url";

const execFileAsync = promisify(execFile);
const exampleDir = fileURLToPath(new URL("../example/", import.meta.url));

export const setupNodeExampleTest = async () => {
if (!process.env.RUBY_NPM_PACKAGE_ROOT) {
throw new Error("RUBY_NPM_PACKAGE_ROOT must be set");
}

const rubyPackageRoot = path.resolve(process.env.RUBY_NPM_PACKAGE_ROOT);
const temporaryDir = await fs.mkdtemp(
path.join(os.tmpdir(), "ruby-wasm-node-example-"),
);
const packageLink = path.join(
temporaryDir,
"node_modules/@ruby/head-wasm-wasi",
);

try {
await fs.mkdir(path.dirname(packageLink), { recursive: true });
await fs.symlink(rubyPackageRoot, packageLink, "dir");
} catch (error) {
await fs.rm(temporaryDir, { recursive: true, force: true });
throw error;
}

return {
run: (exampleFile) =>
execFileAsync(process.execPath, [path.join(exampleDir, exampleFile)], {
cwd: temporaryDir,
timeout: 60_000,
}),
cleanup: () => fs.rm(temporaryDir, { recursive: true, force: true }),
};
};
Loading