{"id":20731675,"url":"https://github.com/tapjs/treport","last_synced_at":"2025-04-23T22:08:09.421Z","repository":{"id":34413725,"uuid":"174889696","full_name":"tapjs/treport","owner":"tapjs","description":"a reporter for node-tap","archived":false,"fork":false,"pushed_at":"2023-10-10T17:32:53.000Z","size":3175,"stargazers_count":12,"open_issues_count":7,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-23T22:06:33.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/tapjs.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},"funding":{"github":["isaacs"]}},"created_at":"2019-03-10T22:37:54.000Z","updated_at":"2025-01-04T07:37:20.000Z","dependencies_parsed_at":"2024-01-28T23:43:37.446Z","dependency_job_id":null,"html_url":"https://github.com/tapjs/treport","commit_stats":{"total_commits":157,"total_committers":3,"mean_commits":"52.333333333333336","dds":0.01273885350318471,"last_synced_commit":"d7e54dc83d7f3c9e00ebc1d0339e7f8614797450"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Ftreport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Ftreport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Ftreport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Ftreport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tapjs","download_url":"https://codeload.github.com/tapjs/treport/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250522298,"owners_count":21444511,"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":[],"created_at":"2024-11-17T05:16:23.801Z","updated_at":"2025-04-23T22:08:09.377Z","avatar_url":"https://github.com/tapjs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/isaacs"],"categories":[],"sub_categories":[],"readme":"# treporter\n\nReporters for node-tap\n\nAn [ink](http://npm.im/ink)-based reporter for use with\n[tap](http://npm.im/tap) version 13 and higher.\n\n## Built-in Report Types\n\n### Base\n\nThe default, and the class to extend to create new reporters.  Does all the\nthings, handles all the edge cases, and ends with a pleasant surprise.\n\n### Terse\n\nA lot like Base, but says a lot less.  No timer, no list of tests concurrently\nrunning, nothing printed on test passing.  Just the failures and the terse\nsummary.\n\n### Specy\n\nA `spec` style reporter with the current running jobs and Terse summary and\nfooter.\n\n## Extending\n\nYou can extend this by creating a module whose main `module.exports` is a\nchild class that extends the `treport.Base` class (which in turn extends\n`React.Component`).\n\n```js\nconst React = require('react')\nconst {Base} = require('treport')\nclass MyTreportBasedTapReporter extends Base {\n  // my stuff...\n}\nmodule.exports = MyTreportBasedTapReporter\n```\n\nTo use your module as the test reporter, you'd do this:\n\n```\nnpm install -D my-treport-based-tap-reporter\ntap --reporter=my-treport-based-tap-reporter\n```\n\nTap will `require()` that module, see it's a `React.Component`, and use it\nwith ink.\n\nYour child class will get its `constructor()` called with `{tap:tap}`,\nwhich is the root tap object for the test runner.\n\nIt can override the `render()` method, or anything else.  In most cases, you\nwill likely want to override just part of the class, or one of the tags used\nfor the layout, but the sky is the limit.  A child class could also modify the\ndata being tracked, but leave the tags untouched.\n\nThe following methods describe each of the class methods that can be\noverridden.\n\n### render()\n\nThe main rendering entry point, as is the React custom.  The Base class\nreturns:\n\n```jsx\n\u003cBox flexDirection=\"column\"\u003e\n  \u003cthis.Log log={this.state.log} /\u003e\n  \u003cthis.Runs runs={this.state.runs} /\u003e\n  { this.state.results ? (\n      \u003cthis.Summary\n        results={this.state.results}\n        tests={this.state.tests} /\u003e\n    )\n    : '' }\n  \u003cthis.Footer\n    suiteCounts={suiteCounts}\n    assertCounts={assertCounts}\n    time={time} /\u003e\n\u003c/Box\u003e\n```\n\nOne of the easiest ways to change the look and feel of the test reporter is to\nswap out these components.\n\n### get Log()\n\nA getter function that returns the React component for the \"log\" section.  This\nsection gets failure/todo/skip results pushed into it, as well as the final\npass/fail/todo/skip result for tests when they complete.  Typically, it should\nuse a `\u003cStatic\u003e` tag, since this will often get much longer than the height of\nthe terminal window, and you want to be able to see the results.\n\nSee `state.log` below for more info.\n\n### get Runs()\n\n- `runs` Array of Test objects\n\nA getter function that returns the React component for the \"runs\" section.\n`this.state.runs` is a list of the tests currently in progress.\n\n### get Summary()\n\nThis is a section that shows when the test run is fully completed.  It shows a\npretty banner with rainbows, along with any tests that failed, or are marked as\nskip or todo.\n\n### get Footer()\n\nThis is a section that shows the count of test suites (ie, processes) queued\nand completed, a count of assertions completed, and a timer so you can see how\nlong the test is running for.\n\n## State Properties\n\nThe reporter keeps the following state properties up to date as the test\nproceeds:\n\n### this.state.log\n\nArray of log objects.  Each is one of the following types:\n\n- `{ raw: \u003cString\u003e }` just a plain old string.\n- `{ res: {ok, name, diag, todo, skip, testName} }` A test point\n- `{ test: [Test Object] }` A test that has completed\n\n### this.state.tests\n\nAll tests are added to this array.  In the event of a bailout, everything other\nthan the bailing-out test is removed, so that the Summary output isn't\ncluttered up with a bunch of spurious failures.\n\n### this.state.runs\n\nArray of tests currently running.  (When not running in parallel mode, this is\nalways a single item.)\n\n### this.state.results\n\nThe `tap.results` object at the end of the test run.\n\n### this.state.assertCounts\n\nCounts of all assertions run in all tests. `{total, pass, fail, skip, todo}`\n\nIn order to avoid overwhelming the display, updates to assertion counts are\ndebounced so that they are not updated more than once every 50ms.\n\n### this.state.suiteCounts\n\nJust like `assertCounts`, but for test suites, and not debounced.\n\n### this.state.time\n\nTotal elapsed time in ms since the test run started.\n\n### this.state.bailout\n\nWhen a bailout occurs, this is set to the bailout reason, or `true` if no\nreason is given.\n\n### this.start\n\nThe `Date.now()` when the test run started.\n\n### this.assertCounts\n\nUpdated on each test assertion.  Matched to `this.state.assertCounts` at most\nonce every 50ms.\n\n### constructor()\n\nThe constructor receives `tap` as an argument, initializes state, and assigns\nappropriate event handlers to keep state up to date.  Then, the\n`this.tapResume(tap)` method is called to resume and discard the TAP output\nfrom the test harness, since the reporter gets everything it needs from the\nevents and child test objects.\n\n### tapResume(tap)\n\nOverride to prevent the `tap` object from being resumed when calling the Base\nconstructor.\n\n### get time()\n\nCalled to get the current running time.\n\n### bailout(bailout, test = null)\n\nCalled when a test bails out.  If `test` is set to null, then that means that\nthe root Tap test is bailing out independently of any child test.  (This is\nunusual.)\n\n### inc(type)\n\nCalled on each assertion to increment `this.assertCounts` and\n`this.state.assertCounts`.\n\n### addTest(test)\n\nCalled whenever a new test is added to the queue (but before it has started\nrunning).\n\n### startTest(test)\n\nCalled when a test starts.\n\n### endTest(test)\n\nCalled when a test ends.\n\n### endAll(tap)\n\nCalled when the main all tests are done and the tap test runner completes.\n\n### logRes(test, res)\n\nCalled when a fail/todo/skip result is emitted from a test, and pushes it onto\nthe log.\n\n### onRaw(test, fd)\n\nReturns a handler to take all the non-TAP data from a child test, so that it\ncan be printed to the log with a helpful prefix.  In the Base test class, this\nprefixes with the name of the test and the file descriptor printed to.\n\nSo, for example, a test named `test/foo.js` would have its stderr output\nprefixed with `test/foo.js 2\u003e ...` and its stdout output prefixed with\n`test/foo.js 1\u003e ...`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftapjs%2Ftreport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftapjs%2Ftreport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftapjs%2Ftreport/lists"}