|
1 | 1 | import {expectAssignable, expectError, expectType} from 'tsd'; |
2 | 2 | import type {PackageJson} from 'type-fest'; |
3 | | -import meow, {type Result} from '../source/index.js'; |
| 3 | +import meow from '../source/index.js'; |
4 | 4 |
|
5 | 5 | type AnyFlag = NonNullable<NonNullable<Parameters<typeof meow>[0]>['flags']>[string]; |
6 | 6 |
|
7 | 7 | const importMeta = import.meta; |
8 | 8 |
|
| 9 | +// Missing importMeta should error |
9 | 10 | expectError(meow('Help text')); |
10 | 11 | expectError(meow('Help text', {})); |
11 | | -expectType<Result<never>>(meow('Help text', {importMeta, hardRejection: false})); |
12 | | -expectAssignable<{flags: {foo: number}}>( |
13 | | - meow({importMeta: import.meta, flags: {foo: {type: 'number', isRequired: true}}}), |
14 | | -); |
15 | | -expectAssignable<{flags: {foo: string}}>( |
16 | | - meow({importMeta, flags: {foo: {type: 'string', isRequired: true}}}), |
17 | | -); |
18 | | -expectAssignable<{flags: {foo: boolean}}>( |
19 | | - meow({importMeta, flags: {foo: {type: 'boolean', isRequired: true}}}), |
20 | | -); |
21 | | -expectAssignable<{flags: {foo: number | undefined}}>( |
22 | | - meow({importMeta, flags: {foo: {type: 'number'}}}), |
23 | | -); |
24 | | -expectAssignable<{flags: {foo: string | undefined}}>( |
25 | | - meow({importMeta, flags: {foo: {type: 'string'}}}), |
26 | | -); |
27 | | -expectAssignable<{flags: {foo: boolean | undefined}}>( |
28 | | - meow({importMeta, flags: {foo: {type: 'boolean'}}}), |
29 | | -); |
30 | | -expectAssignable<{flags: {foo: number[] | undefined}}>( |
31 | | - meow({importMeta, flags: {foo: {type: 'number', isMultiple: true}}}), |
32 | | -); |
33 | | -expectAssignable<{flags: {foo: string[] | undefined}}>( |
34 | | - meow({importMeta, flags: {foo: {type: 'string', isMultiple: true}}}), |
35 | | -); |
36 | | -expectAssignable<{flags: {foo: boolean[] | undefined}}>( |
37 | | - meow({importMeta, flags: {foo: {type: 'boolean', isMultiple: true}}}), |
38 | | -); |
39 | | -expectType<Result<never>>(meow({importMeta, description: 'foo'})); |
40 | | -expectType<Result<never>>(meow({importMeta, description: false})); |
41 | | -expectType<Result<never>>(meow({importMeta, help: 'foo'})); |
42 | | -expectType<Result<never>>(meow({importMeta, help: false})); |
43 | | -expectType<Result<never>>(meow({importMeta, version: 'foo'})); |
44 | | -expectType<Result<never>>(meow({importMeta, autoHelp: false})); |
45 | | -expectType<Result<never>>(meow({importMeta, autoVersion: false})); |
46 | | -expectType<Result<never>>(meow({importMeta, pkg: {foo: 'bar'}})); |
47 | | -expectType<Result<never>>(meow({importMeta, argv: ['foo', 'bar']})); |
48 | | -expectType<Result<never>>(meow({importMeta, inferType: true})); |
49 | | -expectType<Result<never>>(meow({importMeta, booleanDefault: true})); |
50 | | -expectType<Result<never>>(meow({importMeta, booleanDefault: undefined})); |
51 | | -expectType<Result<never>>(meow({importMeta, hardRejection: false})); |
52 | 12 |
|
| 13 | +// Flag types |
| 14 | +expectAssignable<{flags: {foo: number}}>(meow({importMeta, flags: {foo: {type: 'number', isRequired: true}}})); |
| 15 | +expectAssignable<{flags: {foo: string | undefined}}>(meow({importMeta, flags: {foo: {type: 'string'}}})); |
| 16 | +expectAssignable<{flags: {foo: boolean[] | undefined}}>(meow({importMeta, flags: {foo: {type: 'boolean', isMultiple: true}}})); |
| 17 | + |
| 18 | +// Complete result test |
53 | 19 | const result = meow('Help text', { |
54 | 20 | importMeta, |
55 | 21 | flags: { |
56 | 22 | foo: {type: 'boolean', shortFlag: 'f'}, |
57 | | - 'foo-bar': {type: 'number', aliases: ['foobar', 'fooBar']}, |
| 23 | + 'foo-bar': {type: 'number', aliases: ['foobar']}, |
58 | 24 | bar: {type: 'string', default: ''}, |
59 | 25 | abc: {type: 'string', isMultiple: true}, |
60 | | - baz: {type: 'string', choices: ['rainbow', 'cat', 'unicorn']}, |
| 26 | + baz: {type: 'string', choices: ['rainbow', 'cat']}, |
61 | 27 | }, |
62 | 28 | }); |
63 | 29 |
|
64 | 30 | expectType<string[]>(result.input); |
65 | 31 | expectType<PackageJson>(result.pkg); |
66 | 32 | expectType<string>(result.help); |
67 | | - |
68 | 33 | expectType<boolean | undefined>(result.flags.foo); |
69 | 34 | expectType<number | undefined>(result.flags.fooBar); |
70 | 35 | expectType<string>(result.flags.bar); |
71 | 36 | expectType<string[] | undefined>(result.flags.abc); |
72 | 37 | expectType<string | undefined>(result.flags.baz); |
73 | | -expectType<boolean | undefined>(result.unnormalizedFlags.foo); |
74 | | -expectType<unknown>(result.unnormalizedFlags.f); |
75 | | -expectType<number | undefined>(result.unnormalizedFlags['foo-bar']); |
76 | | -expectType<unknown>(result.unnormalizedFlags.foobar); |
77 | | -expectType<unknown>(result.unnormalizedFlags.fooBar); |
78 | | -expectType<string>(result.unnormalizedFlags.bar); |
79 | | -expectType<string[] | undefined>(result.unnormalizedFlags.abc); |
80 | | -expectType<string | undefined>(result.unnormalizedFlags.baz); |
81 | 38 |
|
82 | 39 | result.showHelp(); |
83 | 40 | result.showHelp(1); |
84 | 41 | result.showVersion(); |
85 | 42 |
|
| 43 | +// Const assertion |
86 | 44 | const options = { |
87 | 45 | importMeta, |
88 | 46 | flags: { |
89 | | - rainbow: { |
90 | | - type: 'boolean', |
91 | | - shortFlag: 'r', |
92 | | - }, |
| 47 | + rainbow: {type: 'boolean', shortFlag: 'r'}, |
93 | 48 | }, |
94 | 49 | } as const; |
95 | 50 |
|
96 | 51 | meow('', options); |
97 | 52 |
|
| 53 | +// Flag validation - defaults |
98 | 54 | expectAssignable<AnyFlag>({type: 'string', default: 'cat'}); |
99 | 55 | expectAssignable<AnyFlag>({type: 'number', default: 42}); |
100 | | -expectAssignable<AnyFlag>({type: 'boolean', default: true}); |
101 | | - |
102 | | -expectAssignable<AnyFlag>({type: 'string', default: undefined}); |
103 | | -expectAssignable<AnyFlag>({type: 'number', default: undefined}); |
104 | | -expectAssignable<AnyFlag>({type: 'boolean', default: undefined}); |
105 | | - |
106 | 56 | expectAssignable<AnyFlag>({type: 'string', isMultiple: true, default: ['cat']}); |
107 | | -expectAssignable<AnyFlag>({type: 'number', isMultiple: true, default: [42]}); |
108 | | -expectAssignable<AnyFlag>({type: 'boolean', isMultiple: true, default: [false]}); |
109 | | - |
110 | 57 | expectError<AnyFlag>({type: 'string', isMultiple: true, default: 'cat'}); |
111 | | -expectError<AnyFlag>({type: 'number', isMultiple: true, default: 42}); |
112 | | -expectError<AnyFlag>({type: 'boolean', isMultiple: true, default: false}); |
113 | 58 |
|
| 59 | +// Flag validation - choices |
114 | 60 | expectAssignable<AnyFlag>({type: 'string', choices: ['cat', 'unicorn']}); |
115 | | -expectAssignable<AnyFlag>({type: 'number', choices: [1, 2]}); |
116 | | -expectAssignable<AnyFlag>({type: 'boolean', choices: [true, false]}); |
117 | | -expectAssignable<AnyFlag>({type: 'string', isMultiple: true, choices: ['cat']}); |
118 | | -expectAssignable<AnyFlag>({type: 'string', isMultiple: false, choices: ['cat']}); |
119 | | - |
| 61 | +expectAssignable<AnyFlag>({choices: ['cat']}); |
120 | 62 | expectError<AnyFlag>({type: 'string', choices: 'cat'}); |
121 | | -expectError<AnyFlag>({type: 'number', choices: 1}); |
122 | | -expectError<AnyFlag>({type: 'boolean', choices: true}); |
123 | | - |
124 | 63 | expectError<AnyFlag>({type: 'string', choices: [1]}); |
125 | | -expectError<AnyFlag>({type: 'number', choices: ['cat']}); |
126 | | -expectError<AnyFlag>({type: 'boolean', choices: ['cat']}); |
127 | | - |
128 | | -expectAssignable<AnyFlag>({choices: ['cat']}); |
129 | | -expectAssignable<AnyFlag>({choices: [1]}); |
130 | | -expectAssignable<AnyFlag>({choices: [true]}); |
131 | 64 | expectError<AnyFlag>({choices: ['cat', 1, true]}); |
0 commit comments