npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

thunk-test

v1.3.1

Published

Modular testing for JavaScript

Downloads

375

Readme

ThunkTest

Node.js CI npm version

Modular testing for JavaScript. Declare tests as thunks, then execute them with a call.

const Test = require('thunk-test')

const identity = value => value

describe('identity', () => {
  it('returns whatever was passed to it',
    Test(identity)
      .case(+0, -0)
      .case('hey', 'hey')
      .case(NaN, result => {
        assert(isNaN(result))
      }))
})
//   identity
//  ✓ identity(1) -> 1
//  ✓ identity('hey') -> 'hey'
//  ✓ identity(NaN) |> result => assert(isNaN(result))
//     ✓ returns whatever was passed to it

thunk Tests are composed of a string descriptor, a function to test, and test cases denoted by .case and .throws. Any test cases may be asynchronous - either by returning a Promise explicitly or using the async keyword. Both .case and .throws accept a variadic number of arguments - the same as those provided to the function - with the exception of the last argument:

  • not a function - compare the return value directly by SameValueZero
  • an asserter function - pass the return value to the asserter function and let the asserter handle all the assertions. Note that if this value is a Promise, it is resolved before calling this function
Test(testname string, tester function)
  .case(...args, expectedResult any)
  .case(...args, asserter (result any)=>Promise|(disposer function)|null)
  .throws(...args, expectedError Error)
  .throws(...args, errorAsserter (error Error, result any)=>Promise|(disposer function)|null)

Concisely test many different cases with a declarative, idiomatic API.

Test(
  'pipe: awesome username generator',
  pipe([
    string => string.toUpperCase(),
    string => `x${string}x`,
    string => `X${string}X`,
    string => `x${string}x`,
    string => `_${string}_`,
  ]))
  .case('deimos', '_xXxDEIMOSxXx_') // objects deep equal, otherwise strict equal
  .case('|', result => assert.equal(result, '_xXx|xXx_')) // can supply a callback
  .case('?', async result => assert.equal(result, '_xXx?xXx_')) // async ok
  .throws(1, new TypeError('string.toUpperCase is not a function'))
  .throws(null, (err, arg0) => {
    assert.strictEqual(arg0, null)
    assert.strictEqual(err.name, 'TypeError')
    assert.strictEqual(err.message, 'Cannot read property \'toUpperCase\' of null')
  })()
// -- pipe: awesome username generator
//  ✓ pipeline('deimos') -> '_xXxDEIMOSxXx_'
//  ✓ pipeline('|') -> result => assert.equal(result, '_xXx|xXx_')
//  ✓ pipeline(1) throws TypeError: string.toUpperCase is not a function
//  ✓ pipeline(null) throws; (err, arg0) => {
//       assert.strictEqual(arg0, null)
//       assert.strictEqual(err.name, 'TypeError')
//       assert.strictEqual(err.message, 'Cannot read property \'toUpperCase\' of null')
//     }
//  ✓ pipeline('?') -> async result => assert.equal(result, '_xXx?xXx_')
//  ✓ pipeline(NaN) throws; async (err, arg0) => {
//       assert.strictEqual(arg0, NaN)
//       assert.strictEqual(err.name, 'TypeError')
//       assert.strictEqual(err.message, 'string.toUpperCase is not a function')
//     }

Preprocessing and postprocessing are available with callbacks supplied to .before and .after.

Note: since all callbacks are run with the same context, you can get and set values in the execution context (this) of a thunk Test from any provided callback.

Test('square', function square(number) {
  return number ** 2
}).before(function () {
    this.hello = 'world'
  })
  .case(3, function (squared) {
    assert(squared == 9)
    assert(this.hello == 'world')
  })
  .after(function () {
    assert(this.hello == 'world')
  })()
// -- square
// ✓ square(3) |> function (squared) {
//    assert(squared == 9)
//    assert(this.hello == 'world')
//  }

Syntax

ThunkTest = ()=>() {
  before: function=>this,
  after: function=>this,
  beforeEach: function=>this,
  afterEach: function=>this,
  case: (...args, expectedResult|function=>(disposer ()=>Promise<>|())|())=>this,
  throws: (...args, expectedError|function=>(disposer ()=>Promise<>|())|())=>this,
}

Test(story string, func function) -> ThunkTest

Test(func function) -> ThunkTest

Installation

with npm

npm i thunk-test

browser script, global Test

<script src="https://unpkg.com/thunk-test"></script>

browser module

import Test from 'https://unpkg.com/thunk-test/es.js'