{"id":16125738,"url":"https://github.com/dy/tst","last_synced_at":"2026-01-16T17:46:39.297Z","repository":{"id":47753410,"uuid":"49088846","full_name":"dy/tst","owner":"dy","description":"Tests without efforts","archived":false,"fork":false,"pushed_at":"2025-04-06T19:14:15.000Z","size":310,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-30T11:52:24.481Z","etag":null,"topics":["mocha","tap","test"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dy.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2016-01-05T19:48:25.000Z","updated_at":"2025-04-06T19:14:19.000Z","dependencies_parsed_at":"2025-05-30T10:09:24.921Z","dependency_job_id":"164193bf-161b-4c15-8f9c-e0d7b626cd91","html_url":"https://github.com/dy/tst","commit_stats":{"total_commits":174,"total_committers":3,"mean_commits":58.0,"dds":"0.12068965517241381","last_synced_commit":"fc7c15ceaa267cba485c73eed0742ee164ea1fba"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/dy/tst","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dy%2Ftst","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dy%2Ftst/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dy%2Ftst/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dy%2Ftst/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dy","download_url":"https://codeload.github.com/dy/tst/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dy%2Ftst/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263785001,"owners_count":23511013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["mocha","tap","test"],"created_at":"2024-10-09T21:31:22.532Z","updated_at":"2026-01-16T17:46:39.288Z","avatar_url":"https://github.com/dy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tst [![test](https://github.com/dy/tst/actions/workflows/test.yml/badge.svg)](https://github.com/dy/tst/actions/workflows/test.yml) [![npm](https://img.shields.io/npm/v/tst?color=red)](https://npmjs.org/package/tst) [![demo](https://img.shields.io/badge/demo-%F0%9F%9A%80-midnightblue)](https://dy.github.io/tst/) [![ॐ](https://img.shields.io/badge/MIT-%E0%A5%90-white)](https://krishnized.github.io/license)\n\nTest without \u003cem\u003ee\u003c/em\u003efforts.\n\n* vanilla ESM — no build, no tooling\n* node + browser\n* standalone assertions\n* async, timeouts, TAP\n* 0 deps, ~400 LOC\n\n## usage\n\n```js\nimport test from 'tst.js'\n\ntest('math', ({ ok, is }) =\u003e {\n  ok(true)\n  is(1 + 1, 2)\n  is({a: 1}, {a: 1})  // deep equality\n})\n\ntest('async', async ({ ok }) =\u003e {\n  await fetch('/api')\n  ok(true)\n})\n```\n\n\n## assertions\n\n| Function | Description |\n|----------|-------------|\n| `ok(a, msg?)` | Assert truthy |\n| `is(a, b, msg?)` | Assert equal (`Object.is` for primitives, deep equal for objects) |\n| `not(a, b, msg?)` | Assert not equal |\n| `any(a, [x,y,z], msg?)` | Assert value is one of options |\n| `same(a, b, msg?)` | Assert same members (order-independent) |\n| `throws(fn, match?, msg?)` | Assert fn throws (optionally matching regex/class) |\n| `rejects(fn, match?, msg?)` | Assert async fn rejects (optionally matching regex/class) |\n| `almost(a, b, eps?, msg?)` | Assert approximate equality |\n| `pass(msg)` / `fail(msg)` | Explicit pass/fail |\n\n\u003e [!NOTE]\n\u003e Standalone use: `import { ok, is, not, any, same, throws, rejects, almost, pass, fail } from 'tst/assert.js'`\n\n\n## modifiers\n\n```js\ntest.skip('ignored', t =\u003e {})      // skip test\ntest.todo('future feature')        // mark as todo\ntest.only('focus', t =\u003e {})        // run only this\ntest.mute('quiet', t =\u003e {})        // hide assertions, show summary\ntest.demo('example', t =\u003e {})      // run but don't fail exit code\ntest.fork('isolate', t =\u003e {})      // run in worker thread (fresh V8 context)\n\n// Combine via options\ntest('both', { fork: true, only: true }, t =\u003e {})\n```\n\n\u003e [!NOTE]\n\u003e Fork has no scope access — use `data` for values, `await import()` for modules.\n\n\n## options\n\n```js\ntest('name', {\n  timeout: 3000,     // override default 5000ms\n  data: { x: 1 },    // pass to callback as 2nd arg\n  skip: isCI,        // conditionally skip\n  retry: 3           // retry up to n times (flaky tests)\n}, (t, data) =\u003e {})\n```\n\n## config\n\nManual run (disables auto-run):\n\n```js\nimport test from 'tst.js'\nawait test.run({\n  grep: /api/,       // filter by name\n  bail: true,        // stop on first failure\n  mute: true,        // hide passing tests\n  timeout: 10000,    // fail if takes \u003e10s\n  format: 'tap'      // pretty (default), tap or custom object\n})\n```\n\nOr env vars:\n\n```bash\nTST_GREP=pattern node test.js  # filter by name\nTST_BAIL=1 node test.js        # stop on first failure\nTST_MUTE=1 node test.js        # hide passing tests\nTST_FORMAT=tap node test.js    # TAP output (pipeable)\n```\n\nOr URL params (browser):\n```\ntest.html?grep=pattern\ntest.html?bail\ntest.html?mute\ntest.html?format=tap\n```\n\n\u003e [!NOTE]\n\u003e Tests run sequentially. For parallelism, run separate test files.\n\n\n## why?\n\nYou want to test `add(1, 2) === 3`.\n\nJest wants `jest.config.js`, `babel.config.js`, 200MB node_modules, transformation pipelines, mock systems.\n\nTesting should be: write test, run file, see result. No ceremony. No maintenance. No build step.\n\nSpiritual successor to [tape](https://ghub.io/tape) — browser + node, ESM-native, async-native.\n\n\u003c!--\n* [testra](https://github.com/eliot-akira/testra)\n* [tape-modern](https://ghub.io/tape-modern)\n* [@goto-bus-stop/tape-modern](https://github.com/goto-bus-stop/tape-modern#readme)\n* [brittle](https://github.com/davidmarkclements/brittle)\n* [tap](https://ghub.io/tap)\n* [tape](https://github.com/tape-testing/tape)\n* [zora](https://github.com/lorenzofox3/zora)\n* [tapes](https://www.npmjs.com/package/tapes)\n* [tape-es](https://github.com/vanillaes/tape-es)\n* [uvu](https://github.com/lukeed/uvu)\n* [pitesti](https://github.com/bengl/pitesti)\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdy%2Ftst","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdy%2Ftst","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdy%2Ftst/lists"}