-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parser/printer fuzz tests for expressions #1248
Conversation
when I see something like this, I immediately think of adding shrinking (fast-check should support it)
even shrinking integer literals would already help a lot here |
I'm thinking about that right now. It might become more user- friendly values value: fc.bigInt({ min: -1_000_000_000n, max: 1_000_000_000n }) |
80ca1e6
to
88786b8
Compare
@xpyctumo I took the liberty to merge the new parser into your branch and pushed a few fixes for the expressions generator too. Looks like the new parser fixed the issue with duplicated unary operators! |
Btw, these fuzzing-like tests should go into their own folder and only gets executed on a special request, separately from |
f5d0f1f
to
ccdf98c
Compare
One of the example I get:
is not allowed because we need a capital initial letter for the types
|
I think supporting Slice might be too complicated at the moment since we use |
It's kinda bad code, but it can be a good starting point for nice and clear error output: import {diffJson} from "diff";
fc.property(randomAstExpression(maxDepth), (generatedAst) => {
const prettyBefore = prettyPrint(generatedAst);
const parsedAst = parser.parseExpression(prettyBefore);
const prettyAfter = prettyPrint(parsedAst);
expect(prettyBefore).toBe(prettyAfter)
const actual = eqExpressions(generatedAst, parsedAst);
if (!actual) {
const replacer = (key: string, value: unknown): unknown => {
if (key === "id") return undefined;
if (typeof value === "bigint") return value.toString();
return value;
};
const left = JSON.stringify(sortObjectKeys(generatedAst), replacer, 4);
const right = JSON.stringify(sortObjectKeys(parsedAst), replacer, 4);
const differences = diffJson(left, right);
const ConsoleColors = {
added: "\x1b[32m",
removed: "\x1b[31m",
reset: "\x1b[0m",
};
differences.forEach(part => {
const color = part.added
? ConsoleColors.added
: part.removed
? ConsoleColors.removed
: ConsoleColors.reset;
process.stdout.write(color + part.value + ConsoleColors.reset);
});
process.stdout.write(`\n\n${prettyBefore}\n\n`);
process.stdout.write(`${prettyAfter}\n\n`);
}
expect(actual).toBe(true);
}), |
I decided to ignore the |
Following generators are must be implemented. I leave them here to debug. function randomAddress(): fc.Arbitrary<Address> {
return fc.constant(
address("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N"), // TODO: use random address
);
}
function randomCell(): fc.Arbitrary<Cell> {
return fc.constant(beginCell().endCell()); // TODO: use random random here
}
function randomAstAddress(): fc.Arbitrary<A.AstAddress> {
return dummyAstNode(
fc.record({
kind: fc.constant("address"),
value: randomAddress(),
}),
);
}
function randomAstCell(): fc.Arbitrary<A.AstCell> {
return dummyAstNode(
fc.record({
kind: fc.constant("cell"),
value: randomCell(),
}),
);
}
function randomSlice(): fc.Arbitrary<Slice> {
return fc.constant(beginCell().endCell().beginParse());
}
function randomAstSlice(): fc.Arbitrary<A.AstSlice> {
return dummyAstNode(
fc.record({
kind: fc.constant("slice"),
value: randomSlice(),
}),
);
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need
- to introduce a command to run a sampler:
yarn random-ast 42
would produce 42 random expressions and pretty print those in the terminal -- this is needed to understand what kind of expressions we actually produce - to document this type of tests in CONTRIBUTING.md
…T and added an example to `CONTRIBUTING.md`
d611b56
to
b9ca261
Compare
Issue
Closes #1469
Checklist
Plan