Consumes a defaults object with booleans, generates all possible variations of it

Quick Take

import { strict as assert } from "assert";
import { combinations } from "object-boolean-combinations";

    a: true,
    b: false,
    c: true,
    { a: false, b: false, c: false },
    { a: true, b: false, c: false },
    { a: false, b: true, c: false },
    { a: true, b: true, c: false },
    { a: false, b: false, c: true },
    { a: true, b: false, c: true },
    { a: false, b: true, c: true },
    { a: true, b: true, c: true },
// you get 2^n plain objects in an array


It's used to generate an array of all possible variations, 2^n, of n boolean options object keys.

Input (key values don't matter as long as key are booleans):

"oodles": true,
"crambles": false


"oodles": true,
"crambles": true
"oodles": true,
"crambles": false
"oodles": false,
"crambles": true
"oodles": false,
"crambles": false

detergent has 12 boolean toggles — that's 2^12 = 4096 variations to test for each input.

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

And so on.

Our packages don't use this library directly, there is a higher-level package test-mixer which takes into account non-boolean keys and uses this package to generate variations of boolean keys only, then restores the other keys.

API - Input


In other words, it's a function which takes two input arguments, second one being optional (marked by square brackets).

Input argument Type Obligatory? Description
inputObject Plain object yes Plain object from which we should reference the keys.
overrideObject Plain object no Keys in this object will be used as-is and will not be used for generating combinations. See overriding section below.

API - Output

Program returns an array of plain objects.


Sometimes you want to override the object keys, for example, in the a settings object, we want to override all a and b keys to be only true (1). This reduces the object combinations from 2^3 = 8 to: 2^(3-2) = 2^1 = 2:

const { combinations } = require("object-boolean-combinations");
const test = combinations(
{ a: false, b: false, c: false },
{ a: true, b: true } // <----- Override. These values will be on all combinations.
console.log(`test = ${JSON.stringify(test, null, 4)}`);
// => [
// {a: true, b: true, c: false},
// {a: true, b: true, c: true}
// ]

In example above, a and b are "pinned" to 1, thus reducing the amount of combinations by power of two, essentially halving resulting objects count twice. Notice how only c is having variations.

Overriding the combinations — in practice

In practice, we use this overriding to perform the specific tests on Detergent.js. For example, let's say, we are testing: does Detergent encode entities correctly. In that case we need two arrays filled with objects:

  • first array — encodeEntities = true and all possible combinations of the other 9 settings (2^(10-1)=512 objects in array)
  • second array — encodeEntities = false and all possible combinations of the rest — again 512 objects in array.

Here's a unit test which uses objectBooleanCombinations() to create a combinations array of settings objects, then uses forEach() to iterate through them all, testing each:

test("encode entities - pound sign", (t) => {
combinations(sampleObj, {
convertEntities: true,
}).forEach(function (elem) {
detergent("\u00A3", elem),
"pound char converted into entity"


See it in the monorepo opens in a new tab, on GitHub.


To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.


MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 test-mixer 3.0.1
Test helper to generate function opts object variations
📦 ast-monkey 8.0.1
Traverse and edit AST
📦 ast-monkey-traverse 3.0.1
Utility library to traverse AST
📦 ast-monkey-util 2.0.1
Utility library of AST helper functions
📦 json-comb-core 7.0.1
The inner core of json-comb
📦 json-variables 11.0.1
Resolves custom-marked, cross-referenced paths in parsed JSON
📦 object-merge-advanced 13.0.1
Recursively, deeply merge of anything (objects, arrays, strings or nested thereof), which weighs contents by type hierarchy to ensure the maximum content is retained