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

@test-bdd/testjs

v0.3.2

Published

A testing library for JavaScript that uses behavior-driven development and functional programming.

Downloads

226

Readme

testjs

A testing library for JavaScript that uses functional programming. The library works in Deno, Node and the browser.

Features

  • Functional: It uses functional programming. So, there are no hidden control flows. The tests run in the order you specify, and nothing apart from what you specify is run. This makes your test easier to reason about.
  • Behavior-driven Development (BDD): It uses behavior-driven development. This means that you test your code according to features or behavior and not implementation. This makes tests easier to write and testing code easier to maintain because even if the implementation changes, your tests don't have to change.
  • TypeScript: It supports TypeScript out of the box.
  • Multiple JavaScript Environment: It works in Deno, Node and in the browser.

Comparison with Similar Tools

This library shares some similarities with Jest and Vitest. Let us take a look at how similar and different this library is from the aforementioned tools.

Similarities

This library uses behavior-driven development similar to the one used in Jest and Vitest. It uses the same terminology, such as expect, it, and describe. It also uses patterns and test organization strategies similar to the other tools.

Differences

This library uses functional programming while Jest and Vitest use object-oriented programming. This library uses scripts written by the user to run the tests, while the other tools use CLI tools. The other libraries stop at the suite level when it comes to organizing tests. This library on the other hand adds two more levels - module and package.

Architecture

The testing library is organized into five levels giving you an easy way to organize your tests.

|-- Package
|   |-- Module
|   |   |-- Suite
|   |   |   |-- Step
|   |   |   |   |-- Expectation

Expectation

This the building block of all tests. It tests if a test meets a particular expectation. For example, if you are testing a function, you can test if the function returns a correct value for a specific input. This level is handled by expect.

Step

A group of related Expectations. It tests if the test subject meets the requirements for a group of expectations. For example, if you are testing a function, you can test if the function returns the correct value for a group of inputs that are related. This level is handled by it.

Suite

A group of related Steps. It tests if a particular feature is provided correctly by the test subject. For example, it can be used to test whether or not a function works correctly for its use case. This level is handled by describe.

Module

A group of related Suites. It tests if a group of related features are provided correctly by the test subject. For example, you can use it to test if a group of related functions provide the expected features. This level is handled by mod.

Package

This is the top-most test. It is a group of Modules. This level is handled by pack.

Usage

Synchronous

// Deno
import { describe, toEqual } from 'https://deno.land/x/testjs/mod.ts';

// Node ESM
// import { describe, toEqual } from '@test-bdd/testjs';

// Node CommonJS
// const { describe, toEqual } = require('@test-bdd/testjs');

// Test subject
const isEven = (num: number) => num % 2 === 0;

describe('isEven', (it) => {
  it('should return true for multiples of 2', (expect) => {
    expect(isEven(2), toEqual(true)); // PASSED
    expect(isEven(100), toEqual(true)); // PASSED
  });

  it('should return true for 0', (expect) => {
    expect(isEven(0), toEqual(true)); // PASSED
  });
});

Asynchronous

// Deno
import {
  describe,
  toBeGreaterThanOrEqual,
  toBeLessThan
} from 'https://deno.land/x/testjs/mod.ts';

// Node ESM
// import {
//   describe,
//   toBeGreaterThanOrEqual,
//   toBeLessThan
// } from '@test-bdd/testjs';

// Node CommonJS
// const {
//   describe,
//   toBeGreaterThanOrEqual,
//   toBeLessThan
// } = require('@test-bdd/testjs');

// Test subject
const delay = (timeMilliseconds: number) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, timeMilliseconds);
  });
};

describe('delay', async (it) => {
  await it('should delay by 1s', async (expect) => {
    const timeMilliseconds = 1000;
    const time = performance.now();
    await delay(timeMilliseconds);
    const finalTime = performance.now() - time;
    expect(finalTime, toBeGreaterThanOrEqual(timeMilliseconds));
    expect(finalTime, toBeLessThan(timeMilliseconds * 2));
  });
});

Running Tests

You can run tests by simply running the scripts containing the tests. However, the library comes with a test runner that provides a flexible way of running tests.

Running Scripts

Deno

In deno, you can run a script using deno run main.test.ts where main.test.ts is the name of the test script. You can also create a task in deno.jsonc file to avoid repeated typing of long text. A task for running tests may look like the following:

{
  "tasks": {
    "test": "deno run main.test.ts"
  }
}

To run the script, use deno task test.

Do not forget to include necessary flags. For example, if the tests need file read and write permissions, you can modify the above task as follows:

{
  "tasks": {
    "test": "deno run --allow-read --allow-write main.test.ts"
  }
}

Node

In Node.js, you can run scripts by using node main.test.js assuming main.test.js is the test file. You can create a script in package.json to avoid repetition. The script would look like the following:

{
  "scripts": {
    "test": "node main.test.ts"
  }
}

To run the script, use node run test.

Using the Test Runner

Refer to the documentation for the test runner.

Output

Syntax

The following is the syntax for the output of a test at any level:

OUTCOME (TESTS_PASSED/TOTAL) TIMEms [: DESCRIPTION]

where

  • OUTCOME indicates whether the test passed or failed. It can either be PASSED or FAILED.
  • TESTS_PASSED is the number of tests that have passed.
  • TOTAL is the total number of tests.
  • TIME is the time (in milliseconds) taken to run all tests at that level.
  • DESCRIPTION is the description you provide for the test. It is optional.

Examples

The following examples provide possible outputs for the test given in Usage;

All Passed

PASSED (2/2) 5ms: isEven
  PASSED (2/2) 3ms: it returns true for multiples of 2
    PASSED (1/1) 1ms
    PASSED (1/1) 2ms
  PASSED (1/1) 2ms: it returns true for 0
    PASSED (1/1) 2ms

Some Passed

If a test fails, all tests at higher levels of that test are also considered to have failed.

FAILED (1/2) 5ms: isEven
  PASSED (2/2) 3ms: it returns true for multiples of 2
    PASSED (1/1) 1ms
    PASSED (1/1) 2ms
  FAILED (0/1) 2ms: it returns true for 0
    FAILED (0/1) 2ms: false is not equal to true

All Failed

FAILED (0/2) 5ms: isEven
  FAILED (0/2) 3ms: it returns true for multiples of 2
    FAILED (0/1) 1ms: false is not equal to true
    FAILED (0/1) 2ms: false is not equal to true
  FAILED (0/1) 2ms: it returns true for 0
    FAILED (0/1) 2ms: false is not equal to true

API

Check out the API documentation for more.

License

Apache 2.0.