Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→test-mixernext

test-mixer4.3.0

Test helper to generate function opts object variations

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • PURPOSE
  • API — MIXER()
  • API — VERSION
  • API — TYPES
  • IN PRACTICE
  • Changelog

Installation

Quick Take

Examples

  • Clone nested values in generated variations
  • No defaults means no variations
  • Carry non-boolean values into every variation
  • Pin one option while varying the others

Purpose

It’s used to generate an array of all possible combinations of options object boolean settings.

detergent has 12 boolean toggles — that’s 2^12 = 4096 variations to test for each input. This program generates those options variations.

string-collapse-white-space has 6 boolean toggles — that’s 2^6 = 64 variations to test for each input.

And so on.

API — mixer()

The main function mixer() is imported like this:

It’s a function which takes two input arguments:

Input argumentTypeDescription
ref
Type: A plain object or something falsy
refA plain object or something falsyPlain object with “pinned” values (each will reduce the generated combinations count by 1)
defaultsObj
Type: A plain object
defaultsObjA plain objectPut the default options object here.

Function will return an array of zero or more plain objects.

By the way. The order of the arguments seems backward because typically you want to export a wrapper around the mixer(), with defaults set, so that you can save time and omit the second argument, defaults. See an example below, with import { mixer as testMixer } from "text-mixer";, then export const mixer = (ref) => testMixer(ref, opts);, then prepped mixer() is one-argument function, ready for use.

API — version

You can import version:

API — types

This package is written in TypeScript and exports the following types:

TypeDescription
PlainObject
Type: PlainObject
PlainObjectA plain object with string keys and values of any type — what mixer() accepts.
PlainObjectOfBool
Type: PlainObjectOfBool
PlainObjectOfBoolA plain object whose values are all booleans — the element type of what mixer() returns.
import type { PlainObject, PlainObjectOfBool } from "test-mixer";

In practice

Let’s say you test detergent. It has the following default options:

{
  fixBrokenEntities: true,
  removeWidows: true,
  convertEntities: true,
  convertDashes: true,
  convertApostrophes: true,
  replaceLineBreaks: true,
  removeLineBreaks: false,
  useXHTML: true,
  dontEncodeNonLatin: true,
  addMissingSpaces: true,
  convertDotsToEllipsis: true,
  stripHtml: true,
  eol: "lf",
  stripHtmlButIgnoreTags: ["b", "strong", "i", "em", "br", "sup"],
  stripHtmlAddNewLine: ["li", "/ul"],
  cb: null,
}

Imagine you’re testing how detergent strips HTML, setting, opts.stripHtml.

// 😱 eleven other boolean opts settings were left out, 2^12 - 1 = 4095 other combinations!
import tap from "tap";
import { det } from "detergent";
tap.test(`01`, (t) => {
  t.equal(
    det(t, n, `text <a>text</a> text`, {
      stripHtml: true,
    }).res,
    "text text text",
  );
  t.end();
});

Here’s the proper way:

// ✅
import tap from "tap";
import { det, opts } from "detergent";
import { mixer as testMixer } from "text-mixer";

// create a wrapper to skip writing the second input argument again and again
const mixer = (ref) => testMixer(ref, opts);

tap.test(`01`, (t) => {
  // 2^11 = 2048 variations:
  mixer({
    stripHtml: false, // <--- will be the same across all generated objects
  }).forEach((opt, n) => {
    t.equal(det(t, n, `text <a>text</a> text`, opt).res, `text <a>text</a> text`, JSON.stringify(opt, null, 4));
  });
  // another 2^11 = 2048 variations:
  mixer({
    stripHtml: true,
  }).forEach((opt, n) => {
    t.equal(det(t, n, `text <a>text</a> text`, opt).res, `text text text`, JSON.stringify(opt, null, 4));
  });
  t.end();
});

Changelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab