Generate All Possible Combinations in JavaScript Using Combinate
Nick Scialli
June 13, 2020
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!
Nick Scialli is a senior UI engineer at Microsoft.