storybook/scripts/utils/options.test.ts

192 lines
5.1 KiB
TypeScript
Raw Normal View History

import { createCommand } from 'commander';
2022-07-27 20:13:36 +10:00
import { describe, it, expect } from '@jest/globals';
import { createOptions, getOptions, areOptionsSatisfied, getCommand } from './options';
import type { OptionValues, MaybeOptionValues } from './options';
const allOptions = createOptions({
first: {
type: 'boolean',
description: 'first',
},
second: {
type: 'boolean',
description: 'second',
2022-07-25 16:21:49 +10:00
inverse: true,
},
third: {
type: 'string',
description: 'third',
values: ['one', 'two', 'three'] as const,
required: true as const,
},
fourth: {
type: 'string',
description: 'fourth',
},
fifth: {
type: 'string[]',
description: 'fifth',
values: ['a', 'b', 'c'] as const,
},
sixth: {
type: 'string[]',
description: 'sixth',
},
});
2022-07-27 20:13:36 +10:00
// TS "tests"
2022-07-28 19:46:40 +10:00
// deepscan-disable-next-line
2022-07-27 20:13:36 +10:00
function test(mv: MaybeOptionValues<typeof allOptions>, v: OptionValues<typeof allOptions>) {
console.log(mv.first, mv.second, mv.third, mv.fourth, mv.fifth, mv.sixth);
2022-07-28 19:46:40 +10:00
// @ts-expect-error as it's not allowed
console.log(mv.seventh);
console.log(v.first, v.second, v.third, v.fourth, v.fifth, v.sixth);
2022-07-28 19:46:40 +10:00
// @ts-expect-error as it's not allowed
console.log(v.seventh);
2022-07-27 20:13:36 +10:00
}
describe('getOptions', () => {
it('deals with boolean options', () => {
expect(getOptions(createCommand(), allOptions, ['command', 'name', '--first'])).toMatchObject({
first: true,
2022-07-25 16:21:49 +10:00
second: true,
});
});
it('deals with inverse boolean options', () => {
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--no-second'])
2022-07-25 16:21:49 +10:00
).toMatchObject({
2022-07-25 16:29:14 +10:00
first: false,
2022-07-25 16:21:49 +10:00
second: false,
});
});
it('deals with short options', () => {
expect(getOptions(createCommand(), allOptions, ['command', 'name', '-f', '-S'])).toMatchObject({
2022-07-25 16:21:49 +10:00
first: true,
second: false,
});
});
it('deals with string options', () => {
const r = getOptions(createCommand(), allOptions, ['command', 'name', '--third', 'one']);
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--third', 'one'])
).toMatchObject({
third: 'one',
});
});
2022-07-25 16:29:14 +10:00
it('disallows invalid string options', () => {
expect(() =>
getOptions(createCommand(), allOptions, ['command', 'name', '--third', 'random'])
2022-07-27 20:13:36 +10:00
).toThrow(/Unexpected value/);
2022-07-25 16:29:14 +10:00
});
2022-08-08 10:34:39 +10:00
it('allows arbitrary string options when values are not specified', () => {
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--fourth', 'random'])
).toMatchObject({
fourth: 'random',
});
});
it('deals with multiple string options', () => {
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--fifth', 'a'])
).toMatchObject({
fifth: ['a'],
});
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--fifth', 'a', '--fifth', 'b'])
).toMatchObject({
fifth: ['a', 'b'],
});
});
2022-07-25 16:29:14 +10:00
it('disallows invalid multiple string options', () => {
expect(() =>
getOptions(createCommand(), allOptions, ['command', 'name', '--fifth', 'random'])
2022-07-27 20:13:36 +10:00
).toThrow(/Unexpected value/);
2022-07-25 16:29:14 +10:00
});
2022-08-08 10:34:39 +10:00
it('allows arbitrary multiple string options when values are not specified', () => {
expect(
getOptions(createCommand(), allOptions, ['command', 'name', '--sixth', 'random'])
).toMatchObject({
sixth: ['random'],
});
});
});
describe('areOptionsSatisfied', () => {
it('checks each required string option has a value', () => {
2022-07-27 20:13:36 +10:00
expect(
areOptionsSatisfied(allOptions, {
first: true,
second: true,
third: undefined,
fourth: undefined,
fifth: ['a', 'c'],
sixth: [],
2022-07-27 20:13:36 +10:00
})
).toBe(false);
expect(
areOptionsSatisfied(allOptions, {
first: true,
second: true,
third: 'one',
fourth: undefined,
fifth: [],
sixth: [],
2022-07-27 20:13:36 +10:00
})
).toBe(true);
});
});
describe('getCommand', () => {
const { first, second, third, fifth } = allOptions;
it('works with boolean options', () => {
2022-07-27 20:13:36 +10:00
expect(getCommand('node foo', { first, second }, { first: true, second: true })).toBe(
'node foo --first'
);
});
2022-07-25 16:21:49 +10:00
it('works with inverse boolean options', () => {
2022-07-27 20:13:36 +10:00
expect(getCommand('node foo', { first, second }, { first: false, second: false })).toBe(
2022-07-25 16:21:49 +10:00
'node foo --no-second'
);
});
it('works with string options', () => {
2022-07-27 20:13:36 +10:00
expect(getCommand('node foo', { third }, { third: 'one' })).toBe('node foo --third one');
});
it('works with multiple string options', () => {
expect(getCommand('node foo', { fifth }, { fifth: ['a', 'b'] })).toBe(
'node foo --fifth a --fifth b'
);
});
2022-07-27 22:17:39 +10:00
// This is for convenience
it('works with partial options', () => {
expect(getCommand('node foo', allOptions, { third: 'one' })).toBe(
'node foo --no-second --third one'
);
});
it('works with combinations string options', () => {
expect(
getCommand('node foo', allOptions, {
first: true,
second: false,
2022-07-27 20:13:36 +10:00
third: 'one',
fifth: ['a', 'b'],
})
).toBe('node foo --first --no-second --third one --fifth a --fifth b');
});
});