{"id":16376458,"url":"https://github.com/bengl/pitesti","last_synced_at":"2025-08-28T05:14:22.351Z","repository":{"id":36651702,"uuid":"40957998","full_name":"bengl/pitesti","owner":"bengl","description":"A super-simple JavaScript test framework.","archived":false,"fork":false,"pushed_at":"2022-03-12T19:31:31.000Z","size":101,"stargazers_count":10,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-26T09:00:20.143Z","etag":null,"topics":["async-await","javascript","nodejs","promise","tap","test","test-anything-protocol","testing"],"latest_commit_sha":null,"homepage":"","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/bengl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-18T07:42:30.000Z","updated_at":"2023-08-29T19:59:45.000Z","dependencies_parsed_at":"2022-09-06T05:30:14.683Z","dependency_job_id":null,"html_url":"https://github.com/bengl/pitesti","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/bengl/pitesti","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengl%2Fpitesti","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengl%2Fpitesti/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengl%2Fpitesti/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengl%2Fpitesti/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bengl","download_url":"https://codeload.github.com/bengl/pitesti/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengl%2Fpitesti/sbom","scorecard":{"id":232501,"data":{"date":"2025-08-11","repo":{"name":"github.com/bengl/pitesti","commit":"52b36d455c4a915997e89aedc7ddceaf48e7d9e4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/bengl/pitesti/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/bengl/pitesti/ci.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:25","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T05:05:35.726Z","repository_id":36651702,"created_at":"2025-08-17T05:05:35.726Z","updated_at":"2025-08-17T05:05:35.726Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272444055,"owners_count":24936064,"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","status":"online","status_checked_at":"2025-08-28T02:00:10.768Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["async-await","javascript","nodejs","promise","tap","test","test-anything-protocol","testing"],"created_at":"2024-10-11T03:24:44.646Z","updated_at":"2025-08-28T05:14:22.331Z","avatar_url":"https://github.com/bengl.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PITESTI\n\n[![Build Status](https://github.com/bengl/pitesti/actions/workflows/ci.yml/badge.svg)](https://github.com/bengl/pitesti/actions/workflows/ci.yml)\n\n**`pitesti`** is a tiny but useful test framework for Node.js. Node 12.x and\nhigher are supported.\n\nYou can also use `pitesti` in browsers. See below for details.\n\n## GOALS\n\n* Only output [TAP](https://testanything.org/).\n* Allow just about anything to be passed in as a \"test\". For example:\n   * A function that either throws or doesn't.\n   * A function taking a nodeback/errback, where the error indicates test fail.\n   * A promise (whose result is assumed by the test).\n   * A function returning a promise (whose result is assumed by the test).\n* Super-simple test definition format.\n* No setup or teardown functions (except in BDD mode).\n\n## USAGE\n\nFirst, create a test suite.\n\n```js\nconst test = require('pitesti')();\n```\n\n`pitesti` exports a single function which creates test suites. It takes in an\noptions object (or nothing) with the following values:\n\n* `outputStream`: where to write TAP output. Default is `process.stdout`.\n* `summary`: whether or not to write a summary to the `outputStream` and the end\nof testing. Default is `true`.\n* `timeout`: Milliseconds after which to fail the test if it hasn't passed yet.\nDefault is 5000. See \"Timeouts\" below.\n* `contextSeparator`: String used to separate context names from test names.\n  Default is `' '`.\n* `done`: a callback function that will take in an exit code. Default is\n`process.exit`.\n\nNow you can write some tests and run them.\n\n```js\nconst test = require('pitesti')();\n\n// any function returning a promise can be a test\ntest('foo example test 1', function(){\n  return Promise.resolve();\n});\n\n// a failing test is one that returns a (eventually) rejecting promise\ntest('foo example test 2', function(){\n  return Promise.reject(new Error('bad'));\n});\n\n// async functions also work just fine!\ntest('foo example test 3', async function(){\n  await something();\n});\n\n// if you already have some promises lying around, you can pass those in\nlet myPromise = Promise.resolve();\ntest('foo example test 4', myPromise);\n\n// you can call test as a template literal, for a fun DSL\ntest `foo example test 5` (() =\u003e Promise.resolve('good'));\n\n// you can also have tests that just call a callback or throw\ntest `foo example test 6` (cb =\u003e {\n  maybeThrow();\n  maybeCallBackWithError(cb);\n});\n\n// this starts running the suite\ntest();\n```\n\nThis will run the tests, outputting to the `outputStream`, and when done will\ncall `done`, so in this example it will print the following to `stdout` and then\nexit.\n\n```\nTAP version 13\n1..3\nok 1 foo example 1\nnot ok 2 foo example 2\n  ---\n  name: Error\n  message: bad\n  stack: |-\n    Error: bad\n      \u003cstacktrace line 1\u003e\n      \u003cstacktrace line 2\u003e\n      \u003cstacktrace line 3\u003e\n      \u003c...\u003e\n  ...\nok 3 foo example 3\nok 3 foo example 4\n```\n\nSince one of the tests failed, the exit code is 1, rather than the 0 we'd get in\na 100% success case.\n\n### Assertions\n\nYou can use whatever assertion library you want, provided that you return a\nPromise whose end-result passes or fails the test, or just simply throw. Pretty\nmuch every assertion library falls under this, so you should be fine.\n\n### Skip and Only\n\nYou can skip or isolate a test the same way you would in Mocha. The template\nliteral forms work as with just `test`.\n\n```js\ntest.only('only this test will run', function(){\n    // ...\n});\n```\n\n```js\ntest.skip('all tests except this one will run', function(){\n    // ...\n});\n```\n\n### Timeouts\n\nBy default, each test case has a time limit of 5000ms, after which the test will\nbe considered a failure.\n\nYou can set a global timeout for an entire test suite using the options object\nas described above. You can also pass a third argument to the `test` function\nthat is an options object containing a timeout option, in order to set a timeout\nfor a specific test:\n\n```js\ntest('this is a test with a 1 second timeout', () =\u003e {\n  // ...\n}, { timeout: 1000 });\n```\n\nTo completely disable timeouts, you can set a `timeout` property to `Infinity`.\n\n### Multiple Files\n\nPitesti isn't designed with files in mind. That means you're free to do whatever\nyou want.\n\nThere are two main suggested approaches to take:\n\n1. Write test files as functions taking in the test suite function, and then\n   pass that in to each module from a main test file.\n2. Use a tool like the [`node-tap` cli ](http://www.node-tap.org/cli/) to run\n   all your test files as individual suites.\n\n### Grouping, Contexts\n\nYou can add a layer of context to tests by using `test.context`:\n\n```js\ntest.context('MyClass', () =\u003e {\n  test('foo', () =\u003e { /* ... */ });\n  test('bar', () =\u003e { /* ... */ });\n});\n```\n\nYou can do this up to an arbitrary depth.\n\nYou can change the separator used in the TAP output by using the\n`contextSeparator` option as defined above.\n\n\n### Mocha/BDD Syntax\n\nA BDD-style interface is provided, exported as `pitesti/bdd`. The exported\nfunctions are as follows, with the effectively the same functionality as\nMocha.\n\n* `describe`\n* `context`\n* `it`\n* `before`\n* `beforeAll` (same as `before`)\n* `beforeEach`\n* `after`\n* `afterAll` (same as `after`)\n* `afterEach`\n\nIf you'd like these as globals, you can do something like this.\n\n```js\nObject.assign(global, require('pitesti/bdd'));\n```\n\nNote that Mocha's `this` object is not supported. Instead, to configure an\nindividual test for timeouts, add an extra parameter to the `it` function, much\nlike the `test` function in regular Pitesti.\n\nFor example:\n\n```js\nit('does a thing', () =\u003e {\n  // ... some slow code ...\n}, { timeout: 10000 });\n```\n\nMuch like with Mocha, you don't need to initiate the test suite. It will run\non its own in a `nextTick`. Unlike Mocha, you cannot add additional test cases\ndynamically after the first tick.\n\n\u003e **NOTE:** `pitesti/bdd` does not currently work in browsers.\n\n### Browser Usage\n\nPitesti can be used in a browser environment via\n[`webpack`](https://webpack.js.org/), [`browserify`](http://browserify.org/), or\nother web packaging tools.\n\nYou'll have to set an `outputStream`, so if you're using one of the tools above,\nyou should be able to do something like:\n\n```js\nconst pitesti = require('pitesti');\nconst { Writable } = require('stream');\nconst out = document.getElementById('test-output');\nconst outputStream = new Writable({\n  write(chunk, encoding, cb) {\n    out.innerHTML += chunk;\n    cb();\n  }\n});\nconst test = pitesti({ outputStream });\n```\n\n### Caveats\n\n* Pitesti runs tests _sequentially_. While running in \"parallel\" might sound\nbetter, in reality, many real-world tests involve singletons and other global\nstate that's changed throught the course of a single test. It's far easier to\nreason about what's going on if only one test can be causing an error at any\ngiven time.\n* If your code fails to examine errors in errbacks/nodebacks, or does not handle\npromise rejections, you may find that these errors are invisible. The position\ntaken by Pitesti is that if you're ignoring an error, you don't care that it's\nan error, and it's not a problem for your code.\n\n## LICENSE\n\nCode licensed under MIT license. See LICENSE.txt\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengl%2Fpitesti","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbengl%2Fpitesti","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengl%2Fpitesti/lists"}