TypeOfNaN

Generate All Possible Combinations in JavaScript Using Combinate

Nick Scialli
June 13, 2020

combinate screenshot

One challenge we often face when creating apps is combinatoric complexity. Today, we’re going to use a handy helper npm package I created to list all possible permutations of variables we’re interested in. This can be especially handy for generating tests for every possible data scenario!

The Problem

Let’s say we have an app that has has some user-set color value, a variable that indicates whether the user is an admin, and a light or dark theme mode.

The following represents the possible values for each variable:

color = "red" | "blue" | "green"
admin = true | false
mode = "light" | "dark"

This assumes our possible values for color are "red", "blue", or "green", our possible values for admin are true or false, and our possible values for mode are "light" and "dark".

We’d like to test our app using each possible combination of these variables. In this case, there are 3 x 2 x 2 = 12 combinations. We could write out all these test cases individually, but that would be a pain. Also, in a real application, you would likely end up with many more than 12 combinations.

Using Combinate

Let’s solve this problem with the combinate package I created!

First, let’s get combinate install. We can do this with npm or yarn.

npm i combinate

or

yarn add combinate

Next, let’s create an object that represents all the possible options for each variable:

const options = {
  color: ['red', 'blue', 'green'],
  admin: [true, false],
  mode: ['light', 'dark'],
};

Finally, we just have to pass this to our combinate function, and we’ll get an array of all of the possible combinations! let’s see it in action.

import combinate from 'combinate';

const options = {
  color: ['red', 'blue', 'green'],
  admin: [true, false],
  mode: ['light', 'dark'],
};

const combinations = combinate(options);

console.log(combinations);

/*
[
  {"admin": true, "color": "red", "mode": "light"},
  {"admin": true, "color": "blue", "mode": "light"},
  {"admin": true, "color": "green", "mode": "light"},
  {"admin": false, "color": "red", "mode": "light"},
  {"admin": false, "color": "blue", "mode": "light"},
  {"admin": false, "color": "green", "mode": "light"},
  {"admin": true, "color": "red", "mode": "dark"},
  {"admin": true, "color": "blue", "mode": "dark"},
  {"admin": true, "color": "green", "mode": "dark"},
  {"admin": false, "color": "red", "mode": "dark"},
  {"admin": false, "color": "blue", "mode": "dark"},
  {"admin": false, "color": "green", "mode": "dark"}
]
*/

Using in a Test

Getting all combinations is great and all, but what’s actual use case for doing this?

One way I’ve used this is frontend storyshot generation using a tool like Storybook. Using Storybook in conjunction with combinate, you can generate visual tests for every possible combination quickly.

A super barebones example, if you’re familiar with Storybook, would look something like this:

// Get all combinations
const options = {
  color: ['red', 'blue', 'green'],
  admin: [true, false],
  mode: ['light', 'dark'],
};
const combinations = combinate(options);

// Create main story section
const navbarStories = storiesOf('Navbar', module);

// Add a story for each combination
combinatons.forEach(({ color, admin, mode }) => {
  navbarStories.add(`${color} - ${admin} - ${mode}`, () => (
    <Navbar color={color} admin={admin} mode={mode} />
  ));
});

Conclusion

Hopefully this little utility saves you some time writing our different app state combinations for things like testing! Would love to hear what you think!

If you'd like to support this blog by buying me a coffee I'd really appreciate it!

Nick Scialli

Nick Scialli is a senior UI engineer at Microsoft.

© 2024 Nick Scialli