Repository navigation
Expand file tree
/
Copy pathnaming.test.ts
More file actions
65 lines (57 loc) · 2.57 KB
/
Copy pathnaming.test.ts
File metadata and controls
65 lines (57 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { describe, expect, it } from 'vitest'
import { CLI_CONTRACT } from '../contract/commands'
import type { CommandSpec } from '../contract/types'
import { V2_OPERATIONS, type V2OperationName } from '../generated/v2-api'
import { formatApiErrorDetails, SimApiError } from '../http/client'
import { retypeApiError } from './naming'
import type { OperationSpec } from './types'
function retype(operation: V2OperationName, error: unknown): SimApiError {
return retypeApiError(
error,
operation,
(CLI_CONTRACT[operation] ?? {}) as CommandSpec,
V2_OPERATIONS[operation] as unknown as OperationSpec
) as SimApiError
}
function detailLines(operation: V2OperationName, details: unknown): string[] {
return formatApiErrorDetails(
retype(operation, new SimApiError('Invalid request', 400, 'BAD_REQUEST', details)).details
)
}
/**
* The server names its own fields, which is right for an OpenAPI reader and
* untypeable in a terminal: `drop includeJobRuns` names no flag the CLI has.
*/
describe('a validation error restated in the spellings a caller can type', () => {
it('names the flag in both the message and the details', () => {
const message =
'sortBy: only "startedAt" can order job runs; drop includeJobRuns or sort by "startedAt"'
const error = new SimApiError(message, 400, 'BAD_REQUEST', [{ path: ['sortBy'], message }])
const retyped = retype('listLogs', error)
expect(retyped.message).toContain('drop --include-job-runs')
expect(retyped.message).toContain('--sort-by')
expect(retyped.message).not.toMatch(/\bincludeJobRuns\b/)
expect(detailLines('listLogs', error)[1]).toContain('--sort-by')
})
/**
* The requirement that a mechanical kebab-casing fails: the flag for
* `folderPath` is `--folder`, so translating the wire name by rule would
* print a flag that does not exist.
*/
it('resolves the spelling through the contract, not by kebab-casing', () => {
const line = detailLines('listWorkflows', [
{ path: ['folderPath'], message: 'Path must be a canonical folder path' },
])[1]
expect(line).toContain('--folder:')
expect(line).not.toContain('--folder-path')
expect(line).not.toContain('folderPath')
})
it('leaves a CLI-raised error and a non-API throw byte-identical', () => {
const local = new SimApiError('--limit must be a whole number of 0 or more', 0)
expect(retype('listLogs', local)).toBe(local)
const other = new Error('sortBy is not a flag')
expect(
retypeApiError(other, 'listLogs', {}, V2_OPERATIONS.listLogs as unknown as OperationSpec)
).toBe(other)
})
})