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

@zoroaster/reducer

v1.3.0

Published

The test suite reducer to run each test and see whether it passes or fails; and the runner which adds time-outs and evaluates contexts.

Downloads

11

Readme

@zoroaster/reducer

npm version

@zoroaster/reducer is a recursive reducer of tests and tests suites that can also focus on particular ones; and a test runner that supports contexts evaluation and timeouts and collecting the data from streams returned by tests. It is part of the Zoroaster Context Testing Framework.

yarn add @zoroaster/reducer

Table Of Contents

API

The package is available by importing its default reducer and the runTest function:

import reducer, { runTest } from '@zoroaster/reducer'

async reducer(  tests: Array<Test|TestSuite>,  config?: ReducerConfig,): Tree

Runs tests and test suites in the array with the runTest and runTestSuite methods and returns an object representing the tree structure in which tests were run. The runTest method can be imported from this library, and the runTestSuite can be implemented as a recursive reducer. Whether an object is a test is determined by the presence of the fn property.

import reducer, { runTest } from '@zoroaster/reducer'

const runInSequence = async (testSuite, level = 0) => {
  const indent = '  '.repeat(level)
  return await reducer(testSuite, {
    async runTest(test) {
      const result = await runTest(test)
      if (result.error) {
        console.log('%s[x] %s: %s', indent, test.name, result.error.message)
      } else {
        console.log('%s[+] %s: %s', indent, test.name, result.result)
      }
      if (result.error) result.error = result.error.message // for display
      return result
    },
    async runTestSuite(ts) {
      console.log('%s %s', indent, ts.name)
      return await runInSequence(ts.tests, level + 1)
    },
  })
}

(async () => {
  const tree = await runInSequence([
    {
      name: 'test',
      fn() { return 'ok' },
    },
    {
      name: 'test with context',
      context: class Context {
        async _init() {
          await new Promise(r => setTimeout(r, 10))
          this.hello = 'world'
        }
      },
      fn({ hello }) { return `ok - ${hello}` },
    },
    {
      name: 'test-suite',
      tests: [
        {
          name: 'test1',
          fn() { throw new Error('fail') },
        },
      ],
    },
  ])
  console.error(tree)
})()
[+] test: ok
[+] test with context: ok - world
 test-suite
  [x] test1: fail
{ test: 
   { name: 'test',
     fn: [Function: fn],
     started: 2019-05-02T14:37:00.789Z,
     finished: 2019-05-02T14:37:00.789Z,
     error: null,
     result: 'ok',
     destroyResult: [] },
  'test with context': 
   { name: 'test with context',
     context: [Function: Context],
     fn: [Function: fn],
     started: 2019-05-02T14:37:00.796Z,
     finished: 2019-05-02T14:37:00.810Z,
     error: null,
     result: 'ok - world',
     destroyResult: [ undefined ] },
  'test-suite': 
   { test1: 
      { name: 'test1',
        fn: [Function: fn],
        started: 2019-05-02T14:37:00.811Z,
        finished: 2019-05-02T14:37:00.811Z,
        error: 'fail',
        result: null,
        destroyResult: [] } } }

The main interfaces that @Zoroaster/Reducer uses are the Test and TestSuite, which contain the minimal properties required to decide whether to run a test using its fn function, or to reduce a test suite further using its tests property. These types are shared with zoroaster binary and come from the @zoroaster/types package, and are provided via externs to be able to compile the project with Google Closure Compiler via Depack.

import('@zoroaster/types').Test _contextTesting.Test: The test interface.

import('@zoroaster/types').TestSuite _contextTesting.TestSuite: The test sutie interface.

_contextTesting.ReducerConfig: The options for the reducer.

| Name | Type | Description | Default | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------- | | onlyFocused | boolean | Run only focused tests. | false | | runTest* | function(!_contextTesting.Test): !Promise | The function that wraps around @zoroaster/reducer.runTest method. | - | | runTestSuite* | function(!_contextTesting.TestSuite, boolean): !Promise<!_contextTesting.TestSuite> | The function used to run a test suite. The second argument receives whether only focused tests should be run within this test suite. | - |

