Skip to content

Commit

Permalink
refactor test codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-trunov committed Jan 15, 2025
1 parent 83da46d commit 4accc2c
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 109 deletions.
149 changes: 68 additions & 81 deletions src/test/e2e-emulated/map-tests/generate.ts
Original file line number Diff line number Diff line change
@@ -1,80 +1,66 @@
import { run } from "../../../node";
import { MapType, keyTypes, valTypes } from "./map-properties-key-value-types";
import { keyTypes, valTypes } from "./map-properties-key-value-types";
import { mkdir, writeFile } from "fs/promises";
import path from "path";
import { exit } from "node:process";
import {
descriptionToString,
intKeyFormats,
intValFormats,
MapIntKeyDescription,
MapIntValDescription,
maxInt,
minInt,
} from "./map-int-limits-key-value-types";
import { readFile } from "node:fs/promises";

type TestKind = "property" | "int-limits";
type TestKind = "map-properties" | "map-int-limits";

const pwd = (fileName: string): string => path.join(__dirname, fileName);

const testDirectory = (kind: TestKind, testName: string): string =>
pwd(`./build/${kind}_${testName}`);
pwd(`./build/${kind}_${testName}`.replaceAll(" ", "-"));

const testContractFileName = "test.tact";
const specFileNameProperties = "map-properties.spec.ts";
const specFileNameLimits = "map-int-limits.spec.ts";

