|
1 | 1 | import test from 'node:test'; |
2 | 2 | import assert from 'node:assert/strict'; |
3 | 3 | import { parseArgs, usage } from '../args.ts'; |
| 4 | +import { AppError } from '../errors.ts'; |
| 5 | +import { getCliCommandNames } from '../command-schema.ts'; |
| 6 | +import { listCapabilityCommands } from '../../core/capabilities.ts'; |
4 | 7 |
|
5 | 8 | test('parseArgs recognizes --relaunch', () => { |
6 | 9 | const parsed = parseArgs(['open', 'settings', '--relaunch']); |
@@ -61,6 +64,71 @@ test('parseArgs rejects invalid swipe pattern', () => { |
61 | 64 |
|
62 | 65 | test('usage includes --relaunch flag', () => { |
63 | 66 | assert.match(usage(), /--relaunch/); |
| 67 | + assert.match(usage(), /pinch <scale> \[x\] \[y\]/); |
| 68 | + assert.match(usage(), /--metadata/); |
| 69 | +}); |
| 70 | + |
| 71 | +test('every capability command has a parser schema entry', () => { |
| 72 | + const schemaCommands = new Set(getCliCommandNames()); |
| 73 | + for (const command of listCapabilityCommands()) { |
| 74 | + assert.equal(schemaCommands.has(command), true, `Missing schema for command: ${command}`); |
| 75 | + } |
| 76 | +}); |
| 77 | + |
| 78 | +test('compat mode warns and strips unsupported pilot-command flags', () => { |
| 79 | + const parsed = parseArgs(['press', '10', '20', '--depth', '2'], { strictFlags: false }); |
| 80 | + assert.equal(parsed.command, 'press'); |
| 81 | + assert.equal(parsed.flags.snapshotDepth, undefined); |
| 82 | + assert.equal(parsed.warnings.length, 1); |
| 83 | + assert.match(parsed.warnings[0], /not supported for command press/); |
| 84 | +}); |
| 85 | + |
| 86 | +test('strict mode rejects unsupported pilot-command flags', () => { |
| 87 | + assert.throws( |
| 88 | + () => parseArgs(['press', '10', '20', '--depth', '2'], { strictFlags: true }), |
| 89 | + (error) => |
| 90 | + error instanceof AppError && |
| 91 | + error.code === 'INVALID_ARGS' && |
| 92 | + error.message.includes('not supported for command press'), |
| 93 | + ); |
| 94 | +}); |
| 95 | + |
| 96 | +test('snapshot command accepts command-specific flags', () => { |
| 97 | + const parsed = parseArgs(['snapshot', '-i', '-c', '--depth', '3', '-s', 'Login'], { strictFlags: true }); |
| 98 | + assert.equal(parsed.command, 'snapshot'); |
| 99 | + assert.equal(parsed.flags.snapshotInteractiveOnly, true); |
| 100 | + assert.equal(parsed.flags.snapshotCompact, true); |
| 101 | + assert.equal(parsed.flags.snapshotDepth, 3); |
| 102 | + assert.equal(parsed.flags.snapshotScope, 'Login'); |
| 103 | +}); |
| 104 | + |
| 105 | +test('unknown short flags are rejected', () => { |
| 106 | + assert.throws( |
| 107 | + () => parseArgs(['press', '10', '20', '-x'], { strictFlags: true }), |
| 108 | + (error) => error instanceof AppError && error.code === 'INVALID_ARGS' && error.message === 'Unknown flag: -x', |
| 109 | + ); |
| 110 | +}); |
| 111 | + |
| 112 | +test('all commands participate in strict command-flag validation', () => { |
| 113 | + assert.throws( |
| 114 | + () => parseArgs(['open', 'Settings', '--depth', '1'], { strictFlags: true }), |
| 115 | + (error) => |
| 116 | + error instanceof AppError && |
| 117 | + error.code === 'INVALID_ARGS' && |
| 118 | + error.message.includes('not supported for command open'), |
| 119 | + ); |
| 120 | +}); |
| 121 | + |
| 122 | +test('invalid enum/range errors are deterministic', () => { |
| 123 | + assert.throws( |
| 124 | + () => parseArgs(['snapshot', '--backend', 'foo'], { strictFlags: true }), |
| 125 | + (error) => |
| 126 | + error instanceof AppError && error.code === 'INVALID_ARGS' && error.message === 'Invalid backend: foo', |
| 127 | + ); |
| 128 | + assert.throws( |
| 129 | + () => parseArgs(['snapshot', '--depth', '-1'], { strictFlags: true }), |
| 130 | + (error) => error instanceof AppError && error.code === 'INVALID_ARGS' && error.message === 'Invalid depth: -1', |
| 131 | + ); |
64 | 132 | }); |
65 | 133 |
|
66 | 134 | test('usage includes swipe and press series options', () => { |
|
0 commit comments