Skip to content

Commit

Permalink
test: More AST generators. Simplified logger by removing `dummySrcInf…
Browse files Browse the repository at this point in the history
…o` in the output
  • Loading branch information
xpyctumo committed Dec 26, 2024
1 parent fb01585 commit 80ca1e6
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 0 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
testPathIgnorePatterns: ["/node_modules/", "/dist/"],
maxWorkers: "50%",
globalSetup: "./jest.setup.js",
setupFiles: ["./jest.setup.js"],
globalTeardown: "./jest.teardown.js",
snapshotSerializers: ["@tact-lang/ton-jest/serializers"],
};
53 changes: 53 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,61 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const coverage = require("@tact-lang/coverage");
const fc = require("fast-check");

module.exports = async () => {
if (process.env.COVERAGE === "true") {
coverage.beginCoverage();
}
};

function sanitizeObject(
obj,
options = {
excludeKeys: [],
valueTransformers: {},
},
) {
const { excludeKeys, valueTransformers } = options;

if (Array.isArray(obj)) {
return obj.map((item) => sanitizeObject(item, options));
} else if (obj !== null && typeof obj === "object") {
const newObj = {};
for (const [key, value] of Object.entries(obj)) {
if (!excludeKeys.includes(key)) {
const transformer = valueTransformers[key];
newObj[key] = transformer
? transformer(value)
: sanitizeObject(value, options);
}
}
return newObj;
}
return obj;
}

fc.configureGlobal({
reporter: (log) => {
if (log.failed) {
const sanitizedCounterexample = sanitizeObject(log.counterexample, {
excludeKeys: ["id", "loc"],
valueTransformers: {
value: (val) =>
typeof val === "bigint" ? val.toString() : val,
},
});

const errorMessage = `
===
Property failed after ${log.numRuns} tests
Seed: ${log.seed}
Path: ${log.counterexamplePath}
Counterexample: ${JSON.stringify(sanitizedCounterexample, null, 0)}
Errors: ${log.error ? log.error : "Unknown error"}
===
`;

throw new Error(errorMessage);
}
},
});
8 changes: 8 additions & 0 deletions src/test/prettyPrint/expressions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import {
randomAstOpBinary,
randomAstOpUnary,
randomAstExpression,
randomAstInitOf,
randomAstNull,
randomAstStaticCall,
randomAstStructInstance,
} from "../utils/expression/randomAst";

describe("Pretty Print Expressions", () => {
Expand All @@ -21,6 +25,10 @@ describe("Pretty Print Expressions", () => {
],
["AstOpBinary", randomAstOpBinary(expression(), expression())],
["AstOpUnary", randomAstOpUnary(expression())],
["AstNull", randomAstNull()],
["AstInitOf", randomAstInitOf(expression())],
["AstStaticCall", randomAstStaticCall(expression())],
["AstStructInstance", randomAstStructInstance(expression())],
];

cases.forEach(([caseName, astGenerator]) => {
Expand Down
72 changes: 72 additions & 0 deletions src/test/utils/expression/randomAst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import {
AstBoolean,
AstConditional,
AstExpression,
AstId,
AstInitOf,
AstNull,
AstNumber,
AstOpBinary,
AstOpUnary,
AstStaticCall,
AstString,
AstStructFieldInitializer,
AstStructInstance,
} from "../../../grammar/ast";
import { dummySrcInfo } from "../../../grammar/src-info";

Expand Down Expand Up @@ -112,6 +118,72 @@ export function randomAstConditional(
);
}

function randomAstId(): fc.Arbitrary<AstId> {
return dummyAstNode(
fc.record({
kind: fc.constant("id"),
text: fc.string().filter((text) => /^[A-Za-z_]+$/.test(text)),
// Rules for text value are in src/grammar/grammar.ohm
}),
);
}

export function randomAstNull(): fc.Arbitrary<AstNull> {
return dummyAstNode(
fc.record({
kind: fc.constant("null"),
}),
);
}

export function randomAstInitOf(
expression: fc.Arbitrary<AstExpression>,
): fc.Arbitrary<AstInitOf> {
return dummyAstNode(
fc.record({
kind: fc.constant("init_of"),
contract: randomAstId(),
args: fc.array(expression),
}),
);
}

export function randomAstStaticCall(
expression: fc.Arbitrary<AstExpression>,
): fc.Arbitrary<AstStaticCall> {
return dummyAstNode(
fc.record({
kind: fc.constant("static_call"),
function: randomAstId(),
args: fc.array(expression),
}),
);
}

function randomAstStructFieldInitializer(
expression: fc.Arbitrary<AstExpression>,
): fc.Arbitrary<AstStructFieldInitializer> {
return dummyAstNode(
fc.record({
kind: fc.constant("struct_field_initializer"),
field: randomAstId(),
initializer: expression,
}),
);
}

export function randomAstStructInstance(
expression: fc.Arbitrary<AstExpression>,
): fc.Arbitrary<AstStructInstance> {
return dummyAstNode(
fc.record({
kind: fc.constant("struct_instance"),
type: randomAstId(),
args: fc.array(randomAstStructFieldInitializer(expression)),
}),
);
}

export function randomAstExpression(
maxShrinks: number,
): fc.Arbitrary<AstExpression> {
Expand Down

0 comments on commit 80ca1e6

Please sign in to comment.