const instantiateContractTemplateAndSpecProperties = async (
templateTact: string,
templateSpec: string,
testName: string,
key: MapType,
val: MapType,
): Promise<string> => {
const tactSourceCode = templateTact
.replaceAll("KEY_TYPE_PLACEHOLDER", key.type)
.replaceAll("VAL_TYPE_PLACEHOLDER", val.type);
const testDir = testDirectory("property", testName);
await mkdir(testDir, { recursive: true });
const tactFilePath = path.join(testDir, testContractFileName);
await writeFile(tactFilePath, tactSourceCode);
const specSourceCode = templateSpec
.replaceAll("KEY_1_PLACEHOLDER", key.val1)
.replaceAll("KEY_2_PLACEHOLDER", key.val2)
.replaceAll("VAL_1_PLACEHOLDER", val.val1)
.replaceAll("VAL_2_PLACEHOLDER", val.val2);
const specFilePath = path.join(testDir, specFileNameProperties);
await writeFile(specFilePath, specSourceCode);
return tactFilePath;
const applySubstitutions = (
source: string,
subst: Map<string, string>,
): string => {
return Array.from(subst).reduce((src, [placeholder, concreteValue]) => {
return src.replaceAll(placeholder, concreteValue);
}, source);
};

const instantiateContractTemplateAndSpecLimits = async (
const instantiateContractAndSpecTemplates = async (
testKind: TestKind,
testName: string,
templateTact: string,
templateTactSubst: Map<string, string>,
templateSpec: string,
testName: string,
key: MapIntKeyDescription,
val: MapIntValDescription,
templateSpecSubst: Map<string, string>,
): Promise<string> => {
const tactSourceCode = templateTact
.replaceAll("KEY_FORMAT_PLACEHOLDER", descriptionToString(key))
.replaceAll("VAL_FORMAT_PLACEHOLDER", descriptionToString(val))
.replaceAll("KEY_MIN_PLACEHOLDER", minInt(key).toString())
.replaceAll("KEY_MAX_PLACEHOLDER", maxInt(key).toString())
.replaceAll("VAL_MIN_PLACEHOLDER", minInt(val).toString())
.replaceAll("VAL_MAX_PLACEHOLDER", maxInt(val).toString());
const testDir = testDirectory("int-limits", testName);
const testDir = testDirectory(testKind, testName);
const tactSourceCode = applySubstitutions(templateTact, templateTactSubst);
const specSourceCode = applySubstitutions(templateSpec, templateSpecSubst);
await mkdir(testDir, { recursive: true });
const tactFilePath = path.join(testDir, testContractFileName);
await writeFile(tactFilePath, tactSourceCode);
const specSourceCode = templateSpec;
const specFilePath = path.join(testDir, specFileNameLimits);
const specFilePath = path.join(testDir, `${testKind}.spec.ts`);
await writeFile(specFilePath, specSourceCode);
return tactFilePath;
};

const compileContracts = async () => {
// compile map properties contracts
const compileAndExitOnError = async (tactFilePath: string) => {
const compilationResult = await run({
fileName: tactFilePath,
suppressLog: true,
});
if (!compilationResult.ok) {
console.error(compilationResult.error);
exit(1);
}
};

const generatePropertyTests = async () => {
const templateTactSourceCodeProperties: string = (
await readFile(pwd("map-properties.tact.template"))
).toString();
Expand All @@ -83,26 +69,29 @@ const compileContracts = async () => {
).toString();
for (const key of keyTypes) {
for (const val of valTypes) {
const testName = `${key.type}_${val.type}`.replaceAll(" ", "-");
const tactFilePath =
await instantiateContractTemplateAndSpecProperties(
templateTactSourceCodeProperties,
templateSpecSourceCodeProperties,
testName,
key,
val,
);
const compilationResult = await run({
fileName: tactFilePath,
suppressLog: true,
});
if (!compilationResult.ok) {
console.error(compilationResult.error);
exit(1);
}
const testName = `${key.type}_${val.type}`;
const tactFilePath = await instantiateContractAndSpecTemplates(
"map-properties",
testName,
templateTactSourceCodeProperties,
new Map([
["KEY_TYPE_PLACEHOLDER", key.type],
["VAL_TYPE_PLACEHOLDER", val.type],
]),
templateSpecSourceCodeProperties,
new Map([
["KEY_1_PLACEHOLDER", key._1],
["KEY_2_PLACEHOLDER", key._2],
["VAL_1_PLACEHOLDER", val._1],
["VAL_2_PLACEHOLDER", val._2],
]),
);
await compileAndExitOnError(tactFilePath);
}
}
// compile int map limit contracts
};

const generateIntLimitsTests = async () => {
const templateTactSourceCodeLimits: string = (
await readFile(pwd("map-int-limits.tact.template"))
).toString();
Expand All @@ -111,33 +100,31 @@ const compileContracts = async () => {
).toString();
for (const key of intKeyFormats) {
for (const val of intValFormats) {
const testName =
`${descriptionToString(key)}_${descriptionToString(val)}`.replaceAll(
" ",
"-",
);
const tactFilePath = await instantiateContractTemplateAndSpecLimits(
const testName = `${descriptionToString(key)}_${descriptionToString(val)}`;
const tactFilePath = await instantiateContractAndSpecTemplates(
"map-int-limits",
testName,
templateTactSourceCodeLimits,
new Map([
["KEY_FORMAT_PLACEHOLDER", descriptionToString(key)],
["VAL_FORMAT_PLACEHOLDER", descriptionToString(val)],
["KEY_MIN_PLACEHOLDER", minInt(key).toString()],
["KEY_MAX_PLACEHOLDER", maxInt(key).toString()],
["VAL_MIN_PLACEHOLDER", minInt(val).toString()],
["VAL_MAX_PLACEHOLDER", maxInt(val).toString()],
]),
templateSpecSourceCodeLimits,
testName,
key,
val,
new Map(),
);
const compilationResult = await run({
fileName: tactFilePath,
suppressLog: true,
});
if (!compilationResult.ok) {
console.error(compilationResult.error);
exit(1);
}
await compileAndExitOnError(tactFilePath);
}
}
};

const main = async () => {
try {
await compileContracts();
await generatePropertyTests();
await generateIntLimitsTests();
} catch (e) {
console.error(e);
process.exit(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
type FixedWidthFormat = "int" | "uint";
type VarWidthFormat = "varint" | "varuint";

export type MapIntKeyDescription =
type MapIntKeyDescription =
| {
format: FixedWidthFormat;
size: number;
}
| { format: null };

export type MapIntValDescription =
type MapIntValDescription =
| MapIntKeyDescription
| {
format: VarWidthFormat;
Expand Down
52 changes: 26 additions & 26 deletions src/test/e2e-emulated/map-tests/map-properties-key-value-types.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,76 @@
export type MapType = {
type MapType = {
type: string;
val1: string;
val2: string;
_1: string;
_2: string;
};

const intSizes = [8, 42, 257];
const uintSizes = [9, 32, 256];

const ints: MapType[] = intSizes.map((size) => ({
type: `Int as int${size}`,
val1: "-5n",
val2: "42n",
_1: "-5n",
_2: "42n",
}));

const uints: MapType[] = uintSizes.map((size) => ({
type: `Int as uint${size}`,
val1: "6n",
val2: "121n",
_1: "6n",
_2: "121n",
}));

const varInts = [
{
type: "Int as varint16",
val1: "-7n",
val2: "1000n",
_1: "-7n",
_2: "1000n",
},
{
type: "Int as varint32",
val1: "-74n",
val2: "10000n",
_1: "-74n",
_2: "10000n",
},
{
type: "Int as varuint16",
val1: "7n",
val2: "100n",
_1: "7n",
_2: "100n",
},
{
type: "Int as varuint32",
val1: "740n",
val2: "100000n",
_1: "740n",
_2: "100000n",
},
{
type: "Int as coins",
val1: "7n",
val2: "100n",
_1: "7n",
_2: "100n",
},
];

const allInts = ints.concat(uints, varInts);

const address = {
type: "Address",
val1: 'address("UQBKgXCNLPexWhs2L79kiARR1phGH1LwXxRbNsCFF9doczSI")',
val2: "new Address(0, Buffer.alloc(32, 0))",
_1: 'address("UQBKgXCNLPexWhs2L79kiARR1phGH1LwXxRbNsCFF9doczSI")',
_2: "new Address(0, Buffer.alloc(32, 0))",
};

const otherValueTypes: MapType[] = [
{ type: "Bool", val1: "true", val2: "false" },
{ type: "Bool", _1: "true", _2: "false" },
{
type: "Cell",
val1: 'Cell.fromBase64("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=")',
val2: 'Cell.fromBase64("te6ccgEBAgEALQABDv8AiNDtHtgBCEICGbgzd5nhZ9WhSM+4juFCvgMYJOtxthFdtTKIH6M/6SM=")',
_1: 'Cell.fromBase64("te6cckEBAQEADgAAGEhlbGxvIHdvcmxkIXgtxbw=")',
_2: 'Cell.fromBase64("te6ccgEBAgEALQABDv8AiNDtHtgBCEICGbgzd5nhZ9WhSM+4juFCvgMYJOtxthFdtTKIH6M/6SM=")',
},
{
type: "SomeStruct",
val1: "{ $$$$type: 'SomeStruct', i: -321n, b: false, a: new Address(0, Buffer.alloc(32, 0)), u1: 10n, u2: 20n }",
val2: "{ $$$$type: 'SomeStruct', i: -322n, b: true, a: new Address(0, Buffer.alloc(32, 1)), u1: 101n, u2: 202n }",
_1: "{ $$$$type: 'SomeStruct', i: -321n, b: false, a: new Address(0, Buffer.alloc(32, 0)), u1: 10n, u2: 20n }",
_2: "{ $$$$type: 'SomeStruct', i: -322n, b: true, a: new Address(0, Buffer.alloc(32, 1)), u1: 101n, u2: 202n }",
},
{
type: "SomeMessage",
val1: "{ $$$$type: 'SomeMessage', nonce: 0n, buyer: new Address(0, Buffer.alloc(32, 2)) }",
val2: "{ $$$$type: 'SomeMessage', nonce: 56n, buyer: new Address(0, Buffer.alloc(32, 1)) }",
_1: "{ $$$$type: 'SomeMessage', nonce: 0n, buyer: new Address(0, Buffer.alloc(32, 2)) }",
_2: "{ $$$$type: 'SomeMessage', nonce: 56n, buyer: new Address(0, Buffer.alloc(32, 1)) }",
},
];

Expand Down

0 comments on commit 4accc2c

Please sign in to comment.