|
1 | | -import { expect, test } from 'vitest' |
| 1 | +import { describe, expect, test } from 'vitest' |
2 | 2 | import { SCHEMA } from '@iroha2/data-model-schema' |
3 | | -import { generate, parseRawIdent } from './codegen' |
| 3 | +import { enumShortcuts, type EmitCode, generate, renderShortcutsTree } from './codegen' |
4 | 4 | import { QUERY_IMPLS } from '@iroha2/iroha-source' |
| 5 | +import { format } from 'prettier' |
| 6 | +import PRETTIER_OPTIONS from '../../../.prettierrc.js' |
| 7 | + |
| 8 | +/* TODO |
| 9 | +
|
| 10 | +- I manually re-arrange structs (for shortcuts, + maybe to avoid extra lazy stuff) |
| 11 | +- II fix core types |
| 12 | +- II more object.freeze |
| 13 | +- II think about never-enums. Just generate as never? (with a note that these are stubs) Or eliminate entirely from the schema/shortcuts tree? |
| 14 | +- III fix Action -> Executable -> Action recursion |
| 15 | +- III fix type -> interface |
| 16 | +- III codecFromPair()? |
| 17 | +- III Codec - differentiate input/output types? |
| 18 | +
|
| 19 | +*/ |
5 | 20 |
|
6 | 21 | // convenient for development in watch mode |
7 | 22 | // works almost as if JavaScript supported comptime codegen |
8 | 23 | test('codegen snapshot', async () => { |
9 | | - const code = generate(SCHEMA, QUERY_IMPLS, './generated-prelude') |
10 | | - expect(code).toMatchFileSnapshot('../src/datamodel/generated.ts') |
| 24 | + const code = generate(SCHEMA, QUERY_IMPLS, './generated-lib') |
| 25 | + const formatted = await format(code, { parser: 'typescript', ...PRETTIER_OPTIONS }) |
| 26 | + expect(formatted).toMatchFileSnapshot('../src/items/generated.ts') |
11 | 27 | }) |
12 | 28 |
|
13 | | -test('parse ident Vec<crate::role::Role>', () => { |
14 | | - expect(parseRawIdent('Vec<crate::role::Role>')).toMatchInlineSnapshot(` |
15 | | - { |
16 | | - "id": "Vec", |
17 | | - "items": [ |
18 | | - { |
19 | | - "id": "Role", |
20 | | - "items": [], |
21 | | - "path": [ |
22 | | - "crate", |
23 | | - "role", |
| 29 | +describe('enum shortcuts', () => { |
| 30 | + const SAMPLE = { |
| 31 | + A: { |
| 32 | + t: 'enum', |
| 33 | + variants: [ |
| 34 | + { tag: 'Unit', discriminant: 0, type: { t: 'null' } }, |
| 35 | + { tag: 'WithType', type: { t: 'local', id: 'Whichever' }, discriminant: 1 }, |
| 36 | + { tag: 'Nested', type: { t: 'local', id: 'B' }, discriminant: 2 }, |
| 37 | + ], |
| 38 | + }, |
| 39 | + B: { |
| 40 | + t: 'enum', |
| 41 | + variants: [ |
| 42 | + { tag: 'Bunit', discriminant: 0, type: { t: 'null' } }, |
| 43 | + { discriminant: 1, tag: 'Bnested', type: { t: 'local', id: 'C' } }, |
| 44 | + ], |
| 45 | + }, |
| 46 | + C: { |
| 47 | + t: 'enum', |
| 48 | + variants: [ |
| 49 | + { tag: 'CUnit', discriminant: 0, type: { t: 'null' } }, |
| 50 | + { discriminant: 1, tag: 'Cfinal', type: { t: 'local', id: 'Whichever' } }, |
| 51 | + ], |
| 52 | + }, |
| 53 | + Whichever: { t: 'alias', to: { t: 'lib', id: 'AccountId' } }, |
| 54 | + } satisfies Record<string, EmitCode> |
| 55 | + |
| 56 | + const SAMPLE_MAP = new Map(Object.entries(SAMPLE)) |
| 57 | + |
| 58 | + test('build shortcuts tree', () => { |
| 59 | + const tree = enumShortcuts(SAMPLE.A.variants, SAMPLE_MAP) |
| 60 | + |
| 61 | + expect(tree).toMatchInlineSnapshot(` |
| 62 | + [ |
| 63 | + { |
| 64 | + "name": "Unit", |
| 65 | + "t": "unit", |
| 66 | + }, |
| 67 | + { |
| 68 | + "name": "WithType", |
| 69 | + "t": "value", |
| 70 | + "value_ty": { |
| 71 | + "id": "Whichever", |
| 72 | + "t": "local", |
| 73 | + }, |
| 74 | + }, |
| 75 | + { |
| 76 | + "name": "Nested", |
| 77 | + "t": "enum", |
| 78 | + "tree": { |
| 79 | + "id": "B", |
| 80 | + "variants": [ |
| 81 | + { |
| 82 | + "name": "Bunit", |
| 83 | + "t": "unit", |
| 84 | + }, |
| 85 | + { |
| 86 | + "name": "Bnested", |
| 87 | + "t": "enum", |
| 88 | + "tree": { |
| 89 | + "id": "C", |
| 90 | + "variants": [ |
| 91 | + { |
| 92 | + "name": "CUnit", |
| 93 | + "t": "unit", |
| 94 | + }, |
| 95 | + { |
| 96 | + "name": "Cfinal", |
| 97 | + "t": "value", |
| 98 | + "value_ty": { |
| 99 | + "id": "Whichever", |
| 100 | + "t": "local", |
| 101 | + }, |
| 102 | + }, |
| 103 | + ], |
| 104 | + }, |
| 105 | + }, |
24 | 106 | ], |
25 | 107 | }, |
26 | | - ], |
27 | | - "path": undefined, |
28 | | - } |
| 108 | + }, |
| 109 | + ] |
29 | 110 | `) |
| 111 | + }) |
| 112 | + |
| 113 | + test('generate shortcut tree', () => { |
| 114 | + const generated = renderShortcutsTree({ id: 'A', variants: enumShortcuts(SAMPLE.A.variants, SAMPLE_MAP) }) |
| 115 | + |
| 116 | + expect(generated).toMatchInlineSnapshot( |
| 117 | + `"Unit: Object.freeze<A>({ kind: 'Unit' }), WithType: (value: Whichever): A => ({ kind: 'WithType', value }), Nested: { Bunit: Object.freeze<A>({ kind: 'Nested', value: B.Bunit }), Bnested: { CUnit: Object.freeze<A>({ kind: 'Nested', value: B.Bnested.CUnit }), Cfinal: (value: Whichever): A => ({ kind: 'Nested', value: B.Bnested.Cfinal(value) }) } }"`, |
| 118 | + ) |
| 119 | + }) |
30 | 120 | }) |
0 commit comments