From 9d48261da01d28d863b31eb794ff6316f65b563d Mon Sep 17 00:00:00 2001 From: jared Date: Fri, 26 Jan 2024 01:15:49 -0700 Subject: [PATCH 01/14] Added golden tests prelude for TS --- testsuites/lbt-prelude/api/build.nix | 5 + testsuites/lbt-prelude/golden/build.nix | 7 + .../lbt-prelude-typescript/.gitignore | 2 + .../lbt-prelude-typescript/build.nix | 32 +++ .../lbt-prelude-typescript/package-lock.json | 136 +++++++++ .../lbt-prelude-typescript/package.json | 29 ++ .../lbt-prelude-typescript/src/Goldens.ts | 257 ++++++++++++++++++ .../lbt-prelude-typescript/src/Json-test.ts | 256 +++++++++++++++++ .../lbt-prelude-typescript/src/index.mts | 61 +++++ .../lbt-prelude-typescript/src/tsconfig.json | 5 + .../lbt-prelude-typescript/tsconfig-base.json | 109 ++++++++ 11 files changed, 899 insertions(+) create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/build.nix create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/package.json create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/src/Goldens.ts create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/src/tsconfig.json create mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/tsconfig-base.json diff --git a/testsuites/lbt-prelude/api/build.nix b/testsuites/lbt-prelude/api/build.nix index a011e6da..552081db 100644 --- a/testsuites/lbt-prelude/api/build.nix +++ b/testsuites/lbt-prelude/api/build.nix @@ -20,6 +20,11 @@ _: { files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; }; + lbf-prelude-golden-api-typescript = config.lbf-nix.lbfTypescript { + name = "lbf-prelude-golden-api"; + src = ./.; + files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; + }; }; }; } diff --git a/testsuites/lbt-prelude/golden/build.nix b/testsuites/lbt-prelude/golden/build.nix index e06d95ed..d0dc11d5 100644 --- a/testsuites/lbt-prelude/golden/build.nix +++ b/testsuites/lbt-prelude/golden/build.nix @@ -24,6 +24,13 @@ _: phases = "installPhase"; installPhase = "ln -s $src $out"; }; + + lbt-prelude-golden-typescript = pkgs.stdenv.mkDerivation { + name = "lbt-prelude-golden-data"; + src = ./.; + phases = "installPhase"; + installPhase = ''ln -s "$src" "$out"''; + }; }; }; diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore new file mode 100644 index 00000000..5f873d7c --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore @@ -0,0 +1,2 @@ +extra-dependencies/ +data/ diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix new file mode 100644 index 00000000..5ff63114 --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix @@ -0,0 +1,32 @@ +{ inputs, ... }: +{ + perSystem = { config, system, ... }: + let + tsFlake = + inputs.flake-lang.lib.${system}.typescriptFlake { + name = "lbt-prelude"; + src = ./.; + npmExtraDependencies = [ + config.packages.lbf-prelude-golden-api-typescript + ]; + + devShellTools = config.settings.shell.tools; + devShellHook = config.settings.shell.hook; + + data = + [ + { + name = "lbt-prelude-golden-data"; + path = config.packages.lbt-prelude-golden-typescript; + } + ]; + }; + in + { + packages = { + inherit (tsFlake.packages) lbt-prelude-typescript lbt-prelude-typescript-tgz; + }; + + inherit (tsFlake) devShells checks; + }; +} diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json new file mode 100644 index 00000000..914db3fd --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json @@ -0,0 +1,136 @@ +{ + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbf-prelude-golden-api": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + }, + "devDependencies": { + "@types/node": "^20.11.7", + "typescript": "^5.3.3" + } + }, + "node_modules/@types/node": { + "version": "20.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.7.tgz", + "integrity": "sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/lbf-prelude": { + "version": "1.0.0", + "resolved": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-XLxQoeX/LBPAHSnzF7LcUBOfMziugGvVMYiC1tdKQXfmv4fxaHQK9H5nTCNVNuRS/yu6xAhmoBQCI8EUBdRBPg==", + "dependencies": { + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbf-prelude-golden-api": { + "version": "1.0.0", + "resolved": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "integrity": "sha512-nCPzAphuHWkS9ltUXDCVkMBKYdUt0594IqlGiXK7mbGxpuRTVli8gve6KAsQmcXUnaDEKiDrhFrnTKReaBVmFQ==", + "dependencies": { + "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbr-prelude": { + "version": "1.0.0", + "resolved": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-3desaAg+xjFL1GMr5rdze2g/e91P5qamIflDO21KxWwKRBvca0C0oSuc/vXaR5SXGK+GG5x2SY2Z8tLJgp6dwg==", + "license": "ISC", + "dependencies": { + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz", + "typescript": "^5.3.3" + } + }, + "node_modules/prelude": { + "version": "1.0.1", + "resolved": "file:extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==", + "license": "ISC" + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + }, + "dependencies": { + "@types/node": { + "version": "20.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.7.tgz", + "integrity": "sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "lbf-prelude": { + "version": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-XLxQoeX/LBPAHSnzF7LcUBOfMziugGvVMYiC1tdKQXfmv4fxaHQK9H5nTCNVNuRS/yu6xAhmoBQCI8EUBdRBPg==", + "requires": { + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbf-prelude-golden-api": { + "version": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "integrity": "sha512-nCPzAphuHWkS9ltUXDCVkMBKYdUt0594IqlGiXK7mbGxpuRTVli8gve6KAsQmcXUnaDEKiDrhFrnTKReaBVmFQ==", + "requires": { + "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbr-prelude": { + "version": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-3desaAg+xjFL1GMr5rdze2g/e91P5qamIflDO21KxWwKRBvca0C0oSuc/vXaR5SXGK+GG5x2SY2Z8tLJgp6dwg==", + "requires": { + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz", + "typescript": "^5.3.3" + } + }, + "prelude": { + "version": "file:extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==" + }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + } +} diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json new file mode 100644 index 00000000..8a38bf9c --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json @@ -0,0 +1,29 @@ +{ + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "description": "Test suite project for LambdaBuffers", + "type": "module", + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + }, + "scripts": { + "build": "npx tsc -b src/", + "test": "node --test" + }, + "author": "Jared Pon", + "license": "ISC", + "files": [ + "./dist/**/*" + ], + "devDependencies": { + "@types/node": "^20.11.7", + "typescript": "^5.3.3" + }, + "dependencies": { + "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbf-prelude-golden-api": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + } +} diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Goldens.ts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Goldens.ts new file mode 100644 index 00000000..dbb13da4 --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Goldens.ts @@ -0,0 +1,257 @@ +import * as LbrPrelude from "lbr-prelude"; +import * as PreludeSet from "prelude/Set.js"; +import * as PreludeMap from "prelude/Map.js"; +import * as Prelude from "prelude"; +import * as LbfFoo from "lbf-prelude-golden-api/LambdaBuffers/Foo.mjs"; +import * as LbfFooBar from "lbf-prelude-golden-api/LambdaBuffers/Foo/Bar.mjs"; +import * as LbfDays from "lbf-prelude-golden-api/LambdaBuffers/Days.mjs"; + +/** + * Returns some hardcoded bytes for testing. + */ +export function someBytes(): LbrPrelude.Bytes { + return Uint8Array.from([115, 111, 109, 101, 32, 98, 121, 116, 101, 115]); +} + +/** + * Returns an array of some hardcoded tests of the {@link Foo} type + */ +export function fooSumGoldens( + x: A, + y: B, + z: C, +): LbfFooBar.FooSum[] { + return [ + { name: "Foo", fields: [x, y, z] }, + { name: "Bar", fields: [x, y] }, + { name: "Baz", fields: y }, + { name: "Qax" }, + { name: "Faz", fields: 0n }, + ]; +} + +/** + * Returns a hardcoded unit test of the {@link A} type + */ +export function aGoldens(): LbfFoo.A[] { + return fooSumGoldens(1337n, false, someBytes()); +} + +/** + * Returns a hardcoded unit test of the {@link FooProd} type + */ +export function fooProdGoldens( + x: A, + y: B, + z: C, +): LbfFooBar.FooProd[] { + return [[x, y, z, 1337n]]; +} + +/** + * Returns a hardcoded unit test of some {@link B} type + */ +export function bGoldens(): LbfFoo.B[] { + return fooProdGoldens(1337n, false, someBytes()); +} + +/** + * A hardcoded unit test of some {@link FooRec} type + */ +export function fooRecGoldens( + x: A, + y: B, + z: C, +): LbfFooBar.FooRec[] { + return [ + { fooA: x, fooB: y, fooC: z, fooInt: 1337n }, + ]; +} + +/** + * A hardcoded unit test of some {@link C} type + */ +export function cGoldens(): LbfFoo.C[] { + return fooRecGoldens(1337n, false, someBytes()); +} + +/** + * A hardcoded unit test of some {@link D} type + */ +export function dGoldens(): LbfFoo.D[] { + const result: LbfFoo.D[] = []; + for (const fooSum of fooSumGoldens(1337n, false, someBytes())) { + for (const fooProd of fooProdGoldens(1337n, false, someBytes())) { + for (const fooRec of fooRecGoldens(1337n, false, someBytes())) { + result.push( + { sum: fooSum, prod: fooProd, rec: fooRec }, + ); + } + } + } + return result; +} + +/** + * A hardcoded unit test of a {@link FInt} type + */ +export function fIntGoldens(): LbfFoo.FInt[] { + return [ + { name: "Nil" }, + { name: "Rec", fields: { name: "Rec", fields: { name: "Nil" } } }, + ]; +} + +/** + * A hardcoded unit test of a {@link GInt} type + */ +export function gIntGoldens(): LbfFoo.GInt[] { + return [ + { name: "Nil" }, + { name: "Rec", fields: { name: "Rec", fields: { name: "Nil" } } }, + ]; +} + +/** + * A hardcoded unit test of some {@link Day} type + */ +export function dayGoldens(): LbfDays.Day[] { + return [ + { name: "Monday" }, + { name: "Tuesday" }, + { name: "Wednesday" }, + { name: "Thursday" }, + { name: "Friday" }, + { name: "Saturday" }, + { name: "Sunday" }, + ]; +} + +/** + * A hardcoded unit test of some {@link WorkDay} type + */ +export function workDayGoldens(): LbfDays.WorkDay[] { + return [{ name: "Monday" }, { name: "Tuesday" }, { name: "Wednesday" }, { + name: "Thursday", + }, { name: "Friday" }]; +} + +/** + * A hardcoded unit test of some {@link FreeDay} type + */ +export function freeDayGoldens(): LbfDays.FreeDay[] { + return [{ day: { name: "Saturday" } }, { day: { name: "Sunday" } }]; +} + +/** + * A hardcoded unit test of some {@link Bool} type + */ +export function boolGoldens(): LbrPrelude.Bool[] { + return [true, false]; +} + +/** + * A hardcoded unit test of some {@link Integer} type + */ +export function integerGoldens(): LbrPrelude.Integer[] { + return [ + 0n, + 1n, + -1n, + 2n ** 32n, + -(2n ** 32n), + 2n ** (64n), + -(2n ** (64n)), + 2n ** (128n), + -(2n ** (128n)), + 2n ** (256n), + -(2n ** (256n)), + ]; +} + +/** + * A hardcoded unit test of some {@link Bytes} types + */ +export function bytesGoldens(): LbrPrelude.Bytes[] { + return [Uint8Array.from([]), Uint8Array.from([0]), someBytes()]; +} + +/** + * A hardcoded unit test of some {@link Char} types + */ +export function charGoldens(): LbrPrelude.Char[] { + return ["\u{0}", "\u{A}", "\u{1f643}"] as LbrPrelude.Char[]; +} + +/** + * A hardcoded unit test of some {@link Text} types + */ +export function textGoldens(): LbrPrelude.Text[] { + return ["", "\n", "dražen popović"]; +} + +/** + * A hardcoded unit test of some {@link Maybe} types + */ +export function maybeGoldens(): LbrPrelude.Maybe[] { + return [{ name: "Nothing" }, { name: "Just", fields: true }, { + name: "Just", + fields: false, + }]; +} + +/** + * A hardcoded unit test of some {@link Either} types + */ +export function eitherGoldens(): LbrPrelude.Either< + LbrPrelude.Bool, + LbrPrelude.Text +>[] { + return [{ name: "Left", fields: true }, { name: "Left", fields: false }, { + name: "Right", + fields: "this is right", + }]; +} + +/** + * A hardcoded unit test of some {@link List} types + */ +export function listGoldens(): LbrPrelude.List[] { + return [[], [true], [false], [true, true, false, false]]; +} + +/** + * A hardcoded unit test of some {@link Set} types + */ +export function setGoldens(): LbrPrelude.Set[] { + const set1: PreludeSet.Set = new PreludeSet.Set(); + const set2: PreludeSet.Set = new PreludeSet.Set(); + PreludeSet.insert(Prelude.ordBool, true, set2); + + const set3: PreludeSet.Set = new PreludeSet.Set(); + PreludeSet.insert(Prelude.ordBool, true, set3); + PreludeSet.insert(Prelude.ordBool, false, set3); + + return [set1, set2, set3]; +} + +/** + * A hardcoded unit test of some {@link Map} types + */ +export function mapGoldens(): LbrPrelude.Map< + LbrPrelude.Bool, + LbrPrelude.Bool +>[] { + const map1: PreludeMap.Map = new PreludeMap + .Map(); + const map2: PreludeMap.Map = new PreludeMap + .Map(); + PreludeMap.insert(Prelude.ordBool, true, true, map2); + + const map3: PreludeMap.Map = new PreludeMap + .Map(); + PreludeMap.insert(Prelude.ordBool, true, true, map3); + PreludeMap.insert(Prelude.ordBool, false, false, map3); + + return [map1, map2, map3]; +} diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts new file mode 100644 index 00000000..0f1c9e14 --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts @@ -0,0 +1,256 @@ +// Unit tests for functionality in `src/Prelude/Runtime/Json.ts` +import { describe, it } from "node:test"; +import * as assert from "node:assert/strict"; +import * as Goldens from "./Goldens.js"; +import * as Fs from "node:fs/promises"; +import * as Path from "node:path"; +import * as Prelude from "prelude"; +import * as PreludeJson from "prelude/Json.js"; + +import * as LbfFoo from "lbf-prelude-golden-api/LambdaBuffers/Foo.mjs"; +// import * as LbfFooBar from "lbf-prelude-golden-api/LambdaBuffers/Foo/Bar.mjs" +import * as LbfDays from "lbf-prelude-golden-api/LambdaBuffers/Days.mjs"; + +import * as LbrPrelude from "lbr-prelude"; + +export async function findGoldens( + goldenDir: string, + title: string, +): Promise<[string, string][]> { + const files: string[] = await Fs.readdir(goldenDir, { recursive: true }); + + const filteredFiles: [string, string][] = []; + for (const file of files) { + if ( + // `title` is a prefix of `file`'s basename + Path.basename(file).startsWith(title) && + // AND it ends with `.json` + Path.extname(file) === ".json" + ) { + filteredFiles.push( + [Path.join(goldenDir, file), Path.basename(file, ".json")], + ); + } + } + return filteredFiles; +} + +export async function fromToGoldenTest( + jsonDict: Prelude.Json, + goldenDir: string, + title: string, + goldens: A[], +): Promise { + const foundGoldens: [string, string][] = await findGoldens(goldenDir, title); + + if (foundGoldens.length !== goldens.length) { + assert.fail( + `Expected to find ${goldens.length} .json golden files for ${title}, but got ${foundGoldens.length}. Forgot to (re)generate the goldens?`, + ); + } + + for (const [filepath, index] of foundGoldens) { + const contents = await Fs.readFile(filepath, { encoding: "utf8" }); + + const fromToJson = PreludeJson.stringify( + jsonDict.toJson( + jsonDict.fromJson( + PreludeJson.parseJson(contents), + ), + ), + ); + + // TODO(jaredponn). This fails on the _first_ test instead of + // accumulating all of them.. Perhaps we want to accumulate all of + // them by e.g. wrapping this with `it`. + if (contents !== fromToJson) { + assert.fail( + `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromToJson}\``, + ); + } + } +} + +describe("JSON tests", () => { + const goldenDir = `data/lbt-prelude-golden-data`; + it(`Foo.A from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.A], + goldenDir, + `Foo.A`, + Goldens.aGoldens(), + ); + }); + + it(`Foo.B from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.B], + goldenDir, + `Foo.B`, + Goldens.bGoldens(), + ); + }); + + it(`Foo.C from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.C], + goldenDir, + `Foo.C`, + Goldens.cGoldens(), + ); + }); + + it(`Foo.D from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.D], + goldenDir, + `Foo.D`, + Goldens.dGoldens(), + ); + }); + + it(`Foo.FInt from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.FInt], + goldenDir, + `Foo.FInt`, + Goldens.fIntGoldens(), + ); + }); + + it(`Foo.GInt from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfFoo.GInt], + goldenDir, + `Foo.GInt`, + Goldens.gIntGoldens(), + ); + }); + + it(`Days.Day from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfDays.Day], + goldenDir, + `Days.Day`, + Goldens.dayGoldens(), + ); + }); + + it(`Days.WorkDay from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfDays.WorkDay], + goldenDir, + `Days.WorkDay`, + Goldens.workDayGoldens(), + ); + }); + + it(`Days.FreeDay from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbfDays.FreeDay], + goldenDir, + `Days.FreeDay`, + Goldens.freeDayGoldens(), + ); + }); + + it(`Prelude.Bool from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Bool], + goldenDir, + `Prelude.Bool`, + Goldens.boolGoldens(), + ); + }); + + it(`Prelude.Char from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Char], + goldenDir, + `Prelude.Char`, + Goldens.charGoldens(), + ); + }); + + it(`Prelude.Integer from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Integer], + goldenDir, + `Prelude.Integer`, + Goldens.integerGoldens(), + ); + }); + + it(`Prelude.Text from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Text], + goldenDir, + `Prelude.Text`, + Goldens.textGoldens(), + ); + }); + + it(`Prelude.Bytes from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Bytes], + goldenDir, + `Prelude.Bytes`, + Goldens.bytesGoldens(), + ); + }); + + it(`Prelude.Maybe from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Maybe](LbrPrelude.Json[LbrPrelude.Bool]), + goldenDir, + `Prelude.Maybe`, + Goldens.maybeGoldens(), + ); + }); + + it(`Prelude.Either from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Either]( + LbrPrelude.Json[LbrPrelude.Bool], + LbrPrelude.Json[LbrPrelude.Text], + ), + goldenDir, + `Prelude.Either`, + Goldens.eitherGoldens(), + ); + }); + + it(`Prelude.List from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.List](LbrPrelude.Json[LbrPrelude.Bool]), + goldenDir, + `Prelude.List`, + Goldens.listGoldens(), + ); + }); + + it(`Prelude.Set from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Set]( + Prelude.ordBool, + LbrPrelude.Json[LbrPrelude.Bool], + ), + goldenDir, + `Prelude.Set`, + Goldens.setGoldens(), + ); + }); + + it(`Prelude.Map from to golden tests`, async () => { + await fromToGoldenTest( + LbrPrelude.Json[LbrPrelude.Map]( + Prelude.ordBool, + LbrPrelude.Json[LbrPrelude.Bool], + LbrPrelude.Json[LbrPrelude.Bool], + ), + goldenDir, + `Prelude.Map`, + Goldens.mapGoldens(), + ); + }); +}); diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts new file mode 100644 index 00000000..ce1e56ca --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts @@ -0,0 +1,61 @@ +// Simple prelude sample project. +// To run, type +// ``` +// npm run build && node ./dist/src/index.mjs +// ``` +// import * as Prelude from "prelude"; +// import * as PreludeJson from "prelude/Json.js"; +// import * as LbrPrelude from "lbr-prelude"; +// import * as MySchema from "lbf-prelude-sample-project/LambdaBuffers/MySchema.mjs"; +// +// const a: MySchema.Branchy = { +// name: "Node", +// fields: [420n, [{ name: "Leaf", fields: true }, { +// name: "Leaf", +// fields: false, +// }]], +// }; +// const b: MySchema.Branchy = { name: "Leaf", fields: false }; +// +// a; +// +// console.log("a == a"); +// console.log( +// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).eq(a, a), +// ); +// console.log("a == b"); +// console.log( +// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).eq(a, b), +// ); +// +// console.log("a != a"); +// console.log( +// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).neq(a, a), +// ); +// console.log("a != b"); +// console.log( +// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).neq(a, b), +// ); +// +// console.log("toJson(a)"); +// console.log( +// PreludeJson.stringify( +// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) +// .toJson(a), +// ), +// ); +// +// console.log("fromJson(toJson(a))"); +// console.log( +// JSON.stringify( +// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) +// .fromJson( +// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) +// .toJson(a), +// ), +// (_key, value) => { +// if (typeof value === "bigint") return (value.toString()); +// else return value; +// }, +// ), +// ); diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/tsconfig.json b/testsuites/lbt-prelude/lbt-prelude-typescript/src/tsconfig.json new file mode 100644 index 00000000..fcab6f23 --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../tsconfig-base", + "include": ["*"], + "references": [ ] +} diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/tsconfig-base.json b/testsuites/lbt-prelude/lbt-prelude-typescript/tsconfig-base.json new file mode 100644 index 00000000..56c4c468 --- /dev/null +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/tsconfig-base.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "node16", /* Specify what module code is generated. */ + "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + /// "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 3910de15760f967cde2ef99d464b0332f141ee1e Mon Sep 17 00:00:00 2001 From: jared Date: Fri, 26 Jan 2024 01:20:38 -0700 Subject: [PATCH 02/14] Basic nix derivations + update flake for Typescript flake --- flake.nix | 3 ++- testsuites/lbt-prelude/api/build.nix | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 2b970e4e..b2f196f4 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ nixpkgs.url = "github:NixOS/nixpkgs"; # flake-lang.nix - flake-lang.url = "github:mlabs-haskell/flake-lang.nix"; + flake-lang.url = "github:mlabs-haskell/flake-lang.nix/jared/add-data-to-typescript-flake"; # Haskell @@ -88,6 +88,7 @@ ./testsuites/lbt-prelude/lbt-prelude-haskell/build.nix ./testsuites/lbt-prelude/lbt-prelude-purescript/build.nix ./testsuites/lbt-prelude/lbt-prelude-rust/build.nix + ./testsuites/lbt-prelude/lbt-prelude-typescript/build.nix ./testsuites/lbt-plutus/api/build.nix ./testsuites/lbt-plutus/golden/build.nix ./testsuites/lbt-plutus/lbt-plutus-haskell/build.nix diff --git a/testsuites/lbt-prelude/api/build.nix b/testsuites/lbt-prelude/api/build.nix index 552081db..670e2d12 100644 --- a/testsuites/lbt-prelude/api/build.nix +++ b/testsuites/lbt-prelude/api/build.nix @@ -20,11 +20,11 @@ _: { files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; }; - lbf-prelude-golden-api-typescript = config.lbf-nix.lbfTypescript { + lbf-prelude-golden-api-typescript = (config.lbf-nix.lbfPreludeTypescript { name = "lbf-prelude-golden-api"; src = ./.; files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; - }; + }).packages.lbf-prelude-golden-api-typescript-tgz; }; }; } From 2e2ed98f4df7f207ec3cf131adf5b47b202e248f Mon Sep 17 00:00:00 2001 From: jared Date: Sat, 27 Jan 2024 03:14:57 -0700 Subject: [PATCH 03/14] Code generation bug fixes + runtime fixes for TS --- .../src/LambdaBuffers/Codegen/Typescript/Print/LamVal.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lambda-buffers-codegen/src/LambdaBuffers/Codegen/Typescript/Print/LamVal.hs b/lambda-buffers-codegen/src/LambdaBuffers/Codegen/Typescript/Print/LamVal.hs index 14223f19..6edb690c 100644 --- a/lambda-buffers-codegen/src/LambdaBuffers/Codegen/Typescript/Print/LamVal.hs +++ b/lambda-buffers-codegen/src/LambdaBuffers/Codegen/Typescript/Print/LamVal.hs @@ -450,8 +450,8 @@ printCtorE ((_, tyN), (ctorN, _)) prodVals = do [ lbrace , indent 2 $ vsep - [ "name" <+> colon <+> pretty '\'' <> ctorNDoc <> pretty '\'' <> comma - , "fields" <+> colon <+> singleDoc + [ "fields" <+> colon <+> singleDoc <> comma + , "name" <+> colon <+> pretty '\'' <> ctorNDoc <> pretty '\'' ] , rbrace ] @@ -461,8 +461,8 @@ printCtorE ((_, tyN), (ctorN, _)) prodVals = do [ lbrace , indent 2 $ vsep - [ "name" <+> colon <+> pretty '\'' <> ctorNDoc <> pretty '\'' <> comma - , "fields" <+> colon <+> encloseSep lbracket rbracket comma prodDocs + [ "fields" <+> colon <+> encloseSep lbracket rbracket comma prodDocs <> comma + , "name" <+> colon <+> pretty '\'' <> ctorNDoc <> pretty '\'' ] , rbrace ] From e917194dadbb384a9dcd757194b71404ae96611f Mon Sep 17 00:00:00 2001 From: jared Date: Sat, 27 Jan 2024 05:51:13 -0700 Subject: [PATCH 04/14] Code cleanup --- flake.nix | 2 +- .../lbt-prelude-typescript/.gitignore | 4 +- .../lbt-prelude-typescript/build.nix | 2 +- .../lbt-prelude-typescript/package-lock.json | 64 +++++++++---------- .../lbt-prelude-typescript/package.json | 8 +-- .../lbt-prelude-typescript/src/Json-test.ts | 1 - .../lbt-prelude-typescript/src/index.mts | 61 ------------------ 7 files changed, 40 insertions(+), 102 deletions(-) delete mode 100644 testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts diff --git a/flake.nix b/flake.nix index b2f196f4..33b3a7b9 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ nixpkgs.url = "github:NixOS/nixpkgs"; # flake-lang.nix - flake-lang.url = "github:mlabs-haskell/flake-lang.nix/jared/add-data-to-typescript-flake"; + flake-lang.url = "github:mlabs-haskell/flake-lang.nix"; # Haskell diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore index 5f873d7c..a3c20529 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore @@ -1,2 +1,2 @@ -extra-dependencies/ -data/ +.extra-dependencies +data diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix index 5ff63114..720344d6 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix @@ -24,7 +24,7 @@ in { packages = { - inherit (tsFlake.packages) lbt-prelude-typescript lbt-prelude-typescript-tgz; + inherit (tsFlake.packages) lbt-prelude-typescript-tgz; }; inherit (tsFlake) devShells checks; diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json index 914db3fd..76a11770 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json @@ -9,10 +9,10 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "lbf-prelude-golden-api": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbf-prelude-golden-api": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" }, "devDependencies": { "@types/node": "^20.11.7", @@ -30,37 +30,37 @@ }, "node_modules/lbf-prelude": { "version": "1.0.0", - "resolved": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "integrity": "sha512-XLxQoeX/LBPAHSnzF7LcUBOfMziugGvVMYiC1tdKQXfmv4fxaHQK9H5nTCNVNuRS/yu6xAhmoBQCI8EUBdRBPg==", + "resolved": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-pjBKImYBDMCk+XEc4GFAiloNG4cKHTWpTDEe41JhBIs7KOR09EuJCkURQaouSx7Ce6LACFoY9ilpHdbtPFFYvA==", "dependencies": { - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } }, "node_modules/lbf-prelude-golden-api": { "version": "1.0.0", - "resolved": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "integrity": "sha512-nCPzAphuHWkS9ltUXDCVkMBKYdUt0594IqlGiXK7mbGxpuRTVli8gve6KAsQmcXUnaDEKiDrhFrnTKReaBVmFQ==", + "resolved": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "integrity": "sha512-vNxFuZhb+LvheA4fi5n1ARXIDjJfrn/AGaQuDREI2jdnL0iSjY/RzBwRZubiZ2CpuBL3m95IYeNS7DuCCZHHUg==", "dependencies": { - "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } }, "node_modules/lbr-prelude": { "version": "1.0.0", - "resolved": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-3desaAg+xjFL1GMr5rdze2g/e91P5qamIflDO21KxWwKRBvca0C0oSuc/vXaR5SXGK+GG5x2SY2Z8tLJgp6dwg==", + "resolved": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-3yDtdD7ywlJMSScbdhc6tsX3GmMR2GciWLSt0f5zu/vL/asgGQR0tOlYAb1QjL1715q1Bfr/61SHomvHv1Fvkw==", "license": "ISC", "dependencies": { - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", "typescript": "^5.3.3" } }, "node_modules/prelude": { "version": "1.0.1", - "resolved": "file:extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==", + "resolved": "file:.extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-HAPZ9DWSnYpz7CBJYlXWoydf6uRZT2UvjdKkkN8j2Qw332rwfpOrSOEVDllgmz7xPF5yxyH8w7YGfND6wNM9pw==", "license": "ISC" }, "node_modules/typescript": { @@ -93,33 +93,33 @@ } }, "lbf-prelude": { - "version": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "integrity": "sha512-XLxQoeX/LBPAHSnzF7LcUBOfMziugGvVMYiC1tdKQXfmv4fxaHQK9H5nTCNVNuRS/yu6xAhmoBQCI8EUBdRBPg==", + "version": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-pjBKImYBDMCk+XEc4GFAiloNG4cKHTWpTDEe41JhBIs7KOR09EuJCkURQaouSx7Ce6LACFoY9ilpHdbtPFFYvA==", "requires": { - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } }, "lbf-prelude-golden-api": { - "version": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "integrity": "sha512-nCPzAphuHWkS9ltUXDCVkMBKYdUt0594IqlGiXK7mbGxpuRTVli8gve6KAsQmcXUnaDEKiDrhFrnTKReaBVmFQ==", + "version": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "integrity": "sha512-vNxFuZhb+LvheA4fi5n1ARXIDjJfrn/AGaQuDREI2jdnL0iSjY/RzBwRZubiZ2CpuBL3m95IYeNS7DuCCZHHUg==", "requires": { - "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } }, "lbr-prelude": { - "version": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-3desaAg+xjFL1GMr5rdze2g/e91P5qamIflDO21KxWwKRBvca0C0oSuc/vXaR5SXGK+GG5x2SY2Z8tLJgp6dwg==", + "version": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-3yDtdD7ywlJMSScbdhc6tsX3GmMR2GciWLSt0f5zu/vL/asgGQR0tOlYAb1QjL1715q1Bfr/61SHomvHv1Fvkw==", "requires": { - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", "typescript": "^5.3.3" } }, "prelude": { - "version": "file:extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==" + "version": "file:.extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-HAPZ9DWSnYpz7CBJYlXWoydf6uRZT2UvjdKkkN8j2Qw332rwfpOrSOEVDllgmz7xPF5yxyH8w7YGfND6wNM9pw==" }, "typescript": { "version": "5.3.3", diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json index 8a38bf9c..6f6ef5ea 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/package.json +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json @@ -21,9 +21,9 @@ "typescript": "^5.3.3" }, "dependencies": { - "lbf-prelude": "file:extra-dependencies/lbf-prelude-1.0.0.tgz", - "lbf-prelude-golden-api": "file:extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "lbr-prelude": "file:extra-dependencies/lbr-prelude-1.0.0.tgz", - "prelude": "file:extra-dependencies/prelude-1.0.1.tgz" + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbf-prelude-golden-api": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } } diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts index 0f1c9e14..fc4fec14 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts @@ -8,7 +8,6 @@ import * as Prelude from "prelude"; import * as PreludeJson from "prelude/Json.js"; import * as LbfFoo from "lbf-prelude-golden-api/LambdaBuffers/Foo.mjs"; -// import * as LbfFooBar from "lbf-prelude-golden-api/LambdaBuffers/Foo/Bar.mjs" import * as LbfDays from "lbf-prelude-golden-api/LambdaBuffers/Days.mjs"; import * as LbrPrelude from "lbr-prelude"; diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts deleted file mode 100644 index ce1e56ca..00000000 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/src/index.mts +++ /dev/null @@ -1,61 +0,0 @@ -// Simple prelude sample project. -// To run, type -// ``` -// npm run build && node ./dist/src/index.mjs -// ``` -// import * as Prelude from "prelude"; -// import * as PreludeJson from "prelude/Json.js"; -// import * as LbrPrelude from "lbr-prelude"; -// import * as MySchema from "lbf-prelude-sample-project/LambdaBuffers/MySchema.mjs"; -// -// const a: MySchema.Branchy = { -// name: "Node", -// fields: [420n, [{ name: "Leaf", fields: true }, { -// name: "Leaf", -// fields: false, -// }]], -// }; -// const b: MySchema.Branchy = { name: "Leaf", fields: false }; -// -// a; -// -// console.log("a == a"); -// console.log( -// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).eq(a, a), -// ); -// console.log("a == b"); -// console.log( -// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).eq(a, b), -// ); -// -// console.log("a != a"); -// console.log( -// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).neq(a, a), -// ); -// console.log("a != b"); -// console.log( -// LbrPrelude.Eq[MySchema.Branchy](LbrPrelude.Eq[LbrPrelude.Bool]).neq(a, b), -// ); -// -// console.log("toJson(a)"); -// console.log( -// PreludeJson.stringify( -// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) -// .toJson(a), -// ), -// ); -// -// console.log("fromJson(toJson(a))"); -// console.log( -// JSON.stringify( -// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) -// .fromJson( -// LbrPrelude.Json[MySchema.Branchy](LbrPrelude.Json[LbrPrelude.Bool]) -// .toJson(a), -// ), -// (_key, value) => { -// if (typeof value === "bigint") return (value.toString()); -// else return value; -// }, -// ), -// ); From c69011e1f22a632d07c82b73ecd1cc94403b7bbe Mon Sep 17 00:00:00 2001 From: jared <> Date: Sat, 27 Jan 2024 06:24:12 -0700 Subject: [PATCH 05/14] Improved error messages --- .../lbt-prelude-typescript/src/Json-test.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts index fc4fec14..d30bab64 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts @@ -51,20 +51,26 @@ export async function fromToGoldenTest( for (const [filepath, index] of foundGoldens) { const contents = await Fs.readFile(filepath, { encoding: "utf8" }); - const fromToJson = PreludeJson.stringify( - jsonDict.toJson( - jsonDict.fromJson( - PreludeJson.parseJson(contents), + try { + const fromToJson = PreludeJson.stringify( + jsonDict.toJson( + jsonDict.fromJson( + PreludeJson.parseJson(contents), + ), ), - ), - ); + ); - // TODO(jaredponn). This fails on the _first_ test instead of - // accumulating all of them.. Perhaps we want to accumulate all of - // them by e.g. wrapping this with `it`. - if (contents !== fromToJson) { + // TODO(jaredponn). This fails on the _first_ test instead of + // accumulating all of them.. Perhaps we want to accumulate all of + // them by e.g. wrapping this with `it`. + if (contents !== fromToJson) { + assert.fail( + `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromToJson}\``, + ); + } + } catch (err) { assert.fail( - `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromToJson}\``, + `Golden test failed for ${index} since an error was thrown: \`${err}\`.`, ); } } From 7cf7d9bafe7b4a76bc702bffb207295e773c20b4 Mon Sep 17 00:00:00 2001 From: jared <> Date: Sat, 27 Jan 2024 07:07:16 -0700 Subject: [PATCH 06/14] Removed useless package in ./build.nix --- testsuites/lbt-prelude/lbt-prelude-typescript/build.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix index 720344d6..34ac5dd3 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/build.nix @@ -23,10 +23,6 @@ }; in { - packages = { - inherit (tsFlake.packages) lbt-prelude-typescript-tgz; - }; - inherit (tsFlake) devShells checks; }; } From 343a1a900f42dcf5b1c1a7e330eafb07c280908b Mon Sep 17 00:00:00 2001 From: jared <> Date: Sat, 27 Jan 2024 07:08:43 -0700 Subject: [PATCH 07/14] Updated flake inputs --- flake.lock | 30 +++++++++---------- .../typescript/lbr-plutus/package-lock.json | 12 ++++---- .../typescript/lbr-prelude/package-lock.json | 4 +-- .../lbt-prelude-typescript/package-lock.json | 16 +++++----- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/flake.lock b/flake.lock index 894df019..cf791d86 100644 --- a/flake.lock +++ b/flake.lock @@ -14390,11 +14390,11 @@ "rust-overlay": "rust-overlay_11" }, "locked": { - "lastModified": 1706349357, - "narHash": "sha256-uWFweNl8h3aS2i8wLJijCKeHi/NTVGm/WritygUsfpU=", + "lastModified": 1706411792, + "narHash": "sha256-hGBRH+0Iu2HeMBS4wIv/ZWdU4sZI22A0gASCdbTdBa8=", "owner": "mlabs-haskell", "repo": "flake-lang.nix", - "rev": "00b1c7badea1604320af504b2b976efefe7d3507", + "rev": "9edc519bc0295abd4304795934eb3569607bf7f8", "type": "github" }, "original": { @@ -14419,11 +14419,11 @@ "rust-overlay": "rust-overlay_17" }, "locked": { - "lastModified": 1706349357, - "narHash": "sha256-uWFweNl8h3aS2i8wLJijCKeHi/NTVGm/WritygUsfpU=", + "lastModified": 1706411792, + "narHash": "sha256-hGBRH+0Iu2HeMBS4wIv/ZWdU4sZI22A0gASCdbTdBa8=", "owner": "mlabs-haskell", "repo": "flake-lang.nix", - "rev": "00b1c7badea1604320af504b2b976efefe7d3507", + "rev": "9edc519bc0295abd4304795934eb3569607bf7f8", "type": "github" }, "original": { @@ -14448,11 +14448,11 @@ "rust-overlay": "rust-overlay_23" }, "locked": { - "lastModified": 1706349357, - "narHash": "sha256-uWFweNl8h3aS2i8wLJijCKeHi/NTVGm/WritygUsfpU=", + "lastModified": 1706411792, + "narHash": "sha256-hGBRH+0Iu2HeMBS4wIv/ZWdU4sZI22A0gASCdbTdBa8=", "owner": "mlabs-haskell", "repo": "flake-lang.nix", - "rev": "00b1c7badea1604320af504b2b976efefe7d3507", + "rev": "9edc519bc0295abd4304795934eb3569607bf7f8", "type": "github" }, "original": { @@ -50671,11 +50671,11 @@ "prelude-typescript": "prelude-typescript" }, "locked": { - "lastModified": 1706357011, - "narHash": "sha256-ToP5ZLDmcCxXzu1lDKKgs3T7wEWu0fyJsWgXe0sGVn4=", + "lastModified": 1706413121, + "narHash": "sha256-NsmQOF+ZyQZhMl9mLWdxAGCgdWPDRqsWXFMycQImvQQ=", "owner": "mlabs-haskell", "repo": "plutus-ledger-api-typescript", - "rev": "82013e0c94c312bacf4879daebacdf446b186249", + "rev": "fec4dc20307b20c9fd5ddec9db157786ef9d2162", "type": "github" }, "original": { @@ -51394,11 +51394,11 @@ "pre-commit-hooks-nix": "pre-commit-hooks-nix_14" }, "locked": { - "lastModified": 1706350068, - "narHash": "sha256-9IQg1jyItkg+ehRtC+REvTTxmPnOvEjQrt35gyjSumQ=", + "lastModified": 1706412670, + "narHash": "sha256-Ygsq5zaRjt4uQkOpyNzZ1amr9iAS1fd+fulAdEYWwHk=", "owner": "mlabs-haskell", "repo": "prelude-typescript", - "rev": "41bf7472016811fdb2c40b1eecbc07dffe070d85", + "rev": "e6f4ce2b9cb22d30175e9f522ed894dc29436ad1", "type": "github" }, "original": { diff --git a/runtimes/typescript/lbr-plutus/package-lock.json b/runtimes/typescript/lbr-plutus/package-lock.json index 36e043f0..f1f303eb 100644 --- a/runtimes/typescript/lbr-plutus/package-lock.json +++ b/runtimes/typescript/lbr-plutus/package-lock.json @@ -53,7 +53,7 @@ "node_modules/lbr-prelude": { "version": "1.0.0", "resolved": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-dCBgP+JBfVGXGUXpmar1fsJ5zrgyMlShGdiD5MAMgdRYe4CcgE0CINS+Xq7vHgTFmWXib3DQ/QXIJCvoM91cvg==", + "integrity": "sha512-xakEfmSqbcYPCFeNFPAHdm2japkfw/a2Hh/kHeA+VZmEaKyVP8JrWJvtNWjfn/k7Dkbj0lbBl48LQWMFkqvjcQ==", "license": "ISC", "dependencies": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", @@ -63,7 +63,7 @@ "node_modules/plutus-ledger-api": { "version": "1.0.0", "resolved": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", - "integrity": "sha512-CR4CshLrbu15tUu7RPA3fvzRZ/HjOsBOJJ4P144b3dtzToP2ljJ4KbCZs3pk3im71sst7fjQKdEM97B3fyMc3Q==", + "integrity": "sha512-UVQfoeULxTnLszKH6u1yYWiYXjqn6LulX02awhi0bX8Bvnoj0hF43EH3e+RrcMDe/6bQh+TVw7N2Xu+RU14esw==", "license": "ISC", "dependencies": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" @@ -72,7 +72,7 @@ "node_modules/prelude": { "version": "1.0.1", "resolved": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==", + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==", "license": "ISC" }, "node_modules/pure-rand": { @@ -131,7 +131,7 @@ }, "lbr-prelude": { "version": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-dCBgP+JBfVGXGUXpmar1fsJ5zrgyMlShGdiD5MAMgdRYe4CcgE0CINS+Xq7vHgTFmWXib3DQ/QXIJCvoM91cvg==", + "integrity": "sha512-xakEfmSqbcYPCFeNFPAHdm2japkfw/a2Hh/kHeA+VZmEaKyVP8JrWJvtNWjfn/k7Dkbj0lbBl48LQWMFkqvjcQ==", "requires": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", "typescript": "^5.3.3" @@ -139,14 +139,14 @@ }, "plutus-ledger-api": { "version": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", - "integrity": "sha512-CR4CshLrbu15tUu7RPA3fvzRZ/HjOsBOJJ4P144b3dtzToP2ljJ4KbCZs3pk3im71sst7fjQKdEM97B3fyMc3Q==", + "integrity": "sha512-UVQfoeULxTnLszKH6u1yYWiYXjqn6LulX02awhi0bX8Bvnoj0hF43EH3e+RrcMDe/6bQh+TVw7N2Xu+RU14esw==", "requires": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" } }, "prelude": { "version": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==" + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==" }, "pure-rand": { "version": "6.0.4", diff --git a/runtimes/typescript/lbr-prelude/package-lock.json b/runtimes/typescript/lbr-prelude/package-lock.json index 6a4e9e65..e527d978 100644 --- a/runtimes/typescript/lbr-prelude/package-lock.json +++ b/runtimes/typescript/lbr-prelude/package-lock.json @@ -16,7 +16,7 @@ "node_modules/prelude": { "version": "1.0.1", "resolved": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==", + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==", "license": "ISC" }, "node_modules/typescript": { @@ -35,7 +35,7 @@ "dependencies": { "prelude": { "version": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-ucWNcpO/mDC3kgAEx/SP9yzmhWH5FgP8TY1kQpPQw8R0zGHtgpdXnmcKcl1n8s92uIDgBtIZGVUNRoEDLjGwqQ==" + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==" }, "typescript": { "version": "5.3.3", diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json index 76a11770..682f8d90 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package-lock.json @@ -31,7 +31,7 @@ "node_modules/lbf-prelude": { "version": "1.0.0", "resolved": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", - "integrity": "sha512-pjBKImYBDMCk+XEc4GFAiloNG4cKHTWpTDEe41JhBIs7KOR09EuJCkURQaouSx7Ce6LACFoY9ilpHdbtPFFYvA==", + "integrity": "sha512-jOL78xR3JwPMCiFZKxLFiaRvtpSlCNdWcp0NcekUwDQ5+Hg2Yg/nMqvB8lqg8orU+ZsWuHO4mo8MNPVMeyJavA==", "dependencies": { "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" @@ -40,7 +40,7 @@ "node_modules/lbf-prelude-golden-api": { "version": "1.0.0", "resolved": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "integrity": "sha512-vNxFuZhb+LvheA4fi5n1ARXIDjJfrn/AGaQuDREI2jdnL0iSjY/RzBwRZubiZ2CpuBL3m95IYeNS7DuCCZHHUg==", + "integrity": "sha512-vXBgsy4ShhRkFNZDWnF6xu7sX8cSWxt9u0+9Z0SEPP3X80hZkwKi3rpsautdfe0SW8d/yx1T20q1SSWxYVBK9A==", "dependencies": { "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", @@ -50,7 +50,7 @@ "node_modules/lbr-prelude": { "version": "1.0.0", "resolved": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-3yDtdD7ywlJMSScbdhc6tsX3GmMR2GciWLSt0f5zu/vL/asgGQR0tOlYAb1QjL1715q1Bfr/61SHomvHv1Fvkw==", + "integrity": "sha512-w9hPnbHU6np87kdChn7D7r021U0UUTDhKxc9rYZqTsu73bRfY1AxxUh4n4FgiF6aa+GFtHFaYd06a0Znka/PMQ==", "license": "ISC", "dependencies": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", @@ -60,7 +60,7 @@ "node_modules/prelude": { "version": "1.0.1", "resolved": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-HAPZ9DWSnYpz7CBJYlXWoydf6uRZT2UvjdKkkN8j2Qw332rwfpOrSOEVDllgmz7xPF5yxyH8w7YGfND6wNM9pw==", + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==", "license": "ISC" }, "node_modules/typescript": { @@ -94,7 +94,7 @@ }, "lbf-prelude": { "version": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", - "integrity": "sha512-pjBKImYBDMCk+XEc4GFAiloNG4cKHTWpTDEe41JhBIs7KOR09EuJCkURQaouSx7Ce6LACFoY9ilpHdbtPFFYvA==", + "integrity": "sha512-jOL78xR3JwPMCiFZKxLFiaRvtpSlCNdWcp0NcekUwDQ5+Hg2Yg/nMqvB8lqg8orU+ZsWuHO4mo8MNPVMeyJavA==", "requires": { "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" @@ -102,7 +102,7 @@ }, "lbf-prelude-golden-api": { "version": "file:.extra-dependencies/lbf-prelude-golden-api-1.0.0.tgz", - "integrity": "sha512-vNxFuZhb+LvheA4fi5n1ARXIDjJfrn/AGaQuDREI2jdnL0iSjY/RzBwRZubiZ2CpuBL3m95IYeNS7DuCCZHHUg==", + "integrity": "sha512-vXBgsy4ShhRkFNZDWnF6xu7sX8cSWxt9u0+9Z0SEPP3X80hZkwKi3rpsautdfe0SW8d/yx1T20q1SSWxYVBK9A==", "requires": { "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", @@ -111,7 +111,7 @@ }, "lbr-prelude": { "version": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", - "integrity": "sha512-3yDtdD7ywlJMSScbdhc6tsX3GmMR2GciWLSt0f5zu/vL/asgGQR0tOlYAb1QjL1715q1Bfr/61SHomvHv1Fvkw==", + "integrity": "sha512-w9hPnbHU6np87kdChn7D7r021U0UUTDhKxc9rYZqTsu73bRfY1AxxUh4n4FgiF6aa+GFtHFaYd06a0Znka/PMQ==", "requires": { "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", "typescript": "^5.3.3" @@ -119,7 +119,7 @@ }, "prelude": { "version": "file:.extra-dependencies/prelude-1.0.1.tgz", - "integrity": "sha512-HAPZ9DWSnYpz7CBJYlXWoydf6uRZT2UvjdKkkN8j2Qw332rwfpOrSOEVDllgmz7xPF5yxyH8w7YGfND6wNM9pw==" + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==" }, "typescript": { "version": "5.3.3", From 4c6304cf3a3a0c08bbb46e94532a293fdea513e9 Mon Sep 17 00:00:00 2001 From: jared <> Date: Sun, 28 Jan 2024 03:56:36 -0700 Subject: [PATCH 08/14] TS lbr-plutus golden tests --- flake.nix | 1 + .../src/LambdaBuffers/V1/Instances.ts | 23 + .../src/LambdaBuffers/V1/Symbols.ts | 2 + testsuites/lbt-plutus/api/build.nix | 7 + testsuites/lbt-plutus/golden/build.nix | 8 + .../lbt-plutus-typescript/.gitignore | 2 + .../lbt-plutus-typescript/build.nix | 28 + .../lbt-plutus-typescript/package-lock.json | 204 ++++ .../lbt-plutus-typescript/package.json | 32 + .../lbt-plutus-typescript/src/Goldens.ts | 884 ++++++++++++++ .../lbt-plutus-typescript/src/Json-test.ts | 480 ++++++++ .../src/PlutusData-test.ts | 1051 +++++++++++++++++ .../lbt-plutus-typescript/src/Utils.ts | 122 ++ .../lbt-plutus-typescript/src/tsconfig.json | 5 + .../lbt-plutus-typescript/tsconfig-base.json | 109 ++ 15 files changed, 2958 insertions(+) create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/build.nix create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/package-lock.json create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/package.json create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/src/Goldens.ts create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/src/Json-test.ts create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/src/PlutusData-test.ts create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/src/tsconfig.json create mode 100644 testsuites/lbt-plutus/lbt-plutus-typescript/tsconfig-base.json diff --git a/flake.nix b/flake.nix index 33b3a7b9..3af3c325 100644 --- a/flake.nix +++ b/flake.nix @@ -93,6 +93,7 @@ ./testsuites/lbt-plutus/golden/build.nix ./testsuites/lbt-plutus/lbt-plutus-haskell/build.nix ./testsuites/lbt-plutus/lbt-plutus-purescript/build.nix + ./testsuites/lbt-plutus/lbt-plutus-typescript/build.nix ./testsuites/lbt-plutus/lbt-plutus-plutarch/build.nix ./testsuites/lbt-plutus/lbt-plutus-rust/build.nix ./experimental/build.nix diff --git a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts index f83da642..ca3808c2 100644 --- a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts +++ b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts @@ -247,6 +247,29 @@ declare module "../PlutusData.js" { PlutusData.IsPlutusData[Symbols.UpperBound] = PlutusLedgerApiV1.isPlutusDataUpperBound; +// Closure +declare module "lbr-prelude" { + export interface EqInstances { + [Symbols.Closure]: Prelude.Eq; + } + + export interface JsonInstances { + [Symbols.Closure]: Prelude.Json; + } +} + +LbrPrelude.Eq[Symbols.Closure] = Prelude.eqBool; +LbrPrelude.Json[Symbols.Closure] = Prelude.jsonBool; + +declare module "../PlutusData.js" { + export interface IsPlutusDataInstances { + [Symbols.Closure]: PlutusLedgerApiPlutusData.IsPlutusData< + PlutusLedgerApiV1.Closure + >; + } +} +PlutusData.IsPlutusData[Symbols.Closure] = PlutusLedgerApiV1.isPlutusDataBool; + // Redeemer declare module "lbr-prelude" { export interface EqInstances { diff --git a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Symbols.ts b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Symbols.ts index fa16d92c..58726f2f 100644 --- a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Symbols.ts +++ b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Symbols.ts @@ -11,6 +11,7 @@ export const Interval: unique symbol = Symbol("Interval"); export const Extended: unique symbol = Symbol("Extended"); export const LowerBound: unique symbol = Symbol("LowerBound"); export const UpperBound: unique symbol = Symbol("UpperBound"); +export const Closure: unique symbol = Symbol("Closure"); export const Redeemer: unique symbol = Symbol("Redeemer"); export const Datum: unique symbol = Symbol("Datum"); export const DatumHash: unique symbol = Symbol("DatumHash"); @@ -36,6 +37,7 @@ export type Interval = PlutusLedgerApiV1.Interval; export type Extended = PlutusLedgerApiV1.Extended; export type LowerBound = PlutusLedgerApiV1.LowerBound; export type UpperBound = PlutusLedgerApiV1.UpperBound; +export type Closure = PlutusLedgerApiV1.Closure; export type Redeemer = PlutusLedgerApiV1.Redeemer; export type Datum = PlutusLedgerApiV1.Datum; export type DatumHash = PlutusLedgerApiV1.DatumHash; diff --git a/testsuites/lbt-plutus/api/build.nix b/testsuites/lbt-plutus/api/build.nix index 6409a845..51410195 100644 --- a/testsuites/lbt-plutus/api/build.nix +++ b/testsuites/lbt-plutus/api/build.nix @@ -26,6 +26,13 @@ _: { files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; }; + lbf-plutus-golden-api-typescript = (config.lbf-nix.lbfPlutusTypescript { + name = "lbf-plutus-golden-api"; + src = ./.; + files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; + }).packages.lbf-plutus-golden-api-typescript-tgz + ; + }; }; } diff --git a/testsuites/lbt-plutus/golden/build.nix b/testsuites/lbt-plutus/golden/build.nix index cc985ea3..7cc79873 100644 --- a/testsuites/lbt-plutus/golden/build.nix +++ b/testsuites/lbt-plutus/golden/build.nix @@ -22,6 +22,14 @@ _: phases = "installPhase"; installPhase = "ln -s $src $out"; }; + + lbt-plutus-golden-typescript = pkgs.stdenv.mkDerivation { + name = "lbt-plutus-golden-data"; + src = ./.; + phases = "installPhase"; + installPhase = ''ln -s "$src" "$out"''; + }; + }; }; diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore b/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore new file mode 100644 index 00000000..a3c20529 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore @@ -0,0 +1,2 @@ +.extra-dependencies +data diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/build.nix b/testsuites/lbt-plutus/lbt-plutus-typescript/build.nix new file mode 100644 index 00000000..45ab1aa1 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/build.nix @@ -0,0 +1,28 @@ +{ inputs, ... }: +{ + perSystem = { config, system, ... }: + let + tsFlake = + inputs.flake-lang.lib.${system}.typescriptFlake { + name = "lbt-plutus"; + src = ./.; + npmExtraDependencies = [ + config.packages.lbf-plutus-golden-api-typescript + ]; + + devShellTools = config.settings.shell.tools; + devShellHook = config.settings.shell.hook; + + data = + [ + { + name = "lbt-plutus-golden-data"; + path = config.packages.lbt-plutus-golden-typescript; + } + ]; + }; + in + { + inherit (tsFlake) devShells checks; + }; +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/package-lock.json b/testsuites/lbt-plutus/lbt-plutus-typescript/package-lock.json new file mode 100644 index 00000000..93fd7d48 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/package-lock.json @@ -0,0 +1,204 @@ +{ + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "lbf-plutus": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "lbf-plutus-golden-api": "file:.extra-dependencies/lbf-plutus-golden-api-1.0.0.tgz", + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + }, + "devDependencies": { + "@types/node": "^20.11.7", + "typescript": "^5.3.3" + } + }, + "node_modules/@types/node": { + "version": "20.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.7.tgz", + "integrity": "sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/lbf-plutus": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "integrity": "sha512-XtJBPw/Dh6KfkNXj/O7cQNkiuJcFhpfMm2G5HNSkLRq1+QAyjsyXicJwhO9toxzlQctaeyK9X0i3AaXJ965UaQ==", + "dependencies": { + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbf-plutus-golden-api": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/lbf-plutus-golden-api-1.0.0.tgz", + "integrity": "sha512-OMIFtYu4L728HT8wYWqfvJK3rtEKUpY6xxO8eHZjfu0Dw0815XElPECaf/8FU7vijSIvuXWMudGpaE0Fgzx4RQ==", + "dependencies": { + "lbf-plutus": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbf-prelude": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-ycFngZkq5iwwYROLBsvpTtw6BdhklgJkmIxWvmF0ksH6X462IuT7i9Rsvx37tfPOBNU6cHoUJ3PeUZHvj6VF3g==", + "dependencies": { + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbr-plutus": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "integrity": "sha512-j7aS5tciyTIXbMK/azdOoKtAB9trUBi4DQ0kQZN1RfpspuOBePD7KLbAT64/oLtcKyqf2fSITk3B+IGawGj41w==", + "license": "ISC", + "dependencies": { + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/lbr-prelude": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-xakEfmSqbcYPCFeNFPAHdm2japkfw/a2Hh/kHeA+VZmEaKyVP8JrWJvtNWjfn/k7Dkbj0lbBl48LQWMFkqvjcQ==", + "license": "ISC", + "dependencies": { + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", + "typescript": "^5.3.3" + } + }, + "node_modules/plutus-ledger-api": { + "version": "1.0.0", + "resolved": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "integrity": "sha512-UVQfoeULxTnLszKH6u1yYWiYXjqn6LulX02awhi0bX8Bvnoj0hF43EH3e+RrcMDe/6bQh+TVw7N2Xu+RU14esw==", + "license": "ISC", + "dependencies": { + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "node_modules/prelude": { + "version": "1.0.1", + "resolved": "file:.extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==", + "license": "ISC" + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + }, + "dependencies": { + "@types/node": { + "version": "20.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.7.tgz", + "integrity": "sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "lbf-plutus": { + "version": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "integrity": "sha512-XtJBPw/Dh6KfkNXj/O7cQNkiuJcFhpfMm2G5HNSkLRq1+QAyjsyXicJwhO9toxzlQctaeyK9X0i3AaXJ965UaQ==", + "requires": { + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbf-plutus-golden-api": { + "version": "file:.extra-dependencies/lbf-plutus-golden-api-1.0.0.tgz", + "integrity": "sha512-OMIFtYu4L728HT8wYWqfvJK3rtEKUpY6xxO8eHZjfu0Dw0815XElPECaf/8FU7vijSIvuXWMudGpaE0Fgzx4RQ==", + "requires": { + "lbf-plutus": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbf-prelude": { + "version": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "integrity": "sha512-ycFngZkq5iwwYROLBsvpTtw6BdhklgJkmIxWvmF0ksH6X462IuT7i9Rsvx37tfPOBNU6cHoUJ3PeUZHvj6VF3g==", + "requires": { + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbr-plutus": { + "version": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "integrity": "sha512-j7aS5tciyTIXbMK/azdOoKtAB9trUBi4DQ0kQZN1RfpspuOBePD7KLbAT64/oLtcKyqf2fSITk3B+IGawGj41w==", + "requires": { + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "lbr-prelude": { + "version": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "integrity": "sha512-xakEfmSqbcYPCFeNFPAHdm2japkfw/a2Hh/kHeA+VZmEaKyVP8JrWJvtNWjfn/k7Dkbj0lbBl48LQWMFkqvjcQ==", + "requires": { + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz", + "typescript": "^5.3.3" + } + }, + "plutus-ledger-api": { + "version": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "integrity": "sha512-UVQfoeULxTnLszKH6u1yYWiYXjqn6LulX02awhi0bX8Bvnoj0hF43EH3e+RrcMDe/6bQh+TVw7N2Xu+RU14esw==", + "requires": { + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } + }, + "prelude": { + "version": "file:.extra-dependencies/prelude-1.0.1.tgz", + "integrity": "sha512-NtSJIsn0+eDmzHZu3o5rK5Fh2Q3/eXmZ+tcsUsip7XmKl06RX0vTWWSsYngJhsdj+Xd7jZl/Wy92m8oNycykVA==" + }, + "typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + } +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/package.json b/testsuites/lbt-plutus/lbt-plutus-typescript/package.json new file mode 100644 index 00000000..1b02d6d7 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/package.json @@ -0,0 +1,32 @@ +{ + "name": "lbf-prelude-typescript", + "version": "1.0.0", + "description": "Test suite project for LambdaBuffers", + "type": "module", + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + }, + "scripts": { + "build": "npx tsc -b src/", + "test": "node --test" + }, + "author": "Jared Pon", + "license": "ISC", + "files": [ + "./dist/**/*" + ], + "devDependencies": { + "@types/node": "^20.11.7", + "typescript": "^5.3.3" + }, + "dependencies": { + "lbf-plutus": "file:.extra-dependencies/lbf-plutus-1.0.0.tgz", + "lbf-plutus-golden-api": "file:.extra-dependencies/lbf-plutus-golden-api-1.0.0.tgz", + "lbf-prelude": "file:.extra-dependencies/lbf-prelude-1.0.0.tgz", + "lbr-plutus": "file:.extra-dependencies/lbr-plutus-1.0.0.tgz", + "lbr-prelude": "file:.extra-dependencies/lbr-prelude-1.0.0.tgz", + "plutus-ledger-api": "file:.extra-dependencies/plutus-ledger-api-1.0.0.tgz", + "prelude": "file:.extra-dependencies/prelude-1.0.1.tgz" + } +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/Goldens.ts b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Goldens.ts new file mode 100644 index 00000000..a80db459 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Goldens.ts @@ -0,0 +1,884 @@ +import * as LbrPrelude from "lbr-prelude"; +import * as LbrPlutusV1 from "lbr-plutus/V1.js"; +import * as LbrPlutusV2 from "lbr-plutus/V2.js"; + +import * as PlaV1 from "plutus-ledger-api/V1.js"; +import * as PlaMap from "plutus-ledger-api/AssocMap.js"; + +import * as LbfFooBar from "lbf-plutus-golden-api/LambdaBuffers/Foo/Bar.mjs"; +import * as LbfFoo from "lbf-plutus-golden-api/LambdaBuffers/Foo.mjs"; +import * as LbfDays from "lbf-plutus-golden-api/LambdaBuffers/Days.mjs"; + +/** + * Hard coded bytes for testing + */ +export function someBytes(): LbrPlutusV1.LedgerBytes { + return Uint8Array.from([115, 111, 109, 101, 32, 98, 121, 116, 101, 115]); +} + +/** + * Hard coded bytes for testing + */ +export function someMoreBytes(): LbrPlutusV1.LedgerBytes { + return Uint8Array.from([ + 115, + 111, + 109, + 101, + 32, + 109, + 111, + 114, + 101, + 32, + 98, + 121, + 116, + 101, + 115, + ]); +} + +/** + * Hard coded bytes for testing + */ +export function emptyBytes(): LbrPlutusV1.LedgerBytes { + return Uint8Array.from([]); +} + +/** + * Hard coded bytes for testing + */ +export function nullBytes(): LbrPlutusV1.LedgerBytes { + return Uint8Array.from([0]); +} + +/* + * Plutus.V1 goldens + */ + +/** + * Hard coded {@link PlutusData} goldens + */ +export function plutusDataGoldens(): LbrPrelude.List { + return [ + { name: "Constr", fields: [0n, []] }, + + { + name: "Constr", + fields: [1n, [ + { name: "Integer", fields: 1n }, + { name: "Bytes", fields: someBytes() }, + ]], + }, + { name: "List", fields: [] }, + + { + name: "List", + fields: [ + { name: "Integer", fields: 1n }, + { name: "Integer", fields: 2n }, + ], + }, + { + name: "List", + fields: [ + { name: "Integer", fields: 1n }, + { name: "Bytes", fields: someBytes() }, + ], + }, + { name: "Map", fields: PlaMap.fromList([]) }, + { + name: "Map", + fields: PlaMap.fromList([[{ name: "Integer", fields: 1n }, { + name: "Bytes", + fields: someBytes(), + }], [{ name: "Integer", fields: 2n }, { + name: "Bytes", + fields: someMoreBytes(), + }]]), + }, + { name: "Integer", fields: 0n }, + { name: "Integer", fields: 1n }, + { name: "Integer", fields: -1n }, + { name: "Bytes", fields: emptyBytes() }, + { name: "Bytes", fields: nullBytes() }, + { name: "Bytes", fields: someBytes() }, + ]; +} + +/** + * Hard coded bytes test + */ +export function blake2b_256Hash(): LbrPlutusV1.LedgerBytes { + const arr = []; + for (let i = 1; i <= 32; ++i) { + arr.push(i); + } + + return Uint8Array.from(arr); +} + +/** + * Hard coded bytes test + */ +export function blake2b_224Hash(): LbrPlutusV1.LedgerBytes { + const arr = []; + for (let i = 1; i <= 28; ++i) { + arr.push(i); + } + + return Uint8Array.from(arr); +} + +/** + * Hard coded {@link Address} test + */ +export function addressGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const credential of credentialGoldens()) { + const mStakingCredentials: LbrPrelude.List< + LbrPrelude.Maybe + > = [{ name: "Nothing" }]; + for (const mStakingCredential of mStakingCredentials) { + res.push({ + addressCredential: credential, + addressStakingCredential: mStakingCredential, + }); + } + } + + for (const credential of credentialGoldens()) { + for (const stakingCredential of stakingCredentialGoldens()) { + const mStakingCredential: LbrPrelude.Maybe< + LbrPlutusV1.StakingCredential + > = { name: "Just", fields: stakingCredential }; + res.push({ + addressCredential: credential, + addressStakingCredential: mStakingCredential, + }); + } + } + + return res; +} + +/** + * Hard coded {@link Credential} test + */ +export function credentialGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const pubKeyHash of pubKeyHashGoldens()) { + res.push({ name: "PubKeyCredential", fields: pubKeyHash }); + } + + for (const scriptHash of scriptHashGoldens()) { + res.push({ name: "ScriptCredential", fields: scriptHash }); + } + + return res; +} + +function unsafeFromJust(maybe: LbrPrelude.Maybe): A { + if (maybe.name === "Just") { + return maybe.fields; + } else { + throw new Error(`unsafeFromJust error: got Nothing but expected Just`); + } +} + +/** + * Hard coded {@link PubKeyHash} test + */ +export function pubKeyHashGoldens(): LbrPrelude.List { + return [unsafeFromJust(PlaV1.pubKeyHashFromBytes(blake2b_224Hash()))]; +} + +/** + * Hard coded {@link ScriptHash} test + */ +export function scriptHashGoldens(): LbrPrelude.List { + return [unsafeFromJust(PlaV1.scriptHashFromBytes(blake2b_224Hash()))]; +} + +/** + * Hard coded {@link StakingCredential} test + */ +export function stakingCredentialGoldens(): LbrPrelude.List< + LbrPlutusV1.StakingCredential +> { + const res: LbrPrelude.List = []; + + for (const credential of credentialGoldens()) { + res.push({ name: "StakingHash", fields: credential }); + } + + res.push({ name: "StakingPtr", fields: [0n, 1n, 2n] }); + + return res; +} + +/** + * Hard coded {@link LedgerBytes} tests + */ +export function bytesGoldens(): LbrPrelude.List { + return [emptyBytes(), nullBytes(), someBytes()]; +} + +/** + * Hard coded {@link Interval} tests + */ +export function intervalGoldens(): LbrPrelude.List< + LbrPlutusV1.Interval +> { + const res: LbrPrelude.List> = []; + + for (const lb of lowerBoundGoldens()) { + for (const ub of upperBoundGoldens()) { + res.push({ ivFrom: lb, ivTo: ub }); + } + } + + return res; +} + +/** + * Hard coded {@link LowerBound} tests + */ +export function lowerBoundGoldens(): LbrPrelude.List< + LbrPlutusV1.LowerBound +> { + const res: LbrPrelude.List> = + []; + + for (const extended of extendedGoldens()) { + for (const closure of closureGoldens()) { + res.push([extended, closure]); + } + } + + return res; +} + +/** + * Hard coded {@link UpperBound} tests + */ +export function upperBoundGoldens(): LbrPrelude.List< + LbrPlutusV1.UpperBound +> { + const res: LbrPrelude.List> = + []; + + for (const extended of extendedGoldens()) { + for (const closure of closureGoldens()) { + res.push([extended, closure]); + } + } + + return res; +} + +/** + * Hard coded {@link Extended} tests + */ +export function extendedGoldens(): LbrPrelude.List< + LbrPlutusV1.Extended +> { + return [ + { name: "NegInf" }, + { name: "PosInf" }, + { + name: "Finite", + fields: 0n, + }, + ]; +} + +/** + * Hard coded {@link Closure} tests + */ +export function closureGoldens(): LbrPrelude.List { + return [true, false]; +} + +/** + * Hard coded {@link POSIXTime} tests + */ +export function posixTimeGoldens(): LbrPrelude.List { + return [0n, 1n, 2n]; +} + +/** + * Hard coded {@link POSIXTimeRange} tests + */ +export function posixTimeRangeGoldens(): LbrPrelude.List< + LbrPlutusV1.POSIXTimeRange +> { + return intervalGoldens(); +} + +/** + * Hard coded {@link CurrencySymbol} tests + */ +export function currencySymbolGoldens(): LbrPrelude.List< + LbrPlutusV1.CurrencySymbol +> { + return [unsafeFromJust(PlaV1.currencySymbolFromBytes(blake2b_224Hash()))]; +} + +/** + * Hard coded ada {@link CurrencySymbol} test + */ +export function adaCurrencySymbolGolden(): LbrPlutusV1.CurrencySymbol { + return PlaV1.adaSymbol; +} + +/** + * Hard coded {@link TokenName} tests + */ +export function tokenNameGoldens(): LbrPrelude.List { + const tn1 = unsafeFromJust(PlaV1.tokenNameFromBytes(emptyBytes())); + const tn2 = unsafeFromJust(PlaV1.tokenNameFromBytes( + ((arr: LbrPrelude.List) => { + for (let i = 1; i < 16; ++i) { + arr.push(i); + } + return Uint8Array.from(arr); + })([]), + )); + const tn3 = unsafeFromJust(PlaV1.tokenNameFromBytes( + ((arr: LbrPrelude.List) => { + for (let i = 1; i < 32; ++i) { + arr.push(i); + } + return Uint8Array.from(arr); + })([]), + )); + + return [tn1, tn2, tn3]; +} + +/** + * Hard coded {@link AssetClass} tests + */ +export function assetClassGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const currencySymbol of currencySymbolGoldens()) { + for (const tokenName of tokenNameGoldens()) { + res.push([currencySymbol, tokenName]); + } + } + + res.push([PlaV1.adaSymbol, PlaV1.adaToken]); + + return res; +} + +/** + * Hard coded {@link Value} tests + */ +export function valueGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const map of mapGoldens()) { + res.push(map); + } + + return res; +} + +/** + * Hard coded {@link Map} tests + */ +export function mapGoldens(): LbrPrelude.List< + LbrPlutusV1.Map< + LbrPlutusV1.CurrencySymbol, + LbrPlutusV1.Map + > +> { + return [ + PlaMap.fromList([]), + PlaMap.fromList< + LbrPlutusV1.CurrencySymbol, + LbrPlutusV1.Map + >( + [ + [ + PlaV1.adaSymbol, + PlaMap.fromList( + [[PlaV1.adaToken, 1337n]], + ), + ], + ], + ), + PlaMap.fromList< + LbrPlutusV1.CurrencySymbol, + LbrPlutusV1.Map + >( + [ + [ + PlaV1.adaSymbol, + PlaMap.fromList([[ + PlaV1.adaToken, + 1337n, + ]]), + ], + + [ + unsafeFromJust(PlaV1.currencySymbolFromBytes(blake2b_224Hash())), + PlaMap.fromList( + [ + [unsafeFromJust(PlaV1.tokenNameFromBytes(emptyBytes())), 1337n], + [ + unsafeFromJust(PlaV1.tokenNameFromBytes( + ((arr: LbrPrelude.List) => { + for (let i = 1; i < 16; ++i) { + arr.push(i); + } + return Uint8Array.from(arr); + })([]), + )), + 16n, + ], + [ + unsafeFromJust(PlaV1.tokenNameFromBytes( + ((arr: LbrPrelude.List) => { + for (let i = 1; i < 32; ++i) { + arr.push(i); + } + return Uint8Array.from(arr); + })([]), + )), + 32n, + ], + ], + ), + ], + ], + ), + ]; +} + +/** + * Hard coded {@link Redeemer} tests + */ +export function redeemerGoldens(): LbrPrelude.List { + return [ + { name: "Integer", fields: 1337n }, + ]; +} + +/** + * Hard coded {@link Datum} tests + */ +export function datumGoldens(): LbrPrelude.List { + return [ + { name: "Integer", fields: 1337n }, + ]; +} + +/** + * Hard coded {@link RedeemerHash} tests + */ +export function redeemerHashGoldens(): LbrPrelude.List< + LbrPlutusV1.RedeemerHash +> { + return [ + unsafeFromJust(PlaV1.redeemerHashFromBytes(blake2b_256Hash())), + ]; +} + +/** + * Hard coded {@link DatumHash} tests + */ +export function datumHashGoldens(): LbrPrelude.List { + return [ + unsafeFromJust(PlaV1.datumHashFromBytes(blake2b_256Hash())), + ]; +} + +/** + * Hard coded {@link TxId} tests + */ +export function txIdGoldens(): LbrPrelude.List { + return [ + unsafeFromJust(PlaV1.txIdFromBytes(blake2b_256Hash())), + ]; +} + +/** + * Hard coded {@link TxOutRef} tests + */ +export function txOutRefGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const txId of txIdGoldens()) { + for (const txIdx of [0n]) { + res.push({ txOutRefId: txId, txOutRefIdx: txIdx }); + } + } + + return res; +} + +// /* +// * Hard coded {@link TxInInfo} tests +// * TODO(jaredponn): this is borked -- this type doesn't actually exist in the .lbf file +// */ +// export function txInInfoGoldensV1() : LbrPrelude.List { +// const res : LbrPrelude.List = []; +// +// for (const txOutRef of txOutRefGoldens()) { +// for (const txOut of txOutGoldensV1()) { +// } +// } +// return res +// } + +// /* +// * Hard coded {@link TxOut} tests +// * TODO(jaredponn): this is borked -- this type doesn't actually exist in the .lbf file +// */ +// + +/* + * Plutus.V2 goldens + */ + +/** + * Hard coded {@link TxInInfo} tests + */ +export function txInInfoGoldensV2(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const txOutRef of txOutRefGoldens()) { + for (const txOut of txOutGoldensV2()) { + res.push({ txInInfoOutRef: txOutRef, txInInfoResolved: txOut }); + } + } + + return res; +} + +/** + * Hard coded {@link TxOut} tests + */ +export function txOutGoldensV2(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + const outDatums = outDatumGoldens(); + for (let outDatumIx = 0; outDatumIx < 1; ++outDatumIx) { + const mScriptHashes: LbrPrelude.List< + LbrPrelude.Maybe + > = [{ name: "Nothing" }]; + mScriptHashes.concat( + scriptHashGoldens().map((x) => { + return { fields: x, name: "Just" }; + }), + ); + + for (const mScriptHash of mScriptHashes) { + res.push( + { + txOutAddress: address, + txOutValue: value, + txOutDatum: outDatums[outDatumIx]!, + txOutReferenceScript: mScriptHash, + }, + ); + } + } + } + } + + return res; +} + +/** + * Hard coded {@link OutputDatum} tests + */ +export function outDatumGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + res.push({ name: "NoOutputDatum" }); + + for (const datumHash of datumHashGoldens()) { + res.push({ name: "OutputDatumHash", fields: datumHash }); + } + + for (const outputDatum of datumGoldens()) { + res.push({ name: "OutputDatum", fields: outputDatum }); + } + + return res; +} + +/* + * Foo.Bar goldens + */ + +/** + * Hardcoded {@link FooSum} tests + */ +export function fooSumGoldens( + x: A, + y: B, + z: C, +): LbrPrelude.List> { + return [ + { name: "Foo", fields: [x, y, z] }, + { name: "Bar", fields: [x, y] }, + { name: "Baz", fields: y }, + { name: "Qax" }, + { name: "Faz", fields: 0n }, + ]; +} + +/** + * Hardcoded {@link FooProd} tests + */ +export function fooProdGoldens( + x: A, + y: B, + z: C, +): LbfFooBar.FooProd[] { + return [[x, y, z, 1337n]]; +} + +/** + * Hard coded {@link FooRec} tests + */ +export function fooRecGoldens( + x: A, + y: B, + z: C, +): LbfFooBar.FooRec[] { + return [ + { fooA: x, fooB: y, fooC: z, fooInt: 1337n }, + ]; +} + +/* + * Foo goldens + */ + +/** + * Hard coded {@link A} tests + */ +export function aGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooSum of fooSumGoldens(address, value, datum)) { + res.push(fooSum); + } + } + } + } + return res; +} + +/** + * Hard coded {@link B} tests + */ +export function bGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooProd of fooProdGoldens(address, value, datum)) { + res.push(fooProd); + } + } + } + } + return res; +} + +/** + * Hard coded {@link C} tests + */ +export function cGoldens(): LbrPrelude.List { + const res: LbrPrelude.List = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooRec of fooRecGoldens(address, value, datum)) { + res.push(fooRec); + } + } + } + } + return res; +} + +/** + * Hard coded {@link D} tests + */ +export function dGoldens(): LbrPrelude.List { + let fooSums: LbrPrelude.List< + LbfFooBar.FooSum + > = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooSum of fooSumGoldens(address, value, datum)) { + fooSums.push(fooSum); + } + } + } + } + + fooSums = fooSums.slice(0, 2); + + let fooProds: LbrPrelude.List< + LbfFooBar.FooProd + > = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooProd of fooProdGoldens(address, value, datum)) { + fooProds.push(fooProd); + } + } + } + } + + fooProds = fooProds.slice(0, 2); + + let fooRecs: LbrPrelude.List< + LbfFooBar.FooRec + > = []; + + for (const address of addressGoldens()) { + for (const value of valueGoldens()) { + for (const datum of datumGoldens()) { + for (const fooRec of fooRecGoldens(address, value, datum)) { + fooRecs.push(fooRec); + } + } + } + } + + fooRecs = fooRecs.slice(0, 2); + + const fooComplicateds: LbrPrelude.List = []; + for (const fooSum of fooSums) { + for (const fooProd of fooProds) { + for (const fooRec of fooRecs) { + fooComplicateds.push( + { sum: fooSum, prod: fooProd, rec: fooRec }, + ); + } + } + } + + return fooComplicateds; +} + +/** + * Hard coded {@link FInt} tests + */ +export function fIntGoldens(): LbfFoo.FInt[] { + return [ + { name: "Nil" }, + { name: "Rec", fields: { name: "Rec", fields: { name: "Nil" } } }, + ]; +} + +/** + * Hard coded {@link GInt} tests + */ +export function gIntGoldens(): LbfFoo.GInt[] { + return [ + { name: "Nil" }, + { name: "Rec", fields: { name: "Rec", fields: { name: "Nil" } } }, + ]; +} + +/* + * Days goldens + */ + +/** + * Hard coded {@link Day} tests + */ +export function dayGoldens(): LbfDays.Day[] { + return [ + { name: "Monday" }, + { name: "Tuesday" }, + { name: "Wednesday" }, + { name: "Thursday" }, + { name: "Friday" }, + { name: "Saturday" }, + { name: "Sunday" }, + ]; +} + +/** + * Hard coded {@link WorkDay} tests + */ +export function workDayGoldens(): LbfDays.WorkDay[] { + return [{ name: "Monday" }, { name: "Tuesday" }, { name: "Wednesday" }, { + name: "Thursday", + }, { name: "Friday" }]; +} + +/** + * Hard coded {@link FreeDay} tests + */ +export function freeDayGoldens(): LbfDays.FreeDay[] { + return [{ day: { name: "Saturday" } }, { day: { name: "Sunday" } }]; +} + +/* + * Prelude goldens + */ + +/** + * Hard coded {@link Bool} tests + */ +export function boolGoldens(): LbrPrelude.Bool[] { + return [false, true]; +} + +/** + * Hard coded {@link Maybe} tests + */ +export function maybeGoldens(): LbrPrelude.Maybe[] { + return [{ name: "Nothing" }, { name: "Just", fields: true }, { + name: "Just", + fields: false, + }]; +} + +/** + * Hard coded {@link Either} tests + */ +export function eitherGoldens(): LbrPrelude.Either< + LbrPrelude.Bool, + LbrPrelude.Bool +>[] { + return [{ name: "Left", fields: true }, { name: "Left", fields: false }, { + name: "Right", + fields: true, + }]; +} + +/** + * Hard coded {@link List} tests + */ +export function listGoldens(): LbrPrelude.List[] { + return [[], [true], [false], [true, true, false, false]]; +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/Json-test.ts b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Json-test.ts new file mode 100644 index 00000000..29031606 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Json-test.ts @@ -0,0 +1,480 @@ +import { describe, it } from "node:test"; + +import * as Utils from "./Utils.js"; + +import * as Goldens from "./Goldens.js"; + +import * as LbrPrelude from "lbr-prelude"; +import * as PreludeJson from "prelude/Json.js"; + +import * as LbrPlutusV1 from "lbr-plutus/V1.js"; +import * as LbrPlutusV2 from "lbr-plutus/V2.js"; + +describe("JSON tests (toJson . fromJson)", () => { + const goldenDir = `data/lbt-plutus-golden-data`; + + it(`PlutusV1.PlutusData from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.PlutusData\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson, + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson, + PreludeJson.stringify, + ), + Goldens.plutusDataGoldens(), + ); + }); + + it(`PlutusV1.Address from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Address\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Address].fromJson, + LbrPrelude.Json[LbrPlutusV1.Address].toJson, + PreludeJson.stringify, + ), + Goldens.addressGoldens(), + ); + }); + + it(`PlutusV1.Credential from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Credential\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Credential].fromJson, + LbrPrelude.Json[LbrPlutusV1.Credential].toJson, + PreludeJson.stringify, + ), + Goldens.credentialGoldens(), + ); + }); + + it(`PlutusV1.StakingCredential from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.StakingCredential\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.StakingCredential].fromJson, + LbrPrelude.Json[LbrPlutusV1.StakingCredential].toJson, + PreludeJson.stringify, + ), + Goldens.stakingCredentialGoldens(), + ); + }); + + it(`PlutusV1.PubKeyHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.PubKeyHash\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.PubKeyHash].fromJson, + LbrPrelude.Json[LbrPlutusV1.PubKeyHash].toJson, + PreludeJson.stringify, + ), + Goldens.pubKeyHashGoldens(), + ); + }); + + it(`PlutusV1.Bytes from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Bytes\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.LedgerBytes].fromJson, + LbrPrelude.Json[LbrPlutusV1.LedgerBytes].toJson, + PreludeJson.stringify, + ), + Goldens.bytesGoldens(), + ); + }); + + it(`PlutusV1.Interval from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Interval\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Interval]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).fromJson, + LbrPrelude.Json[LbrPlutusV1.Interval]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).toJson, + PreludeJson.stringify, + ), + Goldens.intervalGoldens(), + ); + }); + + it(`PlutusV1.Extended from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Extended\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Extended]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).fromJson, + LbrPrelude.Json[LbrPlutusV1.Extended]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).toJson, + PreludeJson.stringify, + ), + Goldens.extendedGoldens(), + ); + }); + + it(`PlutusV1.LowerBound from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.LowerBound\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.LowerBound]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).fromJson, + LbrPrelude.Json[LbrPlutusV1.LowerBound]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).toJson, + PreludeJson.stringify, + ), + Goldens.lowerBoundGoldens(), + ); + }); + + it(`PlutusV1.UpperBound from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.UpperBound\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.UpperBound]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).fromJson, + LbrPrelude.Json[LbrPlutusV1.UpperBound]( + LbrPrelude.Json[LbrPlutusV1.POSIXTime], + ).toJson, + PreludeJson.stringify, + ), + Goldens.upperBoundGoldens(), + ); + }); + + it(`PlutusV1.POSIXTime from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.POSIXTime\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.POSIXTime].fromJson, + LbrPrelude.Json[LbrPlutusV1.POSIXTime].toJson, + PreludeJson.stringify, + ), + Goldens.posixTimeGoldens(), + ); + }); + + it(`PlutusV1.POSIXTimeRange from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.POSIXTimeRange\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.POSIXTimeRange].fromJson, + LbrPrelude.Json[LbrPlutusV1.POSIXTimeRange].toJson, + PreludeJson.stringify, + ), + Goldens.posixTimeRangeGoldens(), + ); + }); + + it(`PlutusV1.CurrencySymbol from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.CurrencySymbol\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.CurrencySymbol].fromJson, + LbrPrelude.Json[LbrPlutusV1.CurrencySymbol].toJson, + PreludeJson.stringify, + ), + [Goldens.adaCurrencySymbolGolden()].concat( + Goldens.currencySymbolGoldens(), + ), + ); + }); + + it(`PlutusV1.TokenName from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TokenName\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.TokenName].fromJson, + LbrPrelude.Json[LbrPlutusV1.TokenName].toJson, + PreludeJson.stringify, + ), + Goldens.tokenNameGoldens(), + ); + }); + + it(`PlutusV1.AssetClass from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.AssetClass\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.AssetClass].fromJson, + LbrPrelude.Json[LbrPlutusV1.AssetClass].toJson, + PreludeJson.stringify, + ), + Goldens.assetClassGoldens(), + ); + }); + + it(`PlutusV1.Value from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Value\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Value].fromJson, + LbrPrelude.Json[LbrPlutusV1.Value].toJson, + PreludeJson.stringify, + ), + Goldens.valueGoldens(), + ); + }); + + it(`PlutusV1.Redeemer from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Redeemer\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Redeemer].fromJson, + LbrPrelude.Json[LbrPlutusV1.Redeemer].toJson, + PreludeJson.stringify, + ), + Goldens.redeemerGoldens(), + ); + }); + + it(`PlutusV1.Datum from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Datum\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Datum].fromJson, + LbrPrelude.Json[LbrPlutusV1.Datum].toJson, + PreludeJson.stringify, + ), + Goldens.datumGoldens(), + ); + }); + + it(`PlutusV1.RedeemerHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.RedeemerHash\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.RedeemerHash].fromJson, + LbrPrelude.Json[LbrPlutusV1.RedeemerHash].toJson, + PreludeJson.stringify, + ), + Goldens.redeemerHashGoldens(), + ); + }); + + it(`PlutusV1.DatumHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.DatumHash\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.DatumHash].fromJson, + LbrPrelude.Json[LbrPlutusV1.DatumHash].toJson, + PreludeJson.stringify, + ), + Goldens.datumHashGoldens(), + ); + }); + + it(`PlutusV1.ScriptHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.ScriptHash\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.ScriptHash].fromJson, + LbrPrelude.Json[LbrPlutusV1.ScriptHash].toJson, + PreludeJson.stringify, + ), + Goldens.scriptHashGoldens(), + ); + }); + + it(`PlutusV1.TxId from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TxId\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.TxId].fromJson, + LbrPrelude.Json[LbrPlutusV1.TxId].toJson, + PreludeJson.stringify, + ), + Goldens.txIdGoldens(), + ); + }); + + it(`PlutusV1.TxOutRef from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TxOutRef\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.TxOutRef].fromJson, + LbrPrelude.Json[LbrPlutusV1.TxOutRef].toJson, + PreludeJson.stringify, + ), + Goldens.txOutRefGoldens(), + ); + }); + + it(`PlutusV1.Map from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Map\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV1.Map]( + LbrPrelude.Json[LbrPlutusV1.CurrencySymbol], + LbrPrelude.Json[LbrPlutusV1.Map]( + LbrPrelude.Json[LbrPlutusV1.TokenName], + LbrPrelude.Json[LbrPrelude.Integer], + ), + ).fromJson, + LbrPrelude.Json[LbrPlutusV1.Map]( + LbrPrelude.Json[LbrPlutusV1.CurrencySymbol], + LbrPrelude.Json[LbrPlutusV1.Map]( + LbrPrelude.Json[LbrPlutusV1.TokenName], + LbrPrelude.Json[LbrPrelude.Integer], + ), + ).toJson, + PreludeJson.stringify, + ), + Goldens.mapGoldens(), + ); + }); + + // TODO(jaredponn): TxInInfo V1 doesn't exist yet + // TODO(jaredponn): TxOut V1 doesn't exist yet + + it(`PlutusV2.TxInInfo from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.TxInInfo\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV2.TxInInfo].fromJson, + LbrPrelude.Json[LbrPlutusV2.TxInInfo].toJson, + PreludeJson.stringify, + ), + Goldens.txInInfoGoldensV2(), + ); + }); + + it(`PlutusV2.OutputDatum from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.OutputDatum\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV2.OutputDatum].fromJson, + LbrPrelude.Json[LbrPlutusV2.OutputDatum].toJson, + PreludeJson.stringify, + ), + Goldens.outDatumGoldens(), + ); + }); + + it(`PlutusV2.TxOut from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.TxOut\.[0-9]*\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + LbrPrelude.Json[LbrPlutusV2.TxOut].fromJson, + LbrPrelude.Json[LbrPlutusV2.TxOut].toJson, + PreludeJson.stringify, + ), + Goldens.txOutGoldensV2(), + ); + }); +}); diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/PlutusData-test.ts b/testsuites/lbt-plutus/lbt-plutus-typescript/src/PlutusData-test.ts new file mode 100644 index 00000000..4a71ae3c --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/PlutusData-test.ts @@ -0,0 +1,1051 @@ +import { describe, it } from "node:test"; + +import * as Utils from "./Utils.js"; + +import * as Goldens from "./Goldens.js"; + +import * as LbrPrelude from "lbr-prelude"; +import * as PreludeJson from "prelude/Json.js"; + +import * as LbfFoo from "lbf-plutus-golden-api/LambdaBuffers/Foo.mjs"; +import * as LbfDays from "lbf-plutus-golden-api/LambdaBuffers/Days.mjs"; + +import * as LbrPlutusV1 from "lbr-plutus/V1.js"; +import * as LbrPlutusV2 from "lbr-plutus/V2.js"; + +/** + * Loosely, we're testing something along the lines of: + * ``` + * toJson . toPlutusData . fromPlutusData . fromJson + * ``` + */ +describe("PlutusData tests (toJson . toPlutusData . fromPlutusData . fromJson)", () => { + const goldenDir = `data/lbt-plutus-golden-data`; + + describe("Foo tests", () => { + it(`Foo.A from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.A\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.A] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.A] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.aGoldens(), + ); + }); + + it(`Foo.B from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.B\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.B] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.B] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.bGoldens(), + ); + }); + + it(`Foo.C from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.C\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.C] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.C] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.cGoldens(), + ); + }); + + it(`Foo.D from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.D\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.D] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.D] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.dGoldens(), + ); + }); + + it(`Foo.FInt from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.FInt\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.FInt] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.FInt] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.fIntGoldens(), + ); + }); + + it(`Foo.GInt from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Foo\.GInt\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfFoo.GInt] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfFoo.GInt] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.gIntGoldens(), + ); + }); + }); + + describe("Day tests", () => { + it(`Days.Day from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Days\.Day\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfDays.Day] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfDays.Day] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.dayGoldens(), + ); + }); + + it(`Days.WorkDay from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Days\.WorkDay\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfDays.WorkDay] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfDays.WorkDay] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.workDayGoldens(), + ); + }); + + it(`Days.FreeDay from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Days\.FreeDay\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbfDays.FreeDay] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbfDays.FreeDay] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.freeDayGoldens(), + ); + }); + }); + + describe("Plutus tests", () => { + it(`PlutusV1.PlutusData from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.PlutusData\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.PlutusData] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.PlutusData] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.plutusDataGoldens(), + ); + }); + + it(`PlutusV1.Address from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Address\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Address] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Address] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.addressGoldens(), + ); + }); + + it(`PlutusV1.Credential from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Credential\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Credential] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Credential] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.credentialGoldens(), + ); + }); + + it(`PlutusV1.StakingCredential from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.StakingCredential\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.StakingCredential] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.StakingCredential] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.stakingCredentialGoldens(), + ); + }); + + it(`PlutusV1.PubKeyHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.PubKeyHash\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.PubKeyHash] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.PubKeyHash] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.pubKeyHashGoldens(), + ); + }); + + it(`PlutusV1.Bytes from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Bytes\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.LedgerBytes] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.LedgerBytes] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.bytesGoldens(), + ); + }); + + it(`PlutusV1.Interval from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Interval\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Interval]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Interval]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.intervalGoldens(), + ); + }); + + it(`PlutusV1.Extended from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Extended\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Extended]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Extended]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.extendedGoldens(), + ); + }); + + it(`PlutusV1.LowerBound from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.LowerBound\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.LowerBound]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.LowerBound]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.lowerBoundGoldens(), + ); + }); + + it(`PlutusV1.UpperBound from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.UpperBound\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.UpperBound]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.UpperBound]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.POSIXTime], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.upperBoundGoldens(), + ); + }); + + it(`PlutusV1.POSIXTime from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.POSIXTime\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.POSIXTime] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.POSIXTime] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.posixTimeGoldens(), + ); + }); + + it(`PlutusV1.POSIXTimeRange from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.POSIXTimeRange\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.POSIXTimeRange] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.POSIXTimeRange] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.posixTimeRangeGoldens(), + ); + }); + + it(`PlutusV1.CurrencySymbol from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.CurrencySymbol\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.CurrencySymbol] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.CurrencySymbol] + .toData(v), + ), + PreludeJson.stringify, + ), + [Goldens.adaCurrencySymbolGolden()].concat( + Goldens.currencySymbolGoldens(), + ), + ); + }); + + it(`PlutusV1.TokenName from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TokenName\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TokenName] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TokenName] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.tokenNameGoldens(), + ); + }); + + it(`PlutusV1.AssetClass from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.AssetClass\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.AssetClass] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.AssetClass] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.assetClassGoldens(), + ); + }); + + it(`PlutusV1.Value from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Value\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Value] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Value] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.valueGoldens(), + ); + }); + + it(`PlutusV1.Redeemer from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Redeemer\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Redeemer] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Redeemer] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.redeemerGoldens(), + ); + }); + + it(`PlutusV1.Datum from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Datum\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Datum] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.Datum] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.datumGoldens(), + ); + }); + + it(`PlutusV1.RedeemerHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.RedeemerHash\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.RedeemerHash] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.RedeemerHash] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.redeemerHashGoldens(), + ); + }); + + it(`PlutusV1.DatumHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.DatumHash\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.DatumHash] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.DatumHash] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.datumHashGoldens(), + ); + }); + + it(`PlutusV1.ScriptHash from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.ScriptHash\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.ScriptHash] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.ScriptHash] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.scriptHashGoldens(), + ); + }); + + it(`PlutusV1.TxId from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TxId\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TxId] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TxId] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.txIdGoldens(), + ); + }); + + it(`PlutusV1.TxOutRef from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.TxOutRef\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TxOutRef] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV1.TxOutRef] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.txOutRefGoldens(), + ); + }); + + it(`PlutusV1.Map from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV1\.Map\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1.IsPlutusData[LbrPlutusV1.Map]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.CurrencySymbol], + LbrPlutusV1.IsPlutusData[LbrPlutusV1.Map]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.TokenName], + LbrPlutusV1.IsPlutusData[LbrPrelude.Integer], + ), + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.Map]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.CurrencySymbol], + LbrPlutusV1.IsPlutusData[LbrPlutusV1.Map]( + LbrPlutusV1.IsPlutusData[LbrPlutusV1.TokenName], + LbrPlutusV1.IsPlutusData[LbrPrelude.Integer], + ), + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.mapGoldens(), + ); + }); + + // TODO(jaredponn) TxInInfo V1 missing + // TODO(jaredponn) TxOut V1 missing + + it(`PlutusV2.TxInInfo from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.TxInInfo\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.TxInInfo] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.TxInInfo] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.txInInfoGoldensV2(), + ); + }); + + it(`PlutusV2.OutputDatum from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.OutputDatum\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.OutputDatum] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.OutputDatum] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.outDatumGoldens(), + ); + }); + + it(`PlutusV2.TxOut from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^PlutusV2\.TxOut\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.TxOut] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData].fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPlutusV2.TxOut] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.txOutGoldensV2(), + ); + }); + }); + + describe("Prelude tests", () => { + it(`Prelude.Bool from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Prelude\.Bool\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Bool] + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Bool] + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.boolGoldens(), + ); + }); + + it(`Prelude.Maybe from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Prelude\.Maybe\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Maybe]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Maybe]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.maybeGoldens(), + ); + }); + + it(`Prelude.Either from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Prelude\.Either\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Either]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPrelude.Either]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.eitherGoldens(), + ); + }); + + it(`Prelude.List from to golden tests`, async () => { + await Utils.fromToGoldenTest( + goldenDir, + new Utils.RegExpFileFilter( + /^Prelude\.List\.[0-9]*\.pd\.json$/g, + ), + Utils.mkFromToAssertGolden( + PreludeJson.parseJson, + (v) => + LbrPlutusV1 + .IsPlutusData[LbrPrelude.List]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .fromData(LbrPrelude.Json[LbrPlutusV1.PlutusData] + .fromJson(v)), + (v) => + LbrPrelude.Json[LbrPlutusV1.PlutusData].toJson( + LbrPlutusV1 + .IsPlutusData[LbrPrelude.List]( + LbrPlutusV1.IsPlutusData[LbrPrelude.Bool], + ) + .toData(v), + ), + PreludeJson.stringify, + ), + Goldens.listGoldens(), + ); + }); + }); +}); diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts new file mode 100644 index 00000000..cf73f25b --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts @@ -0,0 +1,122 @@ +import { it } from "node:test"; +import * as assert from "node:assert/strict"; +import * as Fs from "node:fs/promises"; +import * as Path from "node:path"; + +// WARNING(jaredponn): {@link findGoldens} and {@link fromToGoldenTest} are +// essentially duplicated code (well minor generalizations) of the same testing functions in + +/** +/* @param goldenDir: directory for the golden files +/* @param regexFileFilter: see {@link RegExpFileFilter}. + */ +export async function findGoldens( + goldenDir: string, + regexFileFilter: RegExpFileFilter, +): Promise<[string, string][]> { + const files: string[] = await Fs.readdir(goldenDir, { recursive: true }); + + const filteredFiles: [string, string][] = []; + for (const file of files) { + const filtered = regexFileFilter.match(file); + if (typeof filtered === "string") { + filteredFiles.push( + [Path.join(goldenDir, file), filtered], + ); + } + } + return filteredFiles; +} + +/** + * Wraps a regular expression s.t. when matching strings, we match + * `basename().match()` + */ +export class RegExpFileFilter { + #regexp: RegExp; + + /** + * @param `.match(regexp)` must either match with exactly one string, or + * not match at all. + */ + constructor(regexp: Readonly) { + this.#regexp = regexp; + } + + match(filepath: string): string | null { + const matches = Path.basename(filepath).match(this.#regexp); + if (matches === null) { + return null; + } else if (matches.length === 1) { + return matches[0]; + } else { + throw new Error( + `RegExpFileFilter: regex \`${this.#regexp}\` produced matches \`${matches}\` for \`${filepath}\`, but should only produce exactly one match`, + ); + } + } + + toString(): string { + return this.#regexp.toString(); + } +} + +export async function fromToGoldenTest( + goldenDir: string, + regexFileFilter: RegExpFileFilter, + // assertGolden: function which asserts whether the test is valid. + // index: golden test file name (excluding extension) + // content: the contents of the golden test file (assumed to be UTF8 encoded + // file). + assertGolden: (index: string, content: string) => void, + goldens: A[], +): Promise { + const foundGoldens: [string, string][] = await findGoldens( + goldenDir, + regexFileFilter, + ); + + if (foundGoldens.length !== goldens.length) { + const errMsg = + `lbt-plutus-typescript: warning: expected to find ${goldens.length} golden files for ${regexFileFilter} in ${goldenDir}, but got ${foundGoldens.length}. Forgot to (re)generate the goldens? Or there is a mismatch between the TS goldens and generated Haskell goldens`; + console.warn(errMsg); // TODO(jaredponn): apparently there is a mismatch between the TS goldens + // and the HS goldens.. The HS script apparently only likes outputting 10 + // golden tests when there are clearly more for things like e.g. + // PlutusData. + // One day, add this back in the future: + // ``` + // assert.fail(errMsg) + // ``` + } + + for (const [filepath, index] of foundGoldens) { + const contents = await Fs.readFile(filepath, { encoding: "utf8" }); + + it(`${index}: at ${filepath}`, () => { + assertGolden(index, contents); + }); + } +} + +export function mkFromToAssertGolden( + deserialise: (contents: string) => A, + from: (a: A) => B, + to: (b: B) => A, + serialise: (a: A) => string, +): (index: string, contents: string) => void { + return (index: string, contents: string) => { + try { + const fromTo = serialise(to(from(deserialise(contents)))); + + if (contents !== fromTo) { + assert.fail( + `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromTo}\``, + ); + } + } catch (err) { + assert.fail( + `Golden test failed for ${index} since an error was thrown: \`${err}\`.`, + ); + } + }; +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/tsconfig.json b/testsuites/lbt-plutus/lbt-plutus-typescript/src/tsconfig.json new file mode 100644 index 00000000..fcab6f23 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../tsconfig-base", + "include": ["*"], + "references": [ ] +} diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/tsconfig-base.json b/testsuites/lbt-plutus/lbt-plutus-typescript/tsconfig-base.json new file mode 100644 index 00000000..56c4c468 --- /dev/null +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/tsconfig-base.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "node16", /* Specify what module code is generated. */ + "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + /// "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 96062b5f9b043d70d8a596459cd3e3a2ad00e2c6 Mon Sep 17 00:00:00 2001 From: jared <> Date: Sun, 28 Jan 2024 22:15:35 -0700 Subject: [PATCH 09/14] Add `Map` instances to lbr-plutus-typescript --- .../src/LambdaBuffers/V1/Instances.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts index ca3808c2..f84d8eea 100644 --- a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts +++ b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/V1/Instances.ts @@ -1,5 +1,6 @@ import * as PlutusData from "../PlutusData.js"; import * as PlutusLedgerApiPlutusData from "plutus-ledger-api/PlutusData.js"; +import * as PlutusLedgerApiAssocMap from "plutus-ledger-api/AssocMap.js"; import * as PlutusLedgerApiV1 from "plutus-ledger-api/V1.js"; import * as LbrPrelude from "lbr-prelude"; import * as Prelude from "prelude"; @@ -602,3 +603,35 @@ declare module "../PlutusData.js" { } PlutusData.IsPlutusData[Symbols.PlutusData] = PlutusLedgerApiPlutusData.isPlutusDataPlutusData; + +// Map +declare module "lbr-prelude" { + export interface EqInstances { + [Symbols.Map]: ( + dictK: Prelude.Eq, + dictV: Prelude.Eq, + ) => Prelude.Eq>; + } + + export interface JsonInstances { + [Symbols.Map]: ( + dictK: Prelude.Json, + dictV: Prelude.Json, + ) => Prelude.Json>; + } +} + +LbrPrelude.Eq[Symbols.Map] = PlutusLedgerApiAssocMap.eqMap; +LbrPrelude.Json[Symbols.Map] = PlutusLedgerApiAssocMap.jsonMap; + +declare module "../PlutusData.js" { + export interface IsPlutusDataInstances { + [Symbols.Map]: ( + dictK: PlutusLedgerApiPlutusData.IsPlutusData, + dictV: PlutusLedgerApiPlutusData.IsPlutusData, + ) => PlutusLedgerApiPlutusData.IsPlutusData< + PlutusLedgerApiAssocMap.Map + >; + } +} +PlutusData.IsPlutusData[Symbols.Map] = PlutusLedgerApiAssocMap.isPlutusDataMap; From dc5ee6797d1230661d6bb3dfa658eddeadd7cb60 Mon Sep 17 00:00:00 2001 From: jared <> Date: Mon, 29 Jan 2024 00:13:33 -0700 Subject: [PATCH 10/14] Added IsPlutusData List instance to lbr-plutus-typescript --- runtimes/typescript/lbr-plutus/src/LambdaBuffers/PlutusData.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/PlutusData.ts b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/PlutusData.ts index da8f648e..40a39d49 100644 --- a/runtimes/typescript/lbr-plutus/src/LambdaBuffers/PlutusData.ts +++ b/runtimes/typescript/lbr-plutus/src/LambdaBuffers/PlutusData.ts @@ -54,3 +54,5 @@ export interface IsPlutusDataInstances { dictA: PlutusLedgerApiPlutusData.IsPlutusData, ) => PlutusLedgerApiPlutusData.IsPlutusData>; } +IsPlutusData[LbrPrelude.List] = + PlutusLedgerApiPreludeInstances.isPlutusDataList; From 7ceac2c51f852dc4b32fddfae2f6600fe6633947 Mon Sep 17 00:00:00 2001 From: jared <> Date: Mon, 29 Jan 2024 00:19:09 -0700 Subject: [PATCH 11/14] Update flake.lock --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index cf791d86..519be85e 100644 --- a/flake.lock +++ b/flake.lock @@ -50671,11 +50671,11 @@ "prelude-typescript": "prelude-typescript" }, "locked": { - "lastModified": 1706413121, - "narHash": "sha256-NsmQOF+ZyQZhMl9mLWdxAGCgdWPDRqsWXFMycQImvQQ=", + "lastModified": 1706512604, + "narHash": "sha256-1FaRbJbky7EHdSNJh9dSoiTw08Tn21g/uOe9UkZ2pns=", "owner": "mlabs-haskell", "repo": "plutus-ledger-api-typescript", - "rev": "fec4dc20307b20c9fd5ddec9db157786ef9d2162", + "rev": "1cc41a1c3be1057349113e53c79dd8c270d3cad4", "type": "github" }, "original": { From 5986a31a64676d1ee25fd81ca1a15fe8cf1e83b0 Mon Sep 17 00:00:00 2001 From: jared <> Date: Mon, 29 Jan 2024 13:46:58 -0700 Subject: [PATCH 12/14] Code cleanup --- .../lbt-plutus-typescript/.gitignore | 2 + .../lbt-plutus-typescript/package.json | 3 +- .../lbt-plutus-typescript/src/Utils.ts | 31 ++++++++++++---- .../lbt-prelude-typescript/.gitignore | 2 + .../lbt-prelude-typescript/package.json | 3 +- .../lbt-prelude-typescript/src/Json-test.ts | 37 +++++++++---------- 6 files changed, 49 insertions(+), 29 deletions(-) diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore b/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore index a3c20529..c8d23906 100644 --- a/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/.gitignore @@ -1,2 +1,4 @@ +# Ignore the autogenerated files from flake-lang.nix .extra-dependencies data +node_modules diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/package.json b/testsuites/lbt-plutus/lbt-plutus-typescript/package.json index 1b02d6d7..c92727cd 100644 --- a/testsuites/lbt-plutus/lbt-plutus-typescript/package.json +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/package.json @@ -14,7 +14,8 @@ "author": "Jared Pon", "license": "ISC", "files": [ - "./dist/**/*" + "./dist/**/*", + "./.extra-dependencies/**/*" ], "devDependencies": { "@types/node": "^20.11.7", diff --git a/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts index cf73f25b..62efab0e 100644 --- a/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts +++ b/testsuites/lbt-plutus/lbt-plutus-typescript/src/Utils.ts @@ -4,11 +4,14 @@ import * as Fs from "node:fs/promises"; import * as Path from "node:path"; // WARNING(jaredponn): {@link findGoldens} and {@link fromToGoldenTest} are -// essentially duplicated code (well minor generalizations) of the same testing functions in +// essentially duplicated code (well minor generalizations) of the same testing +// functions in the lbt-prelude testsuite. /** /* @param goldenDir: directory for the golden files /* @param regexFileFilter: see {@link RegExpFileFilter}. + * +/* @returns Tuple of [path to golden file, the resulting "regexFileFilter"ed file] */ export async function findGoldens( goldenDir: string, @@ -61,6 +64,13 @@ export class RegExpFileFilter { } } +/** + * Runs golden tests in the provided `goldenDir` which satisfy the + * `regexFileFilter` where the test passes if `assertGolden` does not throw an + * exception. Note that `goldens` is essentially unused and is only used to + * warn if the number of the TS representation of equivalent HS generated tests + * match. + */ export async function fromToGoldenTest( goldenDir: string, regexFileFilter: RegExpFileFilter, @@ -78,26 +88,31 @@ export async function fromToGoldenTest( if (foundGoldens.length !== goldens.length) { const errMsg = - `lbt-plutus-typescript: warning: expected to find ${goldens.length} golden files for ${regexFileFilter} in ${goldenDir}, but got ${foundGoldens.length}. Forgot to (re)generate the goldens? Or there is a mismatch between the TS goldens and generated Haskell goldens`; + `lbt-plutus-typescript: warning: expected to find ${goldens.length} golden files for ${regexFileFilter} in ${goldenDir}, but got ${foundGoldens.length}. Forgot to (re)generate the goldens? Or there is a mismatch in the number of TS goldens and generated Haskell goldens`; console.warn(errMsg); // TODO(jaredponn): apparently there is a mismatch between the TS goldens - // and the HS goldens.. The HS script apparently only likes outputting 10 - // golden tests when there are clearly more for things like e.g. - // PlutusData. + // and the HS goldens.. The HS script apparently only likes outputting at most 10 + // golden tests when there are clearly more tests (e.g. + // PlutusData has many more tests than just 10) // One day, add this back in the future: // ``` // assert.fail(errMsg) // ``` + // Note this doesn't actually effect the correctness of the tests. } for (const [filepath, index] of foundGoldens) { - const contents = await Fs.readFile(filepath, { encoding: "utf8" }); - - it(`${index}: at ${filepath}`, () => { + await it(`${index} at ${filepath}`, async () => { + const contents = await Fs.readFile(filepath, { encoding: "utf8" }); assertGolden(index, contents); }); } } +/** + * @returns a function which throws an exception if + * `serialise(to(from(deserialise(contents)))) != contents` (or any of + * `serialise`, `to`, `from`, `deserialise` throws an exception) + */ export function mkFromToAssertGolden( deserialise: (contents: string) => A, from: (a: A) => B, diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore index a3c20529..c8d23906 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/.gitignore @@ -1,2 +1,4 @@ +# Ignore the autogenerated files from flake-lang.nix .extra-dependencies data +node_modules diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/package.json b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json index 6f6ef5ea..5c2b1d38 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/package.json +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/package.json @@ -14,7 +14,8 @@ "author": "Jared Pon", "license": "ISC", "files": [ - "./dist/**/*" + "./dist/**/*", + "./.extra-dependencies/**/*" ], "devDependencies": { "@types/node": "^20.11.7", diff --git a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts index d30bab64..b9353ea4 100644 --- a/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts +++ b/testsuites/lbt-prelude/lbt-prelude-typescript/src/Json-test.ts @@ -49,34 +49,33 @@ export async function fromToGoldenTest( } for (const [filepath, index] of foundGoldens) { - const contents = await Fs.readFile(filepath, { encoding: "utf8" }); + await it(`${index} at ${filepath}`, async () => { + const contents = await Fs.readFile(filepath, { encoding: "utf8" }); - try { - const fromToJson = PreludeJson.stringify( - jsonDict.toJson( - jsonDict.fromJson( - PreludeJson.parseJson(contents), + try { + const fromToJson = PreludeJson.stringify( + jsonDict.toJson( + jsonDict.fromJson( + PreludeJson.parseJson(contents), + ), ), - ), - ); + ); - // TODO(jaredponn). This fails on the _first_ test instead of - // accumulating all of them.. Perhaps we want to accumulate all of - // them by e.g. wrapping this with `it`. - if (contents !== fromToJson) { + if (contents !== fromToJson) { + assert.fail( + `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromToJson}\``, + ); + } + } catch (err) { assert.fail( - `Golden test failed for ${index}. Expected:\n\`${contents}\`\nbut got\n\`${fromToJson}\``, + `Golden test failed for ${index} since an error was thrown: \`${err}\`.`, ); } - } catch (err) { - assert.fail( - `Golden test failed for ${index} since an error was thrown: \`${err}\`.`, - ); - } + }); } } -describe("JSON tests", () => { +describe("JSON tests (toJson . fromJson)", () => { const goldenDir = `data/lbt-prelude-golden-data`; it(`Foo.A from to golden tests`, async () => { await fromToGoldenTest( From 1d806a1710aab625ea520c596a72338c5bde578d Mon Sep 17 00:00:00 2001 From: jared <> Date: Wed, 31 Jan 2024 22:36:37 -0700 Subject: [PATCH 13/14] Refactored `lbf-typescript` to return the tgz file directly --- docs/typescript-plutus/api/lbf/build.nix | 4 ++-- docs/typescript-plutus/build.nix | 2 +- docs/typescript-prelude/api/lbf/build.nix | 4 ++-- docs/typescript-prelude/build.nix | 2 +- extras/lbf-nix/lbf-typescript.nix | 2 +- libs/build.nix | 8 ++++---- testsuites/lbt-plutus/api/build.nix | 5 ++--- testsuites/lbt-prelude/api/build.nix | 4 ++-- 8 files changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/typescript-plutus/api/lbf/build.nix b/docs/typescript-plutus/api/lbf/build.nix index 6665ae23..8edbbba5 100644 --- a/docs/typescript-plutus/api/lbf/build.nix +++ b/docs/typescript-plutus/api/lbf/build.nix @@ -2,7 +2,7 @@ _: { perSystem = { config, ... }: let - tsFlake = + lbf-plutus-sample-project-typescript = config.lbf-nix.lbfPlutusTypescript { name = "lbf-plutus-sample-project"; src = ./.; @@ -11,7 +11,7 @@ _: in { packages = { - inherit (tsFlake.packages) lbf-plutus-sample-project-typescript lbf-plutus-sample-project-typescript-tgz; + inherit lbf-plutus-sample-project-typescript; }; }; } diff --git a/docs/typescript-plutus/build.nix b/docs/typescript-plutus/build.nix index d3c449de..d2e78696 100644 --- a/docs/typescript-plutus/build.nix +++ b/docs/typescript-plutus/build.nix @@ -10,7 +10,7 @@ src = ./.; npmExtraDependencies = [ - config.packages.lbf-plutus-sample-project-typescript-tgz + config.packages.lbf-plutus-sample-project-typescript ]; devShellTools = config.settings.shell.tools; diff --git a/docs/typescript-prelude/api/lbf/build.nix b/docs/typescript-prelude/api/lbf/build.nix index d4b983bb..82638851 100644 --- a/docs/typescript-prelude/api/lbf/build.nix +++ b/docs/typescript-prelude/api/lbf/build.nix @@ -2,7 +2,7 @@ _: { perSystem = { config, ... }: let - tsFlake = + lbf-prelude-sample-project-typescript = config.lbf-nix.lbfPreludeTypescript { name = "lbf-prelude-sample-project"; src = ./.; @@ -11,7 +11,7 @@ _: in { packages = { - inherit (tsFlake.packages) lbf-prelude-sample-project-typescript lbf-prelude-sample-project-typescript-tgz; + inherit lbf-prelude-sample-project-typescript; }; }; } diff --git a/docs/typescript-prelude/build.nix b/docs/typescript-prelude/build.nix index e83f1078..c7547504 100644 --- a/docs/typescript-prelude/build.nix +++ b/docs/typescript-prelude/build.nix @@ -9,7 +9,7 @@ name = "prelude-sample-project"; src = ./.; npmExtraDependencies = [ - config.packages.lbf-prelude-sample-project-typescript-tgz + config.packages.lbf-prelude-sample-project-typescript ]; devShellTools = config.settings.shell.tools; diff --git a/extras/lbf-nix/lbf-typescript.nix b/extras/lbf-nix/lbf-typescript.nix index 9efd4420..7367b516 100644 --- a/extras/lbf-nix/lbf-typescript.nix +++ b/extras/lbf-nix/lbf-typescript.nix @@ -276,4 +276,4 @@ let }); }); in -lbTypescriptFlake +lbTypescriptFlake.packages."${name}-typescript-tgz" diff --git a/libs/build.nix b/libs/build.nix index 3b96f102..2e9c47ac 100644 --- a/libs/build.nix +++ b/libs/build.nix @@ -28,7 +28,7 @@ configs = [ "${config.packages.codegen-configs}/purescript-prelude-base.json" ]; }; - lbf-prelude-typescript = (config.lbf-nix.lbfTypescript { + lbf-prelude-typescript = config.lbf-nix.lbfTypescript { name = "lbf-prelude"; src = ./lbf-prelude; files = [ "Prelude.lbf" ]; @@ -38,7 +38,7 @@ [ config.packages.lbr-prelude-typescript-tgz ]; - }).packages.lbf-prelude-typescript-tgz; + }; lbf-prelude-plutarch = config.lbf-nix.lbfPlutarch' { name = "lbf-prelude-plutarch"; @@ -108,7 +108,7 @@ ]; }; - lbf-plutus-typescript = (config.lbf-nix.lbfTypescript { + lbf-plutus-typescript = config.lbf-nix.lbfTypescript { name = "lbf-plutus"; src = ./lbf-plutus; files = [ "Plutus/V1.lbf" "Plutus/V2.lbf" ]; @@ -123,7 +123,7 @@ config.packages.lbf-prelude-typescript config.packages.lbr-plutus-typescript-tgz ]; - }).packages.lbf-plutus-typescript-tgz; + }; lbf-plutus-rust = config.lbf-nix.lbfRust { name = "lbf-plutus"; diff --git a/testsuites/lbt-plutus/api/build.nix b/testsuites/lbt-plutus/api/build.nix index 51410195..35242f41 100644 --- a/testsuites/lbt-plutus/api/build.nix +++ b/testsuites/lbt-plutus/api/build.nix @@ -26,12 +26,11 @@ _: { files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; }; - lbf-plutus-golden-api-typescript = (config.lbf-nix.lbfPlutusTypescript { + lbf-plutus-golden-api-typescript = config.lbf-nix.lbfPlutusTypescript { name = "lbf-plutus-golden-api"; src = ./.; files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; - }).packages.lbf-plutus-golden-api-typescript-tgz - ; + }; }; }; diff --git a/testsuites/lbt-prelude/api/build.nix b/testsuites/lbt-prelude/api/build.nix index 670e2d12..89d7a890 100644 --- a/testsuites/lbt-prelude/api/build.nix +++ b/testsuites/lbt-prelude/api/build.nix @@ -20,11 +20,11 @@ _: { files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; }; - lbf-prelude-golden-api-typescript = (config.lbf-nix.lbfPreludeTypescript { + lbf-prelude-golden-api-typescript = config.lbf-nix.lbfPreludeTypescript { name = "lbf-prelude-golden-api"; src = ./.; files = [ "Foo.lbf" "Foo/Bar.lbf" "Days.lbf" ]; - }).packages.lbf-prelude-golden-api-typescript-tgz; + }; }; }; } From bd178bbcda056e0b8ecdd0197cb99bfaa6cb02a1 Mon Sep 17 00:00:00 2001 From: jared <> Date: Wed, 31 Jan 2024 23:05:57 -0700 Subject: [PATCH 14/14] Consolidated the repeated derivation for the golden tests --- testsuites/lbt-plutus/golden/build.nix | 33 ++++++++++-------------- testsuites/lbt-prelude/golden/build.nix | 34 +++++++++++-------------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/testsuites/lbt-plutus/golden/build.nix b/testsuites/lbt-plutus/golden/build.nix index 7cc79873..100410ba 100644 --- a/testsuites/lbt-plutus/golden/build.nix +++ b/testsuites/lbt-plutus/golden/build.nix @@ -1,6 +1,17 @@ _: { perSystem = { pkgs, config, ... }: + let + goldenData = pkgs.stdenv.mkDerivation { + name = "lbt-plutus-golden-data"; + src = ./.; + # Disable the Fixup phase since it needs to (potentially) write to the + # files in `./.` which are readonly in the nix store + dontFixup = true; + installPhase = ''ln -s "$src" "$out"''; + }; + + in { packages = { lbt-plutus-golden-haskell = config.lbf-nix.haskellData { @@ -9,27 +20,11 @@ _: cabalPackageName = "lbt-plutus-golden-data"; }; - lbt-plutus-golden-purescript = pkgs.stdenv.mkDerivation { - name = "lbt-plutus-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - lbt-plutus-golden-rust = pkgs.stdenv.mkDerivation { - name = "lbt-plutus-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; + lbt-plutus-golden-purescript = goldenData; - lbt-plutus-golden-typescript = pkgs.stdenv.mkDerivation { - name = "lbt-plutus-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = ''ln -s "$src" "$out"''; - }; + lbt-plutus-golden-rust = goldenData; + lbt-plutus-golden-typescript = goldenData; }; }; diff --git a/testsuites/lbt-prelude/golden/build.nix b/testsuites/lbt-prelude/golden/build.nix index d0dc11d5..21e48b96 100644 --- a/testsuites/lbt-prelude/golden/build.nix +++ b/testsuites/lbt-prelude/golden/build.nix @@ -1,6 +1,17 @@ _: { perSystem = { pkgs, config, ... }: + + let + goldenData = pkgs.stdenv.mkDerivation { + name = "lbt-prelude-golden-data"; + src = ./.; + # Disable the Fixup phase since it needs to (potentially) write to the + # files in `./.` which are readonly in the nix store + dontFixup = true; + installPhase = ''ln -s "$src" "$out"''; + }; + in { devShells.dev-lbt-prelude-golden = config.devShells.default; @@ -11,27 +22,12 @@ _: cabalPackageName = "lbt-prelude-golden-data"; }; - lbt-prelude-golden-purescript = pkgs.stdenv.mkDerivation { - name = "lbt-prelude-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; + lbt-prelude-golden-purescript = goldenData; - lbt-prelude-golden-rust = pkgs.stdenv.mkDerivation { - name = "lbt-prelude-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; + lbt-prelude-golden-rust = goldenData; - lbt-prelude-golden-typescript = pkgs.stdenv.mkDerivation { - name = "lbt-prelude-golden-data"; - src = ./.; - phases = "installPhase"; - installPhase = ''ln -s "$src" "$out"''; - }; - }; + lbt-prelude-golden-typescript = goldenData; + }; }; }