Registry / testing / coffee

coffee

JSON →
library5.5.1jsnpmunverified

Coffee is a Node.js library designed for robust and fluent testing of command-line interfaces (CLIs). It abstracts the complexities of `child_process.fork` and `child_process.spawn`, providing a streamlined API for executing and asserting against CLI outputs and exit codes. The library, currently stable at version 5.5.1, offers powerful assertion chains for standard output (stdout), standard error (stderr), and process exit codes, supporting both exact string matches and regular expressions. Coffee differentiates itself with features like a debug mode for printing live stdio, interaction capabilities for prompts, and an extensible architecture for creating custom assertion rules. It ships with TypeScript type definitions, making it well-suited for modern JavaScript and TypeScript development workflows, often integrated into test frameworks like Mocha or Jest.

npm install coffee
INSTALL
IMPORT
SIG · COFFEE
C
coffee
testingjavascriptv5.5.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

coffee
import coffee from 'coffee';
const coffee = require('coffee');
This is the default export, providing the main `coffee` instance with `fork` and `spawn` methods. For modern Node.js and TypeScript, ESM `import` is preferred over CommonJS `require()`.
Coffee
import { Coffee } from 'coffee';
const { Coffee } = require('coffee');
The `Coffee` class is a named export, used when creating custom `coffee` instances (e.g., `class MyCoffee extends Coffee { ... }`) to extend its core functionality or modify behavior.
Rule
import { Rule } from 'coffee';
const { Rule } = require('coffee');
The `Rule` class is a named export, primarily used as a base for developing custom assertion rules (e.g., `class FileRule extends Rule { ... }`) to introduce new `expect` types.

Demonstrates how to use `coffee.fork` to test a Node.js CLI script with arguments, asserting its stdout, stderr, and exit code, and `coffee.spawn` for general shell commands.

import coffee from 'coffee'; import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; // Helper to get __dirname in ESM context const __dirname = path.dirname(fileURLToPath(import.meta.url)); const tempDir = path.join(__dirname, '.coffee-temp'); const cliScriptPath = path.join(tempDir, 'my-cli-test.js'); // Create a dummy CLI script for demonstration purposes. // In a real project, this path would point to your actual CLI entry file. fs.mkdirSync(tempDir, { recursive: true }); fs.writeFileSync(cliScriptPath, ` // my-cli-test.js console.log('Hello, ' + process.argv[2] + '!'); console.error('Debug: CLI ran.'); process.exit(parseInt(process.argv[3] || '0', 10)); `); // Example of how you might use coffee in a test file (e.g., test/my.test.ts) describe('My CLI application', () => { // Clean up the temporary file after all tests afterAll(() => { fs.unlinkSync(cliScriptPath); fs.rmdirSync(tempDir); }); it('should execute with arguments and assert stdout/stderr/code', async () => { // `coffee.fork` is used for Node.js scripts await coffee.fork(cliScriptPath, ['World', '0']) .expect('stdout', 'Hello, World!\n') .expect('stderr', 'Debug: CLI ran.\n') .expect('code', 0) // Expect a successful exit code .end(); // Important to call .end() to finalize the assertion chain }); it('should handle different exit codes', async () => { await coffee.fork(cliScriptPath, ['ErrorUser', '1']) .expect('stdout', 'Hello, ErrorUser!\n') .expect('code', 1) // Expect a non-zero exit code indicating an error .end(); }); it('should spawn a generic shell command', async () => { // `coffee.spawn` is used for non-Node.js shell commands await coffee.spawn('echo', ['Testing spawn']) .expect('stdout', 'Testing spawn\n') .expect('code', 0) .end(); }); });
Debug
Known issues
breakingTransitioning from CommonJS `require()` to ESM `import` for `coffee` in modern Node.js and TypeScript projects might require configuration adjustments (e.g., `type: "module"` in `package.json`). Although `coffee` provides CJS compatibility, using `import coffee from 'coffee'` is the idiomatic approach for new code.
fix
Ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json` or using `.mjs` files) and update `require('coffee')` statements to `import coffee from 'coffee'`. For custom extensions, use `import { Coffee, Rule } from 'coffee'`.
affects: >=5.0.0
gotchaAssertions using `expect('stdout', '...')` or `expect('stderr', '...')` often require exact string matches, including trailing newline characters (`\n`). Missing a newline at the end of the expected string is a very common cause of failing tests.
fix
Always include `\n` at the end of expected `stdout` or `stderr` strings if the child process typically outputs a newline. Alternatively, use regular expressions (e.g., `/your output\n?$/`) for more flexible matching.
affects: >=0.0.0
gotchaForgetting to call `.end()` at the end of the `coffee` assertion chain will prevent the test from executing the child process and resolving, leading to hanging tests or incorrect results. The `.end()` call signals the completion of the assertion setup and returns a promise.
fix
Ensure every `coffee` chain (after `fork` or `spawn` and any `expect` calls) explicitly ends with `.end()` and `await` it. For example: `await coffee.fork(...).expect(...).end();`
affects: >=0.0.0
Errors
Common errors & fixes
AssertionError: Expected exit code 0 but got 1
The command-line program exited with a non-zero status code, indicating an error, while the test expected success (code 0).
fix
Review the CLI script to understand why it's exiting with an error code. If the non-zero code is expected for an error condition, update `expect('code', 0)` to `expect('code', 1)` (or the appropriate error code).
AssertionError: stdout mismatch, expected 'Hello World\n' but got 'Hello World'
The expected stdout string did not exactly match the actual output, often due to a missing newline character or subtle whitespace differences.
fix
Carefully compare the expected string with the actual output. Ensure newline characters (`\n`) are correctly included or excluded. Consider using regular expressions for more robust matching if exact string comparison is too brittle (e.g., `expect('stdout', /^Hello World\n?$/)`).
TypeError: coffee(...).expect is not a function
The `.end()` method was not called at the end of the `coffee` assertion chain, preventing the promise from resolving and the test from completing or executing properly, or a method was called on a non-Coffee object.
fix
Ensure `.end()` is called at the end of your `coffee` assertion chain, and that you `await` the resulting promise. Also, verify that the `coffee` object is correctly initialized and not `null` or `undefined`.
Error: spawn <command> ENOENT
The command specified in `coffee.spawn('command', ...)` could not be found in the system's PATH. This typically means the executable is not installed or not accessible.
fix
Verify that the command (`<command>`) is correctly spelled and installed on the system where tests are run. Ensure its directory is included in the system's PATH environment variable. For Node.js scripts, consider using `coffee.fork()` instead.
Upgrade
Version history
5.5.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
17 hits · last 30 days
node
14
OpenAI (training)
1
Resources
coffee — npm install coffee · libregistry