{"id":21937633,"url":"https://github.com/cap32/kapok-js","last_synced_at":"2025-04-22T12:12:39.438Z","repository":{"id":57288283,"uuid":"89842170","full_name":"Cap32/kapok-js","owner":"Cap32","description":"Javascript Testing utilities for CLI","archived":false,"fork":false,"pushed_at":"2018-01-21T07:00:16.000Z","size":96,"stargazers_count":2,"open_issues_count":16,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-22T12:12:23.491Z","etag":null,"topics":["cli","javascript","node","node-js","nodejs","test","testing","testing-framework","testing-tools","utilities"],"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/Cap32.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-30T09:40:45.000Z","updated_at":"2017-05-02T03:55:22.000Z","dependencies_parsed_at":"2022-09-08T09:42:27.319Z","dependency_job_id":null,"html_url":"https://github.com/Cap32/kapok-js","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Fkapok-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Fkapok-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Fkapok-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Fkapok-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cap32","download_url":"https://codeload.github.com/Cap32/kapok-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237832,"owners_count":21397401,"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":["cli","javascript","node","node-js","nodejs","test","testing","testing-framework","testing-tools","utilities"],"created_at":"2024-11-29T01:20:54.242Z","updated_at":"2025-04-22T12:12:39.406Z","avatar_url":"https://github.com/Cap32.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kapok-js\n\n[![Build Status](https://travis-ci.org/Cap32/kapok-js.svg?branch=master)](https://travis-ci.org/Cap32/kapok-js) [![CircleCI](https://circleci.com/gh/Cap32/kapok-js.svg?style=svg)](https://circleci.com/gh/Cap32/kapok-js)\n\nJavascript Testing utilities for CLI\n\n\n## Table of Contents\n\n\u003c!-- MarkdownTOC autolink=\"true\" bracket=\"round\" --\u003e\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [API](#api)\n  - [Kapok.config](#kapokconfig)\n  - [Kapok.start\\(command\\[, args\\]\\[, options\\]\\)](#kapokstartcommand-args-options)\n  - [Kapok.size](#kapoksize)\n  - [Kapok.killAll\\(\\)](#kapokkillall)\n  - [Kapok#constructor\\(command\\[, args\\]\\[, options\\]\\)](#kapokconstructorcommand-args-options)\n  - [Kapok#assert\\(condition\\[, options\\]\\)](#kapokassertcondition-options)\n  - [Kapok#joinUntil\\(condition\\[, options\\]\\)](#kapokjoinuntilcondition-options)\n  - [Kapok#until\\(condition\\[, options\\]\\)](#kapokuntilcondition-options)\n  - [Kapok#assertUntil\\(condition\\[, options\\]\\)](#kapokassertuntilcondition-options)\n  - [Kapok#ignoreUntil\\(condition\\[, options\\]\\)](#kapokignoreuntilcondition-options)\n  - [Kapok#done\\(\\[callback\\]\\)](#kapokdonecallback)\n  - [Kapok#doneAndKill\\(\\[callback\\]\\)](#kapokdoneandkillcallback)\n  - [Kapok#kill\\(\\[signal, callback\\]\\)](#kapokkillsignal-callback)\n  - [Event: 'data'](#event-data)\n  - [Event: 'out:data'](#event-outdata)\n  - [Event: 'err:data'](#event-errdata)\n  - [Event: 'line'](#event-line)\n  - [Event: 'out:line'](#event-outline)\n  - [Event: 'err:line'](#event-errline)\n  - [Event: 'error'](#event-error)\n  - [Event: 'exit'](#event-exit)\n  - [Event: 'signal:exit'](#event-signalexit)\n- [License](#license)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n## Installation\n\n```bash\nyarn add -D kapok-js\n```\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n## Usage\n\n```js\nimport Kapok from 'kapok-js';\n\nconst kapok = new Kapok('echo', ['hello\\nworld']);\nkapok.assert('hello').assert('world');\n```\n\n##### Advanced Usage\n\n```js\nimport Kapok from 'kapok-js';\nimport { isEqual } from 'lodash';\n\nconst code = `\n  console.log('🌺');\n  console.log('* * *');\n  console.log('start');\n  console.log(JSON.stringify({ hello: 'world' }, null, 2));\n  console.log('end');\n`;\n\n/*\n🌺\n* * *\nstart\n{\n  \"hello\": \"world\"\n}\nend\n*/\n\nconst kapok = new Kapok('node', ['-e', code]); /* just like childProcess.spawn() */\nkapok\n  .ignoreUntil(/\\*/) /* ignore lines until the line matches \"*\" */\n  .assert('start')\n  .joinUntil('}') /* join multi lines until the line is equal to '}', and then join the lines into a string */\n  .assert((message) =\u003e isEqual({ hello: 'world' }, JSON.parse(message)))\n  .assert('end')\n  .done(() =\u003e {\n    console.log('done');\n  })\n;\n```\n\n\n\u003ca name=\"api\"\u003e\u003c/a\u003e\n## API\n\n\u003ca name=\"kapokconfig\"\u003e\u003c/a\u003e\n#### Kapok.config\n\n- `config.shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `true`\n- `config.shouldThrowError` \\\u003cBoolean\\\u003e: Throw a new Error or not when assert fails. Defaults to `false`\n\nA global config to all `Kapok` instances. Can be override.\n\n---\n\n\n\u003ca name=\"kapokstartcommand-args-options\"\u003e\u003c/a\u003e\n#### Kapok.start(command[, args][, options])\n\n- `command` \\\u003cString\\\u003e: The command to run\n- `args` \\\u003cArray\\\u003e: List of string arguments\n- `options` \\\u003cObject\\\u003e: Just like [spawn options](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)\n- Returns \\\u003cKapok\\\u003e\n\nSpawns a new process using the given `command`, just like `child_process.spawn()`, but returns a `Kapok` instance.\n\n`Kapok` inherits [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)\n\n\n---\n\n\u003ca name=\"kapoksize\"\u003e\u003c/a\u003e\n#### Kapok.size\n\n- Returns \\\u003cNumber\\\u003e\n\nGet existing kapok instances size\n\n\n---\n\n\u003ca name=\"kapokkillall\"\u003e\u003c/a\u003e\n#### Kapok.killAll()\n\n- Return \\\u003cPromise\\\u003e\n\nKill all existing kapok instances\n\n\n---\n\n\u003ca name=\"kapokconstructorcommand-args-options\"\u003e\u003c/a\u003e\n#### Kapok#constructor(command[, args][, options])\n\nThe same with `Kapok.start()`\n\n\n---\n\n\u003ca name=\"kapokassertcondition-options\"\u003e\u003c/a\u003e\n#### Kapok#assert(condition[, options])\n\n- `condition` \\\u003cString|RegExp|Function\\\u003e: Testing `message`, throw an error if returns `false`. The `message` is the each line data of process outputs\n  + If is a `String`, it will return `message === condition`\n  + If is a `RegExp`, it will return `condition.test(message)`\n  + If is a `Function`, it will return `condition(message, lines)`\n    * `message` \\\u003cString\\\u003e: Data message of each line\n    * `lines` \\\u003cArray\\\u003e: An array of data. A data includes `message` and `ansiMessage`. `ansiMessage` is like `message`, but includes some ANSI code.\n- `options` \u003cString|Object\u003e\n  + `errorMessage` \\\u003cString\\\u003e: If `condition` returns `false`, it will throw a new error with the message. If the `options` is a `String`, it will become a short hand of `options.errorMessage`\n  + `action` \\\u003cFunction\\\u003e: An addition function to do something while `assert` function fires. Support returning a promise for async action\n  + `shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `Kapok.config.shouldShowLog`\n  + `shouldThrowError` \\\u003cBoolean\\\u003e: Throw a new Error or not when assert fails. Defaults to `Kapok.config.shouldThrowError`\n- Returns \\\u003cKapok\\\u003e\n\nIterate each line of the process outputs, and assert the data message of each line.\n\n###### Example\n\n```js\nconst kapok = new Kapok('echo', ['a\\nb\\nc']);\nkapok\n  .assert('a') /* using `String` */\n  .assert(/b/) /* using `RegExp` */\n  .assert((message) =\u003e message === 'c') /* using `Function` */\n  .done()\n;\n```\n\n---\n\n\u003ca name=\"kapokjoinuntilcondition-options\"\u003e\u003c/a\u003e\n#### Kapok#joinUntil(condition[, options])\n\n- `condition` \\\u003cNumber|String|RegExp|Function\\\u003e: Decide when to stop grouping lines\n  + If is a `Number`, it will return `true` if the delta line number is equal with `condition` number\n  + If is a `String`, it will return `message === condition`\n  + If is a `RegExp`, it will return `condition.test(message)`\n  + If is a `Function`, it will return `condition(message, lines)`\n- `options` \\\u003cObject\\\u003e\n  + `join` \u003cString|Function|false\u003e: Join the grouped `messages` into a string\n    * If is a `String`, it will join messages by `messages.join(joinString)`\n    * If is a `Function`, it will join messages by `join(lines)`\n    * If is `false`, it won't join messages\n    * By default, it is an empty string\n  + `action` \\\u003cFunction\\\u003e: An addition function to do something while condition matched. Support returning a promise for async action\n  + `shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `Kapok.config.shouldShowLog`\n- Returns \\\u003cKapok\\\u003e\n\nA helper function to join multi lines into a string and pass to the next `assert()`. Joining function will stop when `condition()` matched.\n\n###### Example\n\n```js\nconst input = { a: 'hello', b: 'world' };\nconst code = `\n  var data = eval(${JSON.stringify(input)});\n  console.log(JSON.stringify(data, null, 2));\n`;\nconst kapok = new Kapok('node', ['-e', code]);\nkapok\n  .joinUntil('}')\n  .assert((message) =\u003e {\n    const json = JSON.parse(message);\n    return isEqual(json, input);\n  })\n  .done()\n;\n```\n\n---\n\n\u003ca name=\"kapokuntilcondition-options\"\u003e\u003c/a\u003e\n#### Kapok#until(condition[, options])\n\n- `condition` \\\u003cNumber|String|RegExp|Function\\\u003e: Decide when to start to assert next line\n  + If is a `Number`, it will return `true` if the delta line number is equal with `condition` number\n  + If is a `String`, it will return `message === condition`\n  + If is a `RegExp`, it will return `condition.test(message)`\n  + If is a `Function`, it will return `condition(message, lines)`\n- `options` \\\u003cObject\\\u003e\n  + `action` \\\u003cFunction\\\u003e: An addition function to do something while condition matched. Support returning a promise for async action\n  + `shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `Kapok.config.shouldShowLog`\n- Returns \\\u003cKapok\\\u003e\n\nMessage will not pass to the next `assert()` until `condition()` matched.\n\n###### Example\n\n```js\nconst kapok = new Kapok('echo', ['# a\\n# b\\nc']);\nkapok.until(/^[^#]/).assert('c').done(); /* lines before 'c' would be ignored */\n```\n\n---\n\n\u003ca name=\"kapokassertuntilcondition-options\"\u003e\u003c/a\u003e\n#### Kapok#assertUntil(condition[, options])\n\n- `condition` \\\u003cNumber|String|RegExp|Function\\\u003e: Decide when to start to assert\n  + If is a `Number`, it will return `true` if the delta line number is equal with `condition` number\n  + If is a `String`, it will return `message === condition`\n  + If is a `RegExp`, it will return `condition.test(message)`\n  + If is a `Function`, it will return `condition(message, lines)`\n- `options` \\\u003cObject\\\u003e\n  + `action` \\\u003cFunction\\\u003e: An addition function to do something while condition matched. Support returning a promise for async action\n  + `shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `Kapok.config.shouldShowLog`\n- Returns \\\u003cKapok\\\u003e\n\nMessage will not pass to the next `assert()` until `condition()` matched.\n\n###### Example\n\n```js\nconst kapok = new Kapok('echo', ['# a\\n# b\\nc']);\nkapok.assertUntil('c').done(); /* lines before 'c' would be ignored */\n```\n\n---\n\n\u003ca name=\"kapokignoreuntilcondition-options\"\u003e\u003c/a\u003e\n#### Kapok#ignoreUntil(condition[, options])\n\n- `condition` \\\u003cNumber|String|RegExp|Function\\\u003e: Decide when to stop ignoring\n  + If is a `Number`, it will return `true` if the delta line number is equal with `condition` number\n  + If is a `String`, it will return `message === condition`\n  + If is a `RegExp`, it will return `condition.test(message)`\n  + If is a `Function`, it will return `condition(message, lines)`\n- `options` \\\u003cObject\\\u003e\n  + `action` \\\u003cFunction\\\u003e: An addition function to do something while condition matched. Support returning a promise for async action\n  + `shouldShowLog` \\\u003cBoolean\\\u003e: Show log message or not. Defaults to `Kapok.config.shouldShowLog`\n- Returns \\\u003cKapok\\\u003e\n\nA little like `.until()`, but `.ignoreUntil()` will event ignore the last line of the matched `condition()`.\n\n###### Example\n\n```js\nconst kapok = new Kapok('echo', ['# a\\n# b\\nc']);\nkapok.ignoreUntil(/^#/).assert('c'); /* lines before 'c' would be ignored */\n```\n\n---\n\n\u003ca name=\"kapokdonecallback\"\u003e\u003c/a\u003e\n#### Kapok#done([callback])\n\n- `callback` \\\u003cFunction\\\u003e: Provide a callback function. If there's no error, the first argument is `undefined`, otherwise, the first argument is an array of errors\n- Returns \\\u003cPromise\\\u003e\n\nStop asserting. Could provide a callback function or return a promise for async function.\n\n###### Example\n\nUsing [jest](http://facebook.github.io/jest/)\n\n```js\nconst kapok = new Kapok('echo', ['hello']);\n\ntest('echo', async () =\u003e kapok.assert('hello').done());\n```\n\n---\n\n\u003ca name=\"kapokdoneandkillcallback\"\u003e\u003c/a\u003e\n#### Kapok#doneAndKill([callback])\n\n- `callback` \\\u003cFunction\\\u003e: Provide a callback function. If there's no error, the first argument is `undefined`, otherwise, the first argument is an array of errors\n- Returns \\\u003cPromise\\\u003e\n\nLike `done()`, but also kill the process after stop asserting.\n\n---\n\n\u003ca name=\"kapokkillsignal-callback\"\u003e\u003c/a\u003e\n#### Kapok#kill([signal, callback])\n\n- `callback` \\\u003cFunction\\\u003e: Provide a callback function.\n- Returns \\\u003cPromise\\\u003e\n\nKilling kapok process. Could provide a callback function or return a promise for async function.\n\n---\n\n\u003ca name=\"event-data\"\u003e\u003c/a\u003e\n#### Event: 'data'\n\n- `data` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `data` event will emitted when the `stdout` or `stderr` output data.\n\n\n\u003ca name=\"event-outdata\"\u003e\u003c/a\u003e\n#### Event: 'out:data'\n\n- `data` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `out:data` event will emitted when the `stdout` output data.\n\n\n\u003ca name=\"event-errdata\"\u003e\u003c/a\u003e\n#### Event: 'err:data'\n\n- `data` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `err:data` event will emitted when the `stderr` output data.\n\n\n\u003ca name=\"event-line\"\u003e\u003c/a\u003e\n#### Event: 'line'\n\n- `line` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `line` event will emitted when the `stdout` or `stderr` output each lines.\n\n\n\u003ca name=\"event-outline\"\u003e\u003c/a\u003e\n#### Event: 'out:line'\n\n- `line` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `out:line` event will emitted when the `stdout` output each lines.\n\n\n\u003ca name=\"event-errline\"\u003e\u003c/a\u003e\n#### Event: 'err:line'\n\n- `line` \\\u003cObject\\\u003e\n  + `message` \\\u003cString\\\u003e: Data message\n  + `ansiMessage` \\\u003cString\\\u003e: Data message includes ANSI code\n\nThe `err:line` event will emitted when the `stderr` output each lines.\n\n\n\u003ca name=\"event-error\"\u003e\u003c/a\u003e\n#### Event: 'error'\n\nThe same with [child_process error event](https://nodejs.org/api/child_process.html#child_process_event_error)\n\n\n\u003ca name=\"event-exit\"\u003e\u003c/a\u003e\n#### Event: 'exit'\n\nThe same with [child_process exit event](https://nodejs.org/api/child_process.html#child_process_event_exit)\n\n\n\u003ca name=\"event-signalexit\"\u003e\u003c/a\u003e\n#### Event: 'signal:exit'\n\n- `code` \\\u003cString\\\u003e: Exit code\n- `signal` \\\u003cString\\\u003e: Signal\n\nThe `signal:exit` event will emitted when receive `SIG*` exit event.\n\n\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcap32%2Fkapok-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcap32%2Fkapok-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcap32%2Fkapok-js/lists"}