CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tape-promise

Promise and ES2016 async/await support for the Tape testing framework.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Tape Promise

Tape 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.

Package Information

  • Package Name: tape-promise
  • Package Type: npm
  • Language: JavaScript (with Babel transpilation)
  • Installation: npm install --save-dev tape-promise
  • Prerequisites: npm install --save-dev tape

Core Imports

ES6 (ES2015):

import tape from 'tape';
import tapePromise from 'tape-promise';
const test = tapePromise(tape); // decorate tape

ES5 (CommonJS):

var tape = require('tape');
var tapePromise = require('tape-promise').default; // notice 'default'
var test = tapePromise(tape); // decorate tape

Convenience import (pre-configured):

// ES6
import test from 'tape-promise/tape';

// ES5
var test = require('tape-promise/tape');

Basic Usage

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);
  });
}

Architecture

Tape Promise uses a decorator pattern to enhance tape's functionality without requiring tape as a direct dependency:

  • Factory Function: tapePromiseFactory() accepts any tape-compatible test function and returns an enhanced version
  • Promise Detection: Uses is-promise library to identify when test functions return promises
  • Automatic Resolution: Hooks into promise resolution to automatically call t.end() when promises resolve
  • Error Handling: Captures both synchronous exceptions and unhandled promise rejections
  • Method Preservation: Copies all original tape methods (skip, only, etc.) to the enhanced function
  • Assertion Enhancement: Adds new promise-specific assertion methods (rejects, doesNotReject) to the Test prototype
  • Execution Safety: Uses onetime to ensure t.end() is only called once per test
  • Multiple Entry Points: Provides both factory function and pre-configured convenience module

This design allows tape-promise to work with any tape-compatible library while adding comprehensive promise and async/await support.

Capabilities

Tape Promise Factory

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:

  • All original tape methods and properties (skip, only, etc.)
  • Automatic promise resolution handling
  • Async/await test functions
  • Enhanced assertion methods

Enhanced Test Function

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');
});

Promise Rejection Assertions

Enhanced assertion methods for testing promise rejection scenarios.

t.rejects()

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'
  );
});

t.doesNotReject()

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');
  });
});

Enhanced Methods

test.only()

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');
});

Error Handling

Tape Promise automatically handles:

  • Unhandled Promise Rejections: Caught and passed to t.end()
  • Synchronous Exceptions: Caught in try/catch and passed to t.end()
  • Promise Resolution: Automatically calls t.end() when promise resolves (unless t.plan() was called)

Types

// 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
 */

Dependencies

  • is-promise: Utility for checking if a value is a promise
  • onetime: Ensures t.end() is only called once per test
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/tape-promise@4.0.x
Publish Source
CLI
Badge
tessl/npm-tape-promise badge