diff --git a/.changeset/itchy-bananas-punch.md b/.changeset/itchy-bananas-punch.md new file mode 100644 index 0000000..5e4c5b2 --- /dev/null +++ b/.changeset/itchy-bananas-punch.md @@ -0,0 +1,7 @@ +--- +"core-tests": patch +"testsuite": patch +"@guidanoli/cmioc": patch +--- + +Modularize test suite diff --git a/package.json b/package.json index 43e87f8..ed9cd3a 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,18 @@ "private": true, "scripts": { "build": "run-s build:packages build:apps", - "build:packages": "run-s build:core", + "build:packages": "run-s build:core build:testsuite", "build:apps": "run-p build:cli build:site", "build:core": "pnpm run --filter @guidanoli/cmioc build", "build:cli": "pnpm run --filter @guidanoli/cmioc-cli build", "build:site": "pnpm run --filter site build", + "build:testsuite": "pnpm run --filter testsuite build", "check-format": "prettier --check .", "format": "prettier --check --write .", "publish": "changeset publish", "release": "run-s build publish", "test": "run-s test:core", - "test:core": "pnpm run --filter @guidanoli/cmioc test" + "test:core": "pnpm run --filter core-tests test" }, "devDependencies": { "@changesets/cli": "^2.27.7", diff --git a/packages/core/jest.config.ts b/packages/core-tests/jest.config.ts similarity index 100% rename from packages/core/jest.config.ts rename to packages/core-tests/jest.config.ts diff --git a/packages/core-tests/package.json b/packages/core-tests/package.json new file mode 100644 index 0000000..ba129b4 --- /dev/null +++ b/packages/core-tests/package.json @@ -0,0 +1,18 @@ +{ + "name": "core-tests", + "version": "0.0.0", + "private": true, + "scripts": { + "test": "jest" + }, + "dependencies": { + "@guidanoli/cmioc": "workspace:*", + "testsuite": "workspace:*" + }, + "devDependencies": { + "@jest/globals": "^29.7.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.2", + "tsconfig": "workspace:*" + } +} diff --git a/packages/core-tests/test/index.test.ts b/packages/core-tests/test/index.test.ts new file mode 100644 index 0000000..8b7e645 --- /dev/null +++ b/packages/core-tests/test/index.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test } from "@jest/globals"; + +import { + encodeInput, + encodeOutput, + decodeInput, + decodeOutput, +} from "@guidanoli/cmioc"; +import { inputTestSuite, outputTestSuite } from "testsuite"; + +for (const { name, blob, data: input } of inputTestSuite) { + describe(name, () => { + test("encode", () => { + expect(encodeInput(input)).toEqual(blob); + }); + test("decode", () => { + expect(decodeInput(blob)).toEqual(input); + }); + }); +} + +for (const { name, blob, data: output } of outputTestSuite) { + describe(name, () => { + test("encode", () => { + expect(encodeOutput(output)).toEqual(blob); + }); + test("decode", () => { + expect(decodeOutput(blob)).toEqual(output); + }); + }); +} diff --git a/packages/core-tests/tsconfig.json b/packages/core-tests/tsconfig.json new file mode 100644 index 0000000..0e1a235 --- /dev/null +++ b/packages/core-tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "outDir": "dist" + }, + "extends": "tsconfig/base.json", + "include": ["src"] +} diff --git a/packages/core/package.json b/packages/core/package.json index d5c842e..72639b2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,8 +26,7 @@ "scripts": { "build": "tsc", "clean": "rimraf dist", - "prepack": "run-s build", - "test": "jest" + "prepack": "run-s build" }, "dependencies": { "@cartesi/rollups": "2.0.0-rc.3", @@ -35,10 +34,7 @@ "viem": "^2.9.2" }, "devDependencies": { - "@jest/globals": "^29.7.0", - "jest": "^29.7.0", "rimraf": "^5.0.5", - "ts-jest": "^29.1.2", "tsconfig": "workspace:*", "typescript": "catalog:" } diff --git a/packages/core/test/index.test.ts b/packages/core/test/index.test.ts deleted file mode 100644 index 756806d..0000000 --- a/packages/core/test/index.test.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { encodeInput, encodeOutput, decodeInput, decodeOutput } from "../src"; - -import { describe, expect, test } from "@jest/globals"; - -describe("decode/encode", () => { - test("input", () => { - const blob = - "0x415bf363000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070ac08179605af2d9e75782b8decdd3c22aa4d0c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000129bbad00000000000000000000000000000000000000000000000000000000660195215a41539c3688747a1a8c7811b98b0427331ff73aab018eb5c9921993d617f314000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"; - - const input = decodeInput(blob); - - expect(encodeInput(input)).toEqual(blob); - - expect(input.chainId).toEqual(1n); - expect(input.appContract).toEqual( - "0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C", - ); - expect(input.msgSender).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(input.blockNumber).toEqual(19512237n); - expect(input.blockTimestamp).toEqual(1711379745n); - expect(input.prevRandao).toEqual( - 40823578488146031703637781058841789769586951870728503003341100870835983872788n, - ); - expect(input.index).toEqual(42n); - expect(input.payload).toEqual("0xdeadbeef"); - }); - - test("input with empty payload", () => { - const blob = - "0x415bf363000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070ac08179605af2d9e75782b8decdd3c22aa4d0c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000129bbad00000000000000000000000000000000000000000000000000000000660195215a41539c3688747a1a8c7811b98b0427331ff73aab018eb5c9921993d617f314000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000"; - - const input = decodeInput(blob); - - expect(encodeInput(input)).toEqual(blob); - - expect(input.chainId).toEqual(1n); - expect(input.appContract).toEqual( - "0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C", - ); - expect(input.msgSender).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(input.blockNumber).toEqual(19512237n); - expect(input.blockTimestamp).toEqual(1711379745n); - expect(input.prevRandao).toEqual( - 40823578488146031703637781058841789769586951870728503003341100870835983872788n, - ); - expect(input.index).toEqual(42n); - expect(input.payload).toEqual("0x"); - }); - - test("notice", () => { - const blob = - "0xc258d6e500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "notice": { - expect(output.payload).toEqual("0xdeadbeef"); - break; - } - default: - throw new Error("expected output to be a notice"); - } - }); - - test("notice with empty payload", () => { - const blob = - "0xc258d6e500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "notice": { - expect(output.payload).toEqual("0x"); - break; - } - default: - throw new Error("expected output to be a notice"); - } - }); - - test("voucher", () => { - const blob = - "0x237a816f000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000003fafafa0000000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "voucher": { - expect(output.destination).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(output.value).toEqual(1000000000000000000n); - expect(output.payload).toEqual("0xfafafa"); - break; - } - default: - throw new Error("expected output to be a voucher"); - } - }); - - test("voucher with empty payload", () => { - const blob = - "0x237a816f000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "voucher": { - expect(output.destination).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(output.value).toEqual(1000000000000000000n); - expect(output.payload).toEqual("0x"); - break; - } - default: - throw new Error("expected output to be a voucher"); - } - }); - - test("delegate call voucher", () => { - const blob = - "0x10321e8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003fafafa0000000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "delegatecallvoucher": { - expect(output.destination).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(output.payload).toEqual("0xfafafa"); - break; - } - default: - throw new Error("expected output to be a delegatecall voucher"); - } - }); - - test("delegate call voucher with empty payload", () => { - const blob = - "0x10321e8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000"; - - const output = decodeOutput(blob); - - expect(encodeOutput(output)).toEqual(blob); - - switch (output.type) { - case "delegatecallvoucher": { - expect(output.destination).toEqual( - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - ); - expect(output.payload).toEqual("0x"); - break; - } - default: - throw new Error("expected output to be a delegatecall voucher"); - } - }); -}); diff --git a/packages/testsuite/package.json b/packages/testsuite/package.json new file mode 100644 index 0000000..eed4b85 --- /dev/null +++ b/packages/testsuite/package.json @@ -0,0 +1,24 @@ +{ + "name": "testsuite", + "version": "0.0.0", + "private": true, + "files": [ + "dist" + ], + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "scripts": { + "build": "tsc", + "clean": "rimraf dist", + "prepack": "run-s build" + }, + "dependencies": { + "@guidanoli/cmioc": "workspace:*", + "viem": "^2.9.2" + }, + "devDependencies": { + "rimraf": "^5.0.5", + "tsconfig": "workspace:*", + "typescript": "catalog:" + } +} diff --git a/packages/testsuite/src/index.ts b/packages/testsuite/src/index.ts new file mode 100644 index 0000000..4a8e5c7 --- /dev/null +++ b/packages/testsuite/src/index.ts @@ -0,0 +1,99 @@ +import { Hex } from "viem"; + +import { Input, Output } from "@guidanoli/cmioc"; + +export type EncodingTestCase = { + name: string; + blob: Hex; + data: T; +}; + +export const inputTestSuite: EncodingTestCase[] = [ + { + name: "input with non-empty payload", + blob: "0x415bf363000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070ac08179605af2d9e75782b8decdd3c22aa4d0c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000129bbad00000000000000000000000000000000000000000000000000000000660195215a41539c3688747a1a8c7811b98b0427331ff73aab018eb5c9921993d617f314000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000", + data: { + chainId: 1n, + appContract: "0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C", + msgSender: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + blockNumber: 19512237n, + blockTimestamp: 1711379745n, + prevRandao: + 40823578488146031703637781058841789769586951870728503003341100870835983872788n, + index: 42n, + payload: "0xdeadbeef", + }, + }, + { + name: "input with empty payload", + blob: "0x415bf363000000000000000000000000000000000000000000000000000000000000000100000000000000000000000070ac08179605af2d9e75782b8decdd3c22aa4d0c000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000129bbad00000000000000000000000000000000000000000000000000000000660195215a41539c3688747a1a8c7811b98b0427331ff73aab018eb5c9921993d617f314000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000", + data: { + chainId: 1n, + appContract: "0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C", + msgSender: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + blockNumber: 19512237n, + blockTimestamp: 1711379745n, + prevRandao: + 40823578488146031703637781058841789769586951870728503003341100870835983872788n, + index: 42n, + payload: "0x", + }, + }, +]; + +export const outputTestSuite: EncodingTestCase[] = [ + { + name: "notice with non-empty payload", + blob: "0xc258d6e500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000", + data: { + type: "notice", + payload: "0xdeadbeef", + }, + }, + { + name: "notice with empty payload", + blob: "0xc258d6e500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", + data: { + type: "notice", + payload: "0x", + }, + }, + { + name: "voucher with non-empty payload", + blob: "0x237a816f000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000003fafafa0000000000000000000000000000000000000000000000000000000000", + data: { + type: "voucher", + destination: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + value: 1000000000000000000n, + payload: "0xfafafa", + }, + }, + { + name: "voucher with empty payload", + blob: "0x237a816f000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + data: { + type: "voucher", + destination: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + value: 1000000000000000000n, + payload: "0x", + }, + }, + { + name: "delegatecall voucher with non-empty payload", + blob: "0x10321e8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003fafafa0000000000000000000000000000000000000000000000000000000000", + data: { + type: "delegatecallvoucher", + destination: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + payload: "0xfafafa", + }, + }, + { + name: "delegatecall voucher with empty payload", + blob: "0x10321e8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + data: { + type: "delegatecallvoucher", + destination: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + payload: "0x", + }, + }, +]; diff --git a/packages/testsuite/tsconfig.json b/packages/testsuite/tsconfig.json new file mode 100644 index 0000000..0e1a235 --- /dev/null +++ b/packages/testsuite/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "outDir": "dist" + }, + "extends": "tsconfig/base.json", + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0110573..c22ca71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,6 +78,25 @@ importers: viem: specifier: ^2.9.2 version: 2.17.3(typescript@5.5.3) + devDependencies: + rimraf: + specifier: ^5.0.5 + version: 5.0.9 + tsconfig: + specifier: workspace:* + version: link:../tsconfig + typescript: + specifier: 'catalog:' + version: 5.5.3 + + packages/core-tests: + dependencies: + '@guidanoli/cmioc': + specifier: workspace:* + version: link:../core + testsuite: + specifier: workspace:* + version: link:../testsuite devDependencies: '@jest/globals': specifier: ^29.7.0 @@ -85,15 +104,28 @@ importers: jest: specifier: ^29.7.0 version: 29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) - rimraf: - specifier: ^5.0.5 - version: 5.0.9 ts-jest: specifier: ^29.1.2 version: 29.2.2(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@20.14.10)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))(typescript@5.5.3) tsconfig: specifier: workspace:* version: link:../tsconfig + + packages/testsuite: + dependencies: + '@guidanoli/cmioc': + specifier: workspace:* + version: link:../core + viem: + specifier: ^2.9.2 + version: 2.17.3(typescript@5.5.3) + devDependencies: + rimraf: + specifier: ^5.0.5 + version: 5.0.9 + tsconfig: + specifier: workspace:* + version: link:../tsconfig typescript: specifier: 'catalog:' version: 5.5.3