{"id":19353203,"url":"https://github.com/jairussw/as-test","last_synced_at":"2026-04-02T14:49:14.253Z","repository":{"id":240856853,"uuid":"803598135","full_name":"JairusSW/as-test","owner":"JairusSW","description":"Runtime-agnostic testing framework for AssemblyScript. Supports mocking, snapshots, code coverage, multiple runtimes, and more.","archived":false,"fork":false,"pushed_at":"2026-03-27T15:36:45.000Z","size":1028,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-27T16:45:50.699Z","etag":null,"topics":["as-pect","aspect","assemblyscript","test","testing"],"latest_commit_sha":null,"homepage":"https://docs.jairus.dev/as-test","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JairusSW.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-21T03:13:18.000Z","updated_at":"2026-03-27T15:36:51.000Z","dependencies_parsed_at":"2026-02-24T07:12:31.833Z","dependency_job_id":null,"html_url":"https://github.com/JairusSW/as-test","commit_stats":null,"previous_names":["jairussw/as-test"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/JairusSW/as-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JairusSW%2Fas-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JairusSW%2Fas-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JairusSW%2Fas-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JairusSW%2Fas-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JairusSW","download_url":"https://codeload.github.com/JairusSW/as-test/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JairusSW%2Fas-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31308446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["as-pect","aspect","assemblyscript","test","testing"],"created_at":"2024-11-10T04:41:54.692Z","updated_at":"2026-04-02T14:49:14.247Z","avatar_url":"https://github.com/JairusSW.png","language":"JavaScript","funding_links":["https://github.com/sponsors/JairusSW"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\u003cpre\u003e╔═╗ ╔═╗    ╔═╗ ╔═╗ ╔═╗ ╔═╗\n╠═╣ ╚═╗ ══  ║  ╠═  ╚═╗  ║ \n╩ ╩ ╚═╝     ╩  ╚═╝ ╚═╝  ╩ \u003c/pre\u003e\u003c/h1\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eTable of Contents\u003c/summary\u003e\n\n- [Why as-test](#why-as-test)\n- [Installation](#installation)\n- [Docs](#docs)\n- [Project Layout](#project-layout)\n- [Writing Tests](#writing-tests)\n- [Mocking](#mocking)\n- [Snapshots](#snapshots)\n- [Fuzzing](#fuzzing)\n- [Runtimes](#runtimes)\n- [Examples](#examples)\n- [License](#license)\n\n\u003c/details\u003e\n\n## Why as-test\n\nMost AssemblyScript testing tools are tied to a single runtime, usually Node.js. This works for development, but it doesn’t reflect how your code runs in production.\nIf you deploy to WASI, Wazero, or a custom runtime, you often end up mocking everything and maintaining parallel logic just for tests.\nas-test solves this by letting you run tests on your actual target runtime, while only mocking what’s necessary.\n\nKey benefits\n\n- Runtime-agnostic: test on WASI, bindings, or custom runners\n- Minimal mocking: keep real imports when possible\n- Production-like testing: catch runtime-specific issues early\n- Inline mocking and snapshots\n- Custom reporters and coverage\n- Integrated fuzzing support\n\n## Installation\n\nThe easiest way to start is with the project initializer:\n\n```bash\nnpx as-test init\n```\n\nThat gives you a basic config file, a sample test, and optionally a sample fuzzer.\n\nIf you already have a project and just want the package:\n\n```bash\nnpm install --save-dev as-test\n```\n\n## Docs\n\nFull documentation lives at:\n\n\u003chttps://docs.jairus.dev/as-test\u003e\n\n## Project Layout\n\nBy default, `as-test` looks for:\n\n- tests in `assembly/__tests__`\n- fuzzers in `assembly/__fuzz__`\n- config in `as-test.config.json`\n\nGenerated files go into `.as-test/`.\n\nMinimal `as-test.config.json`:\n\n```json\n{\n  \"input\": [\"assembly/__tests__/*.spec.ts\"],\n  \"output\": \".as-test/\",\n  \"buildOptions\": {\n    \"target\": \"wasi\"\n  },\n  \"runOptions\": {\n    \"runtime\": {\n      \"cmd\": \"node .as-test/runners/default.wasi.js \u003cfile\u003e\"\n    }\n  }\n}\n```\n\nCoverage point filtering is configurable when you want to ignore known-noisy gaps:\n\n```json\n{\n  \"coverage\": {\n    \"enabled\": true,\n    \"include\": [\"assembly/src/**/*.ts\"],\n    \"ignore\": {\n      \"labels\": [\"Call\"],\n      \"names\": [\"panic\", \"serialize\"],\n      \"locations\": [\"assembly/src/fuzz.ts:38:*\"],\n      \"snippets\": [\"*message: string*\"]\n    }\n  }\n}\n```\n\n## Writing Tests\n\nTests usually live in `assembly/__tests__/*.spec.ts`.\n\nExample:\n\n```ts\nimport { describe, expect, test } from \"as-test\";\n\ndescribe(\"math\", () =\u003e {\n  test(\"adds numbers\", () =\u003e {\n    expect(1 + 2).toBe(3);\n  });\n});\n```\n\nRun everything:\n\n```bash\nnpx ast test\n```\n\nRun through the automatic worker pool:\n\n```bash\nnpx ast test --parallel\n```\n\nRun one matching file:\n\n```bash\nnpx ast test math\n```\n\nYou do not need to learn every CLI flag to get started. Most projects can begin with `npx ast test`, then add more configuration only when they need it.\n\n## Mocking\n\nMocking is supported, but the idea is to use it sparingly.\n\nWith `as-test`, the ideal path is to run your code against the real runtime and real imports when you can. When that is not practical, you can mock individual imports instead of rebuilding your whole environment around fake behavior.\n\nFor local functions, use `mockFn` and `unmockFn`. For host imports, use `mockImport` and `unmockImport`.\n\nThat is especially useful when:\n\n- an import talks to the outside world\n- a host function is hard to reproduce in a test\n- you want to force an edge case that is difficult to trigger naturally\n\nThis keeps tests focused. You can still verify the logic in your AssemblyScript code without needing every runtime dependency to be real in every test. It also pairs well with snapshots when you want to capture the output of a mocked import and make sure it stays stable over time.\n\nExample:\n\n```ts\nimport { describe, expect, mockFn, test, unmockFn } from \"as-test\";\n\nfunction getConfig(): string {\n  return \"name=prod\\nmode=live\";\n}\n\nmockFn(getConfig, (): string =\u003e \"name=demo\\nmode=test\");\n\ndescribe(\"config\", () =\u003e {\n  test(\"reads mocked data\", () =\u003e {\n    expect(getConfig()).toContain(\"demo\");\n  });\n});\n\nunmockFn(getConfig);\n```\n\nFor import mocking, the same idea applies, but it is usually easier to keep the imported function in a small wrapper module and mock that import path from the spec.\n\n## Snapshots\n\nSnapshots are useful when the output matters more than the exact step-by-step assertions.\n\nThey work well for:\n\n- generated strings or structured text\n- serialized values\n- the output of mocked imports\n- larger results that would be awkward to check field by field\n\nThat lets you keep tests readable while still locking down behavior that should not change unexpectedly.\n\nExample:\n\n```ts\nimport { describe, expect, test } from \"as-test\";\n\nfunction renderReport(): string {\n  return \"name=demo\\nmode=test\";\n}\n\ndescribe(\"report\", () =\u003e {\n  test(\"matches the saved output\", () =\u003e {\n    expect(renderReport()).toMatchSnapshot();\n  });\n});\n```\n\nThe first time you run a snapshot test, create the snapshot with:\n\n```bash\nnpx ast test --create-snapshots\n```\n\nAfter that, a normal `npx ast test` will verify it.\n\nIf an existing snapshot legitimately changed, overwrite it with:\n\n```bash\nnpx ast test --overwrite-snapshots\n```\n\n## Fuzzing\n\nFuzzers usually live in `assembly/__fuzz__/*.fuzz.ts`.\n\nExample:\n\n```ts\nimport { expect, FuzzSeed, fuzz } from \"as-test\";\n\nfuzz(\"bounded integer addition\", (left: i32, right: i32): bool =\u003e {\n  const sum = left + right;\n  expect(sum - right).toBe(left);\n  return sum \u003e= i32.MIN_VALUE;\n}).generate((seed: FuzzSeed, run: (left: i32, right: i32) =\u003e bool): void =\u003e {\n  run(seed.i32({ min: -1000, max: 1000 }), seed.i32({ min: -1000, max: 1000 }));\n});\n```\n\nPass a third argument to override the operation count for one target without changing the global fuzz config:\n\n```ts\nfuzz(\"hot path stays stable\", (): void =\u003e {\n  expect(1 + 1).toBe(2);\n}, 250);\n```\n\nYou can still override fuzz runs from the CLI when you want to force a different count for the current command:\n\n```bash\nnpx ast fuzz --runs 500\nnpx ast fuzz --runs 1.5x\nnpx ast fuzz --runs +10%\nnpx ast fuzz --runs +100000\n```\n\nIf you used `npx ast init` with a fuzzer example, the config is already there. Otherwise, add a `fuzz` block to `as-test.config.json` so `npx ast fuzz` knows what to build:\n\n```json\n{\n  \"fuzz\": {\n    \"input\": [\"./assembly/__fuzz__/*.fuzz.ts\"],\n    \"target\": \"bindings\"\n  }\n}\n```\n\n`ast fuzz` runs fuzz files across the selected modes, reports one result per file, and keeps the final summary separate from the normal test totals. If you want one combined command, use `ast test --fuzz`.\n\nWhen a fuzzer fails, `as-test` now prints the exact failing seeds and one-run repro commands such as `ast fuzz ... --seed \u003cseed+n\u003e --runs 1`. Crash records in `.as-test/crashes` also include the captured inputs passed to `run(...)`, which helps when the generator itself has side effects.\n\nRun only fuzzers:\n\n```bash\nnpx ast fuzz\n```\n\nRun tests and fuzzers together:\n\n```bash\nnpx ast test --fuzz\n```\n\nFuzzing is there when you want broader input coverage, but it does not get in the way of the normal test flow. You can start with ordinary specs and add fuzzers later.\n\n## Runtimes\n\nOne of the main reasons to use `as-test` is that you are not locked into a single runtime.\n\nIf your project runs under WASI, bindings, or a custom runner, you can point your tests at that environment instead of treating Node.js as the only way to execute them.\n\nFor example, a simple WASI setup in `as-test.config.json` can look like this:\n\n```json\n{\n  \"input\": [\"./assembly/__tests__/*.spec.ts\"],\n  \"buildOptions\": {\n    \"target\": \"wasi\"\n  },\n  \"runOptions\": {\n    \"runtime\": {\n      \"cmd\": \"node ./.as-test/runners/default.wasi.js \u003cfile\u003e\"\n    }\n  }\n}\n```\n\nThen run your tests normally:\n\n```bash\nnpx ast test\n```\n\nIf you want to keep more than one runtime around, use modes:\n\n```json\n{\n  \"input\": [\"./assembly/__tests__/*.spec.ts\"],\n  \"modes\": {\n    \"wasi\": {\n      \"buildOptions\": {\n        \"target\": \"wasi\"\n      },\n      \"runOptions\": {\n        \"runtime\": {\n          \"cmd\": \"node ./.as-test/runners/default.wasi.js \u003cfile\u003e\"\n        }\n      }\n    },\n    \"bindings\": {\n      \"buildOptions\": {\n        \"target\": \"bindings\"\n      },\n      \"runOptions\": {\n        \"runtime\": {\n          \"cmd\": \"node ./.as-test/runners/default.bindings.js \u003cfile\u003e\"\n        }\n      }\n    }\n  }\n}\n```\n\nRun a specific mode with:\n\n```bash\nnpx ast test --mode wasi\n```\n\nor\n\n```bash\nnpx ast test --mode wasi,bindings\n```\n\nThis is the general idea throughout the project: write tests once, then choose the runtime that matches how your code actually runs.\n\n## Examples\n\nRunnable example projects live in [examples/](./examples/README.md). They are useful if you want to see complete setups instead of isolated snippets.\n\n## License\n\nThis project is distributed under an open source license. Work on this project is done by passion, but if you want to support it financially, you can do so by making a donation to the project's [GitHub Sponsors](https://github.com/sponsors/JairusSW) page.\n\nYou can view the full license using the following link: [License](./LICENSE)\n\n## Contact\n\nPlease send all issues to [GitHub Issues](https://github.com/JairusSW/json-as/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)\n\n- **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)\n- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/json-as)\n- **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)\n- **Discord:** Contact me at [My Discord](https://discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjairussw%2Fas-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjairussw%2Fas-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjairussw%2Fas-test/lists"}