object-boolean-combinations2.11.66

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";

assert.deepEqual(
  combinations({
    a: true, // values don't matter as long as they're boolean
    b: false,
    c: true,
  }),
  [
    { a: 0, b: 0, c: 0 },
    { a: 1, b: 0, c: 0 },
    { a: 0, b: 1, c: 0 },
    { a: 1, b: 1, c: 0 },
    { a: 0, b: 0, c: 1 },
    { a: 1, b: 0, c: 1 },
    { a: 0, b: 1, c: 1 },
    { a: 1, b: 1, c: 1 },
  ]
);
// you get 2^n plain objects in an array

§ Purpose

We need it to test detergent — it has 11 options and we want to ensure that all 212 variations of all possible settings are tested. Currently detergent has 741,600 asserts, vast majority coming from the asserts on options' variations, generated by this library.

§ API

combinations(inputObject, [overrideObject])

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

§ API - Input

Input argumentTypeObligatory?Description
inputObjectPlain objectyesPlain object from which we should reference the keys.
overrideObjectPlain objectnoKeys 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.

§ Overriding

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: 0, b: 0, c: 0 },
{ a: 1, b: 1 } // <----- Override. These values will be on all combinations.
);
console.log(`test = ${JSON.stringify(test, null, 4)}`);
// => [
// {a: 1, b: 1, c: 0},
// {a: 1, b: 1, c: 1}
// ]

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) {
t.equal(
detergent("\u00A3", elem),
"&pound;",
"pound char converted into entity"
);
});
});

§ Licence

MIT opens in a new tab

Copyright © 2010–2020 Roy Revelt and other contributors

Related packages:

📦 object-flatten-referencing 4.11.27
Flatten complex nested objects according to a reference objects
📦 object-flatten-all-arrays 4.8.23
Merge and flatten any arrays found in all values within plain objects
📦 object-merge-advanced 10.11.29
Recursive, deep merge of anything (objects, arrays, strings or nested thereof), which weighs contents by type hierarchy to ensure the maximum content is retained
📦 object-set-all-values-to 3.9.67
Recursively walk the input and set all found values in plain objects to something
📦 object-no-new-keys 2.9.11
Check, does a plain object (AST/JSON) has any unique keys, not present in a reference object (another AST/JSON)
📦 object-fill-missing-keys 7.10.28
Add missing keys into plain objects, according to a reference object
📦 object-delete-key 1.9.38
Delete keys from all arrays or plain objects, nested within anything, by key or by value or by both, and clean up afterwards. Accepts wildcards.