The reducer iterates through the array of provided tests (which can either be test cases or test suites) and passes them one-by-one to the given runTest and runTestSuite methods which in turn must call @zoroaster/reducer.runTest method. All additional operations such as logging of results must be done by those methods, therefore this library provides the means of iterating through items and running them serially, while also evaluating the contexts. Tests can have a raw context property which is either a context constructor or a context object. If it is a constructor, it should return an object or an instance that stores a state. The package can evaluate the context of the class, function and object types. Tests then receive evaluated context to access the testing API and the state.

A recursive tree is returned by the reducer containing nested test suites with tests updated with the outcome of the runTest method (therefore, the reducer is not pure since the passed tests are mutated).

async runTest(  options: RunTestOptions,): RunTestResult

Asynchronously runs the test within a time-out limit. Evaluates the contexts beforehand and destroys them after (using the same time-out). Returns the started, finished, error, result and destroyResult properties.

The persistentContext property can contain either an array or a single evaluated context instance. They are passed to the tests in the argument list before any of the non-persistent test contexts.

In the example below, the reducer is given and array of tests and the runTest function. The test has the fn property and 2 contexts: one as an object and another one as a class. They are evaluated and passed to the test. The _destroy method of the class context is used to calculate the time taken to run the test. Finally, the result of the runTest is assigned to the tests in the array.

import reducer, { runTest } from '@zoroaster/run-test'
import { Readable } from 'stream'

(async () => {
  const persistentContext = await Promise.resolve('EXAMPLE')
  const tree = await reducer([
    {
      name: 'test',
      context: [
        { TEST: 'hello' },
        class Context {
          async _init() {
            this.data = 'world'
            this._started = new Date()
          }
          async _destroy() {
            const dt = new Date().getTime() - this._started.getTime()
            return `${dt}ms`
          }
        },
      ],
      persistentContext,
      async fn(pc, { TEST }, { data }) {
        await new Promise(r => setTimeout(r, 100))
        return `[${pc}] ${TEST}-${data}: ok`
      },
    },
    {
      name: 'test with stream',
      fn() {
        return new Readable({
          read() {
            this.push('data')
            this.push(null)
          },
        })
      },
    },
  ], {
    runTest,
  })
  console.log(tree)
})()
{ test: 
   { name: 'test',
     context: [ [Object], [Function: Context] ],
     persistentContext: 'EXAMPLE',
     fn: [AsyncFunction: fn],
     started: 2019-05-02T14:37:01.235Z,
     finished: 2019-05-02T14:37:01.366Z,
     error: null,
     result: '[EXAMPLE] hello-world: ok',
     destroyResult: [ undefined, '129ms' ] },
  'test with stream': 
   { name: 'test with stream',
     fn: [Function: fn],
     started: 2019-05-02T14:37:01.382Z,
     finished: 2019-05-02T14:37:01.493Z,
     error: null,
     result: 'data',
     destroyResult: [] } }

import('stream').Writable stream.Writable: An interface to the Catchment class. Has an additional promise property resolved on stream finish.

_contextTesting.RunTestOptions: Options for the runTest method.

| Name | Type | Description | Default | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | context | !Array<> | The contexts to evaluate. | - | | __fn__ | !Function | The function to execute. | - | | persistentContext | !Array<*> | Evaluated persistent contexts that will come before other contexts. | - | | timeout | ?number | The timeout to run the test and evaluate/destroy contexts within. | null | | onCatchment | function(!stream.Writable) | The callback that will be called with the Catchment stream if the test returned a stream. The stream's data will be collected into the catchment to create the result as a string. The callback can be used to emit errors on the Catchment stream. | - |

_contextTesting.RunTestResult: The result of the runTest function.

| Name | Type | Description | Default | | ------------- | -------------- | ------------------------------------------------------------ | ------- | | started* | Date | The date when the test started. | - | | finished* | Date | The date when the test finished. | - | | error | Error | The error which happened during the test. | null | | result | | The result which the test returned. | null | | destroyResult | | The result which the destroy method on the context returned. | null |

Copyright

(c) Context Testing 2019