summaryrefslogtreecommitdiff
path: root/tests/type-consistency/harness.ts
blob: a08e39775a1cf834a4692d1d6165ee197e10770f (plain)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import fs from "fs/promises";
import path from "path";

const convertName = (name: string) => name.replace(" ", "-").toLowerCase();

export const createTestHarness = ({
  harnessName,
  generatedPath,
}: {
  harnessName: string;
  generatedPath: string;
}) => {
  const tests: string[] = [];

  return {
    async writeTests() {
      const file = `import { evaluateProgram, createFn } from "../../../src";
import { describe, expect, expectTypeOf, test } from "vitest";

describe(\`${harnessName}\`, () => {
      ${tests.join("\n")}
    });`;

      await fs.mkdir(generatedPath, { recursive: true });

      await fs.writeFile(
        path.join(generatedPath, `${convertName(harnessName)}.test.ts`),
        file,
        "utf-8"
      );

      console.log(`Wrote ${tests.length} test(s) for "${harnessName}"!`);
    },

    createProgramTest({
      name,
      program,
      expected,
    }: {
      name: string;
      program: string;
      expected: any;
    }) {
      tests.push(`test(\`${name}\`, () => {
    const PROGRAM = \`${program}\` as const;
    const expected: ${JSON.stringify(expected)} = ${JSON.stringify(expected)};
    const result = evaluateProgram(PROGRAM);

    expect(result).toStrictEqual(expected);
    expectTypeOf<typeof result>().toEqualTypeOf<typeof expected>();
      });`);

      return this;
    },

    createFunctionTest({
      name,
      program,
      cases,
    }: {
      name: string;
      program: string;
      cases: Array<{ input: any; output: any }>;
    }) {
      tests.push(`describe(\`${name}\`, () => {
    const PROGRAM = \`${program}\` as const;
    ${cases.map(
      ({ input, output }) => `test(\`${JSON.stringify(
        input
      )} -> ${JSON.stringify(output)}\`, () => {
    const input: ${JSON.stringify(input)} = ${JSON.stringify(input)};
    const expected: ${JSON.stringify(output)} = ${JSON.stringify(output)};
    const fn = createFn()(PROGRAM)
    const result = fn(input)

    expect(result).toStrictEqual(expected);
    expectTypeOf<typeof result>().toEqualTypeOf<typeof expected>();
      })
      `
    )}});`);

      return this;
    },
  };
};