Promise and ES2016 async/await support for the Tape testing framework.
npx @tessl/cli install tessl/npm-tape-promise@4.0.0Tape Promise provides Promise and ES2016 (ES7) async/await support for the Tape testing framework. It acts as a decorator that enhances tape with the ability to handle Promise-based and async/await test functions without requiring tape as a direct dependency.
npm install --save-dev tape-promisenpm install --save-dev tapeES6 (ES2015):
import tape from 'tape';
import tapePromise from 'tape-promise';
const test = tapePromise(tape); // decorate tapeES5 (CommonJS):
var tape = require('tape');
var tapePromise = require('tape-promise').default; // notice 'default'
var test = tapePromise(tape); // decorate tapeConvenience import (pre-configured):
// ES6
import test from 'tape-promise/tape';
// ES5
var test = require('tape-promise/tape');import test from 'tape-promise/tape';
// Promise-based test
test('promise test', function (t) {
return delay(100).then(function () {
t.true(true);
});
});
// Async/await test
test('async test', async function (t) {
await delay(100);
t.true(true);
// t.end() is optional for async functions
});
// Regular tape test still works
test('regular test', function (t) {
t.true(true);
t.end();
});
// Example helper function
function delay(time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, time);
});
}Tape Promise uses a decorator pattern to enhance tape's functionality without requiring tape as a direct dependency:
tapePromiseFactory() accepts any tape-compatible test function and returns an enhanced versionis-promise library to identify when test functions return promisest.end() when promises resolverejects, doesNotReject) to the Test prototypeonetime to ensure t.end() is only called once per testThis design allows tape-promise to work with any tape-compatible library while adding comprehensive promise and async/await support.
Creates a decorated version of tape that supports Promise and async/await test functions.
/**
* Factory function that decorates a tape test function with promise support
* @param {Function} tapeTest - The tape test function to be decorated
* @returns {Function} Enhanced test function with promise support
*/
function tapePromiseFactory(tapeTest);The returned test function supports:
The decorated test function accepts the same arguments as tape but with promise support.
/**
* Enhanced test function that supports promises and async/await
* @param {string} [name] - Test name
* @param {Object} [opts] - Test options
* @param {Function} callback - Test function that can return promises or be async
*/
function test(name, opts, callback);Usage patterns:
// Named test with promise return
test('my test', function (t) {
return someAsyncOperation().then(() => {
t.pass('async operation completed');
});
});
// Async/await test
test('async test', async function (t) {
const result = await someAsyncOperation();
t.equal(result, 'expected');
});
// Test with options
test('test with options', { timeout: 5000 }, async function (t) {
await longRunningOperation();
t.pass('completed');
});Enhanced assertion methods for testing promise rejection scenarios.
Asserts that a promise will reject.
/**
* Assert that the promise will reject
* @param {Promise|Function} promise - Promise to test or function that returns a promise
* @param {RegExp|Function} [expected] - Expected error pattern (RegExp) or constructor (Function)
* @param {string} [message='should reject'] - Assertion message
* @param {Object} [extra] - Extra assertion data
* @returns {Promise} Promise that resolves when assertion completes
*/
t.rejects(promise, expected, message, extra);Usage examples:
test('rejection tests', async (t) => {
// Test promise rejection
await t.rejects(Promise.reject(new Error('failed')));
// Test with error pattern
await t.rejects(
Promise.reject(new Error('connection failed')),
/connection failed/
);
// Test with error constructor
await t.rejects(
Promise.reject(new TypeError('invalid type')),
TypeError
);
// Test function that returns rejecting promise
await t.rejects(function () {
return Promise.reject(new Error('async error'));
});
// With custom message
await t.rejects(
failingAsync(),
/network/,
'should fail with network error'
);
});Asserts that a promise will resolve (not reject).
/**
* Assert that the promise will resolve
* @param {Promise|Function} promise - Promise to test or function that returns a promise
* @param {RegExp|Function} [expected] - Error pattern that should NOT be thrown
* @param {string} [message='should resolve'] - Assertion message
* @param {Object} [extra] - Extra assertion data
* @returns {Promise} Promise that resolves when assertion completes
*/
t.doesNotReject(promise, expected, message, extra);Usage examples:
test('resolution tests', async (t) => {
// Test promise resolution
await t.doesNotReject(Promise.resolve('success'));
// Test that specific error is NOT thrown
await t.doesNotReject(
someAsyncOperation(),
TypeError,
'should not throw TypeError'
);
// Test function that returns resolving promise
await t.doesNotReject(function () {
return Promise.resolve('data');
});
});The only method is also enhanced with promise support for focused testing.
/**
* Enhanced only method with promise support
* @param {string} [name] - Test name
* @param {Object} [opts] - Test options
* @param {Function} callback - Test function that can return promises or be async
*/
test.only(name, opts, callback);Usage:
test.only('focused async test', async function (t) {
const result = await criticalAsyncOperation();
t.ok(result, 'critical operation succeeded');
});Tape Promise automatically handles:
t.end()t.end()t.end() when promise resolves (unless t.plan() was called)// Main factory function signature
/**
* @typedef {Function} tapePromiseFactory
* @param {TapeTest} tapeTest - Original tape test function
* @returns {EnhancedTest} Enhanced test function with promise support
*/
// Enhanced test function interface
/**
* @typedef {Function} EnhancedTest
* @param {string} [name] - Test name
* @param {TestOptions} [opts] - Test options
* @param {TestCallback} callback - Test function
* @property {EnhancedTest} skip - Skip this test
* @property {EnhancedTest} only - Run only this test (with promise support)
*/
// Test callback types
/**
* @typedef {Function} TestCallback
* @param {EnhancedAssert} t - Test assertion object
* @returns {void|Promise} Can return void or a Promise
*/
// Enhanced assertion interface (extends tape's assertions)
/**
* @typedef {Object} EnhancedAssert
* @property {Function} rejects - Assert promise rejection
* @property {Function} doesNotReject - Assert promise resolution
* @property {Function} end - End the test (automatically called for promises)
* @property {Function} plan - Plan number of assertions
* // ... all standard tape assertions (ok, equal, deepEqual, etc.)
*/
// Test options
/**
* @typedef {Object} TestOptions
* @property {number} [timeout] - Test timeout in milliseconds
* @property {boolean} [skip] - Skip this test
* @property {Object} [objectPrintDepth] - Object print depth for assertions
* // ... other tape options
*/
// Internal helper types
/**
* @typedef {Object} TestArgs
* @property {string} name - Resolved test name
* @property {TestOptions} opts - Resolved test options
* @property {TestCallback} cb - Test callback function
*/is-promise: Utility for checking if a value is a promiseonetime: Ensures t.end() is only called once per test