From c2c56ca50aeceb6df651c692ac8452257ab6991f Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 08:27:15 +0300 Subject: [PATCH 01/11] try constant evaluation for all `Int` and `Bool` expressions --- .../intrinsics/tryExpressionIntrinsics.ts | 17 ++ .../feature-constants.spec.ts.snap | 202 +++++++++++++++--- .../feature-intrinsics.spec.ts.snap | 47 +--- src/test/feature-constants.spec.ts | 15 ++ src/test/features/constants.tact | 32 +++ 5 files changed, 236 insertions(+), 77 deletions(-) diff --git a/src/generator/intrinsics/tryExpressionIntrinsics.ts b/src/generator/intrinsics/tryExpressionIntrinsics.ts index d3ea26ef5d..4f2d89f8c6 100644 --- a/src/generator/intrinsics/tryExpressionIntrinsics.ts +++ b/src/generator/intrinsics/tryExpressionIntrinsics.ts @@ -48,5 +48,22 @@ export function tryExpressionIntrinsics( } } + try { + const t = getExpType(ctx.ctx, exp); + const r = resolveConstantValue(t, exp, ctx.ctx); + + if (t.kind === "ref") { + if (t.name === "Int") { + if (typeof r !== "bigint") { + throw new Error("Expected bigint"); + } + return r.toString(10); + } + if (t.name === "Bool") { + return r ? "true" : "false"; + } + } + } catch {} + return null; } diff --git a/src/test/__snapshots__/feature-constants.spec.ts.snap b/src/test/__snapshots__/feature-constants.spec.ts.snap index 0f8e6144f9..cdadac1e51 100644 --- a/src/test/__snapshots__/feature-constants.spec.ts.snap +++ b/src/test/__snapshots__/feature-constants.spec.ts.snap @@ -225,6 +225,76 @@ ConstantTester { "type": "int", }, }, + { + "arguments": [], + "name": "something16", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something17", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something18", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "something19", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt1", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt2", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, + { + "arguments": [], + "name": "minInt3", + "returnType": { + "format": 257, + "kind": "simple", + "optional": false, + "type": "int", + }, + }, { "arguments": [], "name": "globalConst", @@ -372,7 +442,7 @@ ConstantTester { }, ], }, - "address": kQDv7yerqTCJwMlp3JugEltyVuclWRTw9BhZNDWZbYViC4MM, + "address": kQBLPCFB6hZTJVoIVoSLp-zwDPnb5aQG3LnI_S3IHwDre99T, "init": { "code": x{FF00F4A413F4BCF2C80B} x{62_} @@ -381,26 +451,61 @@ ConstantTester { x{6D} x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070} x{2_} - x{6A_} - x{B22EF6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{74} - x{B226B6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} - x{2_} + x{5} x{2_} x{2_} - x{B24DF6CF36CF0C6_} + x{AFD96D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AC5DED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{74} + x{2_} + x{AFC9ED9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{82186A2BB7D000} - x{B245B6CF36CF0C6_} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{AC4D6D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{8BC48656C6C6F20776F726C64218} + x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} + x{2_} + x{2_} + x{AFF86D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AF976D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{B3C3F6CF36CF0C6_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{2_} + x{2_} + x{2_} + x{5} + x{A937DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82186A2BB7D000} + x{AAE0DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{84FF} + x{5} + x{A916DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8BC48656C6C6F20776F726C64218} + x{AAC1DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} x{2_} x{5} x{A975DB3CDB3C31} @@ -441,7 +546,7 @@ ConstantTester { x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} x{800B} - x{AEE3435697066733A2F2F516D6655625A6767516B31555175766B51474D566231474E31597639424B4A46783247787A586F6231397453615382_} + x{AEE3435697066733A2F2F516D5952584D7874336E78397331376A3874474D64315751526D574D6A556764756E75365536685A4C764758627182_} x{AA45DB3CDB3C31} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} @@ -475,26 +580,61 @@ ConstantTester { x{6D} x{0192307FE07021D749C21F953020D70B1FDEC00001D749C121B0917FE070} x{2_} - x{6A_} - x{B22EF6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{74} - x{B226B6CF36CF0C6_} - x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} - x{6D} - x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} - x{2_} + x{5} + x{2_} + x{2_} + x{AFD96D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} + x{AC5DED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{74} + x{2_} + x{AFC9ED9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{AC4D6D9E6D9E18C_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8D086002540B846967BD8AD0D9B17DFB2440228EB4C230FA9782F8A2D9B60428BEBB439C} x{2_} x{2_} - x{B24DF6CF36CF0C6_} + x{AFF86D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{82186A2BB7D000} - x{B245B6CF36CF0C6_} + x{85FF} + x{AF976D9E6D9E18C_} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} - x{8BC48656C6C6F20776F726C64218} + x{85FF} + x{B3C3F6CF36CF0C6_} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82F70000000000000000000000000000000000000000000000000000000000000001} + x{2_} + x{2_} + x{2_} + x{5} + x{A937DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{82186A2BB7D000} + x{AAE0DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{84FF} + x{5} + x{A916DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{8BC48656C6C6F20776F726C64218} + x{AAC1DB3CDB3C31} + x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} + x{6D} + x{85FF} x{2_} x{5} x{A975DB3CDB3C31} @@ -535,7 +675,7 @@ ConstantTester { x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} x{800B} - x{AEE3435697066733A2F2F516D6655625A6767516B31555175766B51474D566231474E31597639424B4A46783247787A586F6231397453615382_} + x{AEE3435697066733A2F2F516D5952584D7874336E78397331376A3874474D64315751526D574D6A556764756E75365536685A4C764758627182_} x{AA45DB3CDB3C31} x{ED44D0D401F863D20030916DE0F828D70B0A8309BAF2E089DB3C} x{6D} diff --git a/src/test/__snapshots__/feature-intrinsics.spec.ts.snap b/src/test/__snapshots__/feature-intrinsics.spec.ts.snap index 0c328fce34..a7e7be9385 100644 --- a/src/test/__snapshots__/feature-intrinsics.spec.ts.snap +++ b/src/test/__snapshots__/feature-intrinsics.spec.ts.snap @@ -7,52 +7,7 @@ exports[`feature-intrinsics should return correct intrinsic results 1`] = ` "events": [ { "$type": "storage-charged", - "amount": "0.000000011", - }, - { - "$type": "received", - "message": { - "body": { - "text": "emit_1", - "type": "text", - }, - "bounce": true, - "from": "@treasure(treasure)", - "to": "@contract", - "type": "internal", - "value": "1", - }, - }, - { - "$type": "processed", - "gasUsed": 7881n, - }, - { - "$type": "sent", - "messages": [ - { - "body": { - "text": "Hello world", - "type": "text", - }, - "to": null, - "type": "external-out", - }, - ], - }, - ], - }, -] -`; - -exports[`feature-intrinsics should return correct intrinsic results 1`] = ` -[ - { - "$seq": 1, - "events": [ - { - "$type": "storage-charged", - "amount": "0.000000011", + "amount": "0.00000001", }, { "$type": "received", diff --git a/src/test/feature-constants.spec.ts b/src/test/feature-constants.spec.ts index 18aba6d17a..77ff7fbe7d 100644 --- a/src/test/feature-constants.spec.ts +++ b/src/test/feature-constants.spec.ts @@ -36,6 +36,21 @@ describe("feature-constants", () => { expect(await contract.getSomething13()).toEqual(88n); expect(await contract.getSomething14()).toEqual(243n); expect(await contract.getSomething15()).toEqual(32n); + expect(await contract.getSomething16()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); + expect(await contract.getSomething17()).toEqual( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n, + ); + expect(await contract.getSomething18()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639935n, + ); + expect(await contract.getSomething19()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); + expect(await contract.getMinInt1()).toEqual( + -115792089237316195423570985008687907853269984665640564039457584007913129639936n, + ); expect(await contract.getGlobalConst()).toEqual(100n); }); }); diff --git a/src/test/features/constants.tact b/src/test/features/constants.tact index 9a9de38e43..87682154e4 100644 --- a/src/test/features/constants.tact +++ b/src/test/features/constants.tact @@ -16,6 +16,10 @@ contract ConstantTester { const something13: Int = -123 ^ -35; const something14: Int = pow(3, 5); const something15: Int = pow2(5); + const something16: Int = -115792089237316195423570985008687907853269984665640564039457584007913129639936; + const something17: Int = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + const something18: Int = -(pow2(255) - 1 + pow2(255)); + const something19: Int = -(pow2(255) - 1 + pow2(255)) - 1; init() { @@ -85,6 +89,34 @@ contract ConstantTester { return self.something15; } + get fun something16(): Int { + return self.something16; + } + + get fun something17(): Int { + return self.something17; + } + + get fun something18(): Int { + return self.something18; + } + + get fun something19(): Int { + return self.something19; + } + + get fun minInt1(): Int { + return -115792089237316195423570985008687907853269984665640564039457584007913129639936; + } + + get fun minInt2(): Int { + return -(pow2(255) - 1 + pow2(255)); + } + + get fun minInt3(): Int { + return -(pow2(255) - 1 + pow2(255)) - 1; + } + get fun globalConst(): Int { return someGlobalConst; } From 14f2c004b5fe754ab4738715ee42d38644a25bbf Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 08:28:54 +0300 Subject: [PATCH 02/11] update test and snapshot --- src/generator/writers/writeExpression.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generator/writers/writeExpression.spec.ts b/src/generator/writers/writeExpression.spec.ts index 5a2d407696..cd3cf304fa 100644 --- a/src/generator/writers/writeExpression.spec.ts +++ b/src/generator/writers/writeExpression.spec.ts @@ -55,7 +55,7 @@ const golden: string[] = [ "($a + ($b / $c))", "true", "false", - "( (( (($a > 1)) ? (true) : (( (($b < 2)) ? (($c == 3)) : (false) )) )) ? (true) : ((~ ( (( (($d != 4)) ? (true) : (false) )) ? ((~ false)) : (false) ))) )", + "( (( (($a > 1)) ? (true) : (( (($b < 2)) ? (($c == 3)) : (false) )) )) ? (true) : ((~ ( (( (($d != 4)) ? (true) : (false) )) ? (true) : (false) ))) )", "$global_f1($a)", "$A$_constructor_a_b(1, 2)", `$j'a`, From e4eaecf8b423636f18ef85304857794092146bc6 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 08:32:33 +0300 Subject: [PATCH 03/11] fix and add null evaluation --- src/generator/intrinsics/tryExpressionIntrinsics.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/generator/intrinsics/tryExpressionIntrinsics.ts b/src/generator/intrinsics/tryExpressionIntrinsics.ts index 4f2d89f8c6..e0a26e04d6 100644 --- a/src/generator/intrinsics/tryExpressionIntrinsics.ts +++ b/src/generator/intrinsics/tryExpressionIntrinsics.ts @@ -52,6 +52,12 @@ export function tryExpressionIntrinsics( const t = getExpType(ctx.ctx, exp); const r = resolveConstantValue(t, exp, ctx.ctx); + if (t.kind === "null") { + if (r !== null) { + throw new Error("Expected null"); + } + return "null()"; + } if (t.kind === "ref") { if (t.name === "Int") { if (typeof r !== "bigint") { @@ -60,6 +66,9 @@ export function tryExpressionIntrinsics( return r.toString(10); } if (t.name === "Bool") { + if (typeof r !== "boolean") { + throw new Error("Expected boolean"); + } return r ? "true" : "false"; } } From 494a5e489d79f6597ecb4732f2faa397236b6ab8 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 09:21:28 +0300 Subject: [PATCH 04/11] fix errors --- .../intrinsics/tryExpressionIntrinsics.ts | 16 ++++++++-- src/test/feature-const-eval.spec.ts | 32 +++++++++++++++++++ src/test/feature-implicit-init.spec.ts | 2 +- src/test/features/const-eval.tact | 14 ++++++++ src/test/test-tact.config.json | 5 +++ src/types/resolveConstantValue.ts | 15 +++++---- 6 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/test/feature-const-eval.spec.ts create mode 100644 src/test/features/const-eval.tact diff --git a/src/generator/intrinsics/tryExpressionIntrinsics.ts b/src/generator/intrinsics/tryExpressionIntrinsics.ts index e0a26e04d6..cc889365df 100644 --- a/src/generator/intrinsics/tryExpressionIntrinsics.ts +++ b/src/generator/intrinsics/tryExpressionIntrinsics.ts @@ -1,3 +1,4 @@ +import { TactSyntaxError } from "../../errors"; import { ASTExpression } from "../../grammar/ast"; import { resolveConstantValue } from "../../types/resolveConstantValue"; import { getExpType } from "../../types/resolveExpression"; @@ -50,9 +51,9 @@ export function tryExpressionIntrinsics( try { const t = getExpType(ctx.ctx, exp); - const r = resolveConstantValue(t, exp, ctx.ctx); if (t.kind === "null") { + const r = resolveConstantValue(t, exp, ctx.ctx); if (r !== null) { throw new Error("Expected null"); } @@ -60,19 +61,30 @@ export function tryExpressionIntrinsics( } if (t.kind === "ref") { if (t.name === "Int") { + const r = resolveConstantValue(t, exp, ctx.ctx); if (typeof r !== "bigint") { throw new Error("Expected bigint"); } return r.toString(10); } if (t.name === "Bool") { + const r = resolveConstantValue(t, exp, ctx.ctx); if (typeof r !== "boolean") { throw new Error("Expected boolean"); } return r ? "true" : "false"; } } - } catch {} + } catch (e) { + if (e instanceof TactSyntaxError) { + if ( + !e.message.includes("Cannot reduce expression to a constant") && + !e.message.includes("Expected constant value") + ) { + throw e; + } + } + } return null; } diff --git a/src/test/feature-const-eval.spec.ts b/src/test/feature-const-eval.spec.ts new file mode 100644 index 0000000000..a7a64a0f24 --- /dev/null +++ b/src/test/feature-const-eval.spec.ts @@ -0,0 +1,32 @@ +import { __DANGER_resetNodeId } from "../grammar/ast"; +import { run } from "../node"; +import { consoleLogger } from "../logger"; + +describe("feature-const-eval", () => { + beforeAll(() => { + jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); + }); + + beforeEach(() => { + __DANGER_resetNodeId(); + }); + + afterAll(() => { + (consoleLogger.error as jest.Mock).mockRestore(); + }); + + afterEach(() => { + (consoleLogger.error as jest.Mock).mockClear(); + }); + + it("should not compile with division by zero", async () => { + const result = await run({ + configPath: __dirname + "/test-tact.config.json", + projectNames: ["const-eval"], + }); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + "Cannot divide by zero", + ); + expect(result).toBe(false); + }); +}); diff --git a/src/test/feature-implicit-init.spec.ts b/src/test/feature-implicit-init.spec.ts index 1574746793..b98672413c 100644 --- a/src/test/feature-implicit-init.spec.ts +++ b/src/test/feature-implicit-init.spec.ts @@ -5,7 +5,7 @@ import { MyContract } from "./features/output/implicit-init_MyContract"; import { run } from "../node"; import { consoleLogger } from "../logger"; -describe("feature-send", () => { +describe("feature-implicit-init", () => { beforeAll(() => { jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); }); diff --git a/src/test/features/const-eval.tact b/src/test/features/const-eval.tact new file mode 100644 index 0000000000..8bf2233c65 --- /dev/null +++ b/src/test/features/const-eval.tact @@ -0,0 +1,14 @@ +contract ConstantTester { + init() { + + } + + receive() { + + } + + get fun something(): Int { + let x: Int = 2 / 0; + return x; + } +} \ No newline at end of file diff --git a/src/test/test-tact.config.json b/src/test/test-tact.config.json index 9220c4be6c..b4c4ea8813 100644 --- a/src/test/test-tact.config.json +++ b/src/test/test-tact.config.json @@ -13,6 +13,11 @@ "name": "invalid-address", "path": "./features/invalid-address.tact", "output": "./features/output" + }, + { + "name": "const-eval", + "path": "./features/const-eval.tact", + "output": "./features/output" } ] } diff --git a/src/types/resolveConstantValue.ts b/src/types/resolveConstantValue.ts index 2985293525..e3ea6f862a 100644 --- a/src/types/resolveConstantValue.ts +++ b/src/types/resolveConstantValue.ts @@ -71,13 +71,16 @@ function reduceInt(ast: ASTExpression): bigint { return reduceIntImpl(ast); } catch (error) { if (error instanceof RangeError) { - throwError( - "Cannot evaluate constant expression due to integer overflow", - ast.ref, - ); - } else { - throw error; + if (error.message === "Division by zero") { + throwError("Cannot divide by zero", ast.ref); + } else if (error.message === "Maximum BigInt size exceeded") { + throwError( + "Cannot evaluate constant expression due to integer overflow", + ast.ref, + ); + } } + throw error; } } From 28a0ba6467564f98b23f4bd74e52825b6b9f8f89 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 09:26:13 +0300 Subject: [PATCH 05/11] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8e5e0b773..87919c22ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The grammar of the unary operators has been fixed, constant and function declarations are prohibited for contracts and at the top level of Tact modules: PR [#365](https://github.com/tact-lang/tact/pull/365) - Typos in ABI generation: : PR [#372](https://github.com/tact-lang/tact/pull/372) - `__tact_load_address_opt` code generation: PR [#373](https://github.com/tact-lang/tact/pull/373) +- All integer and boolean expressions are now being attempted to be evaluated as constants. Additionally, compile-time errors are thrown for errors encountered during the evaluation of actual constants: PR [#352](https://github.com/tact-lang/tact/pull/352) ## [1.3.0] - 2024-05-03 From 2c5a9c5b858b2c02852adf68caf7b48b44dfe7cb Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 23 May 2024 09:28:42 +0300 Subject: [PATCH 06/11] update snapshot --- src/test/__snapshots__/feature-implicit-init.spec.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/__snapshots__/feature-implicit-init.spec.ts.snap b/src/test/__snapshots__/feature-implicit-init.spec.ts.snap index e1154c1f0c..0e9701228c 100644 --- a/src/test/__snapshots__/feature-implicit-init.spec.ts.snap +++ b/src/test/__snapshots__/feature-implicit-init.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`feature-send should deploy 1`] = ` +exports[`feature-implicit-init should deploy 1`] = ` [ { "$seq": 0, @@ -53,7 +53,7 @@ exports[`feature-send should deploy 1`] = ` ] `; -exports[`feature-send should increment counter 1`] = ` +exports[`feature-implicit-init should increment counter 1`] = ` [ { "$seq": 1, From f4e787c94d3ed102c2d6de6566915b6da85a206a Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 26 May 2024 16:23:46 +0300 Subject: [PATCH 07/11] move compilation-fail tests to a separate directory --- .../contracts}/const-eval.tact | 0 .../contracts/implicit-init.tact} | 0 .../contracts}/invalid-address.tact | 0 .../compilation-fail/fail-const-eval.spec.ts | 43 +++++++++++++++++++ .../fail-implicit-init.spec.ts} | 16 +++---- src/test/compilation-fail/tact.config.json | 20 +++++++++ src/test/feature-implicit-init.spec.ts | 25 ----------- src/test/test-tact.config.json | 23 ---------- 8 files changed, 71 insertions(+), 56 deletions(-) rename src/test/{features => compilation-fail/contracts}/const-eval.tact (100%) rename src/test/{features/implicit-init-2.tact => compilation-fail/contracts/implicit-init.tact} (100%) rename src/test/{features => compilation-fail/contracts}/invalid-address.tact (100%) create mode 100644 src/test/compilation-fail/fail-const-eval.spec.ts rename src/test/{feature-const-eval.spec.ts => compilation-fail/fail-implicit-init.spec.ts} (57%) create mode 100644 src/test/compilation-fail/tact.config.json delete mode 100644 src/test/test-tact.config.json diff --git a/src/test/features/const-eval.tact b/src/test/compilation-fail/contracts/const-eval.tact similarity index 100% rename from src/test/features/const-eval.tact rename to src/test/compilation-fail/contracts/const-eval.tact diff --git a/src/test/features/implicit-init-2.tact b/src/test/compilation-fail/contracts/implicit-init.tact similarity index 100% rename from src/test/features/implicit-init-2.tact rename to src/test/compilation-fail/contracts/implicit-init.tact diff --git a/src/test/features/invalid-address.tact b/src/test/compilation-fail/contracts/invalid-address.tact similarity index 100% rename from src/test/features/invalid-address.tact rename to src/test/compilation-fail/contracts/invalid-address.tact diff --git a/src/test/compilation-fail/fail-const-eval.spec.ts b/src/test/compilation-fail/fail-const-eval.spec.ts new file mode 100644 index 0000000000..70bf90d3c4 --- /dev/null +++ b/src/test/compilation-fail/fail-const-eval.spec.ts @@ -0,0 +1,43 @@ +import { __DANGER_resetNodeId } from "../../grammar/ast"; +import { run } from "../../node"; +import { consoleLogger } from "../../logger"; + +describe("fail-const-eval", () => { + beforeAll(() => { + jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); + }); + + beforeEach(() => { + __DANGER_resetNodeId(); + }); + + afterAll(() => { + (consoleLogger.error as jest.Mock).mockRestore(); + }); + + afterEach(() => { + (consoleLogger.error as jest.Mock).mockClear(); + }); + + it("should not compile with division by zero", async () => { + const result = await run({ + configPath: __dirname + "/tact.config.json", + projectNames: ["const-eval"], + }); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + "Cannot divide by zero", + ); + expect(result).toBe(false); + }); + + it("should not compile with invalid address", async () => { + const result = await run({ + configPath: __dirname + "/tact.config.json", + projectNames: ["invalid-address"], + }); + expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( + "FQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N is not a valid address", + ); + expect(result).toBe(false); + }); +}); diff --git a/src/test/feature-const-eval.spec.ts b/src/test/compilation-fail/fail-implicit-init.spec.ts similarity index 57% rename from src/test/feature-const-eval.spec.ts rename to src/test/compilation-fail/fail-implicit-init.spec.ts index a7a64a0f24..03f9e5522c 100644 --- a/src/test/feature-const-eval.spec.ts +++ b/src/test/compilation-fail/fail-implicit-init.spec.ts @@ -1,8 +1,8 @@ -import { __DANGER_resetNodeId } from "../grammar/ast"; -import { run } from "../node"; -import { consoleLogger } from "../logger"; +import { __DANGER_resetNodeId } from "../../grammar/ast"; +import { run } from "../../node"; +import { consoleLogger } from "../../logger"; -describe("feature-const-eval", () => { +describe("fail-implicit-init", () => { beforeAll(() => { jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); }); @@ -19,13 +19,13 @@ describe("feature-const-eval", () => { (consoleLogger.error as jest.Mock).mockClear(); }); - it("should not compile with division by zero", async () => { + it("should not compile with uninitialized storage fields", async () => { const result = await run({ - configPath: __dirname + "/test-tact.config.json", - projectNames: ["const-eval"], + configPath: __dirname + "/tact.config.json", + projectNames: ["implicit-init"], }); expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - "Cannot divide by zero", + "Field test_field is not set", ); expect(result).toBe(false); }); diff --git a/src/test/compilation-fail/tact.config.json b/src/test/compilation-fail/tact.config.json new file mode 100644 index 0000000000..9a77777704 --- /dev/null +++ b/src/test/compilation-fail/tact.config.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", + "projects": [ + { + "name": "implicit-init", + "path": "./contracts/implicit-init.tact", + "output": "./contracts/output" + }, + { + "name": "invalid-address", + "path": "./contracts/invalid-address.tact", + "output": "./contracts/output" + }, + { + "name": "const-eval", + "path": "./contracts/const-eval.tact", + "output": "./contracts/output" + } + ] +} diff --git a/src/test/feature-implicit-init.spec.ts b/src/test/feature-implicit-init.spec.ts index b98672413c..7379c588ef 100644 --- a/src/test/feature-implicit-init.spec.ts +++ b/src/test/feature-implicit-init.spec.ts @@ -2,26 +2,12 @@ import { toNano } from "@ton/core"; import { ContractSystem } from "@tact-lang/emulator"; import { __DANGER_resetNodeId } from "../grammar/ast"; import { MyContract } from "./features/output/implicit-init_MyContract"; -import { run } from "../node"; -import { consoleLogger } from "../logger"; describe("feature-implicit-init", () => { - beforeAll(() => { - jest.spyOn(consoleLogger, "error").mockImplementation(() => {}); - }); - beforeEach(() => { __DANGER_resetNodeId(); }); - afterAll(() => { - (consoleLogger.error as jest.Mock).mockRestore(); - }); - - afterEach(() => { - (consoleLogger.error as jest.Mock).mockClear(); - }); - it("should deploy", async () => { // Init const system = await ContractSystem.create(); @@ -61,15 +47,4 @@ describe("feature-implicit-init", () => { expect(await contract.getGetCounter()).toBe(2n); expect(tracker.collect()).toMatchSnapshot(); }); - - it("should not compile with uninitialized storage fields", async () => { - const result = await run({ - configPath: __dirname + "/test-tact.config.json", - projectNames: ["implicit-init-2"], - }); - expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - 'Field "test_field" is not set', - ); - expect(result).toBe(false); - }); }); diff --git a/src/test/test-tact.config.json b/src/test/test-tact.config.json deleted file mode 100644 index b4c4ea8813..0000000000 --- a/src/test/test-tact.config.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://raw.githubusercontent.com/tact-lang/tact/main/grammar/configSchema.json", - "projects": [ - { - "name": "implicit-init-2", - "path": "./features/implicit-init-2.tact", - "output": "./features/output", - "options": { - "debug": true - } - }, - { - "name": "invalid-address", - "path": "./features/invalid-address.tact", - "output": "./features/output" - }, - { - "name": "const-eval", - "path": "./features/const-eval.tact", - "output": "./features/output" - } - ] -} From adb9a2f40ce933559ea36a07c39122eb4d91cfc9 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Sun, 26 May 2024 16:25:15 +0300 Subject: [PATCH 08/11] fix --- src/test/compilation-fail/fail-const-eval.spec.ts | 4 ++-- src/test/compilation-fail/fail-implicit-init.spec.ts | 2 +- src/test/feature-address.spec.ts | 11 ----------- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/test/compilation-fail/fail-const-eval.spec.ts b/src/test/compilation-fail/fail-const-eval.spec.ts index 70bf90d3c4..f8fb640c04 100644 --- a/src/test/compilation-fail/fail-const-eval.spec.ts +++ b/src/test/compilation-fail/fail-const-eval.spec.ts @@ -24,10 +24,10 @@ describe("fail-const-eval", () => { configPath: __dirname + "/tact.config.json", projectNames: ["const-eval"], }); + expect(result).toBe(false); expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( "Cannot divide by zero", ); - expect(result).toBe(false); }); it("should not compile with invalid address", async () => { @@ -35,9 +35,9 @@ describe("fail-const-eval", () => { configPath: __dirname + "/tact.config.json", projectNames: ["invalid-address"], }); + expect(result).toBe(false); expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( "FQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N is not a valid address", ); - expect(result).toBe(false); }); }); diff --git a/src/test/compilation-fail/fail-implicit-init.spec.ts b/src/test/compilation-fail/fail-implicit-init.spec.ts index 03f9e5522c..d6470d48d1 100644 --- a/src/test/compilation-fail/fail-implicit-init.spec.ts +++ b/src/test/compilation-fail/fail-implicit-init.spec.ts @@ -24,9 +24,9 @@ describe("fail-implicit-init", () => { configPath: __dirname + "/tact.config.json", projectNames: ["implicit-init"], }); + expect(result).toBe(false); expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( "Field test_field is not set", ); - expect(result).toBe(false); }); }); diff --git a/src/test/feature-address.spec.ts b/src/test/feature-address.spec.ts index 731ef03f73..37e58f7102 100644 --- a/src/test/feature-address.spec.ts +++ b/src/test/feature-address.spec.ts @@ -40,15 +40,4 @@ describe("feature-address", () => { "0:4a81708d2cf7b15a1b362fbf64880451d698461f52f05f145b36c08517d76873", ); }); - - it("should not compile with uninitialized storage fields", async () => { - const result = await run({ - configPath: __dirname + "/test-tact.config.json", - projectNames: ["invalid-address"], - }); - expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - "FQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N is not a valid address", - ); - expect(result).toBe(false); - }); }); From 918872e18ff4e4c750825f954fa935cdca9b5155 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Mon, 27 May 2024 13:57:07 +0300 Subject: [PATCH 09/11] fix eslint --- src/test/feature-address.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/feature-address.spec.ts b/src/test/feature-address.spec.ts index 37e58f7102..bbd61f77ad 100644 --- a/src/test/feature-address.spec.ts +++ b/src/test/feature-address.spec.ts @@ -3,7 +3,6 @@ import { ContractSystem } from "@tact-lang/emulator"; import { __DANGER_resetNodeId } from "../grammar/ast"; import { AddressTester } from "./features/output/address_AddressTester"; import { consoleLogger } from "../logger"; -import { run } from "../node"; describe("feature-address", () => { beforeAll(() => { From b56bd5ae0872a9944a6dee1615952607af30fd76 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 6 Jun 2024 14:45:08 +0300 Subject: [PATCH 10/11] fix test --- src/test/compilation-fail/fail-implicit-init.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compilation-fail/fail-implicit-init.spec.ts b/src/test/compilation-fail/fail-implicit-init.spec.ts index d6470d48d1..89b65b0bcc 100644 --- a/src/test/compilation-fail/fail-implicit-init.spec.ts +++ b/src/test/compilation-fail/fail-implicit-init.spec.ts @@ -26,7 +26,7 @@ describe("fail-implicit-init", () => { }); expect(result).toBe(false); expect((consoleLogger.error as jest.Mock).mock.lastCall[0]).toContain( - "Field test_field is not set", + 'Field "test_field" is not set', ); }); }); From 7753e337262578e111e2b48695fda038782f8be1 Mon Sep 17 00:00:00 2001 From: Gusarich Date: Thu, 6 Jun 2024 14:52:33 +0300 Subject: [PATCH 11/11] add test to cspell ignore list --- cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.json b/cspell.json index e80a984cff..c1680300a6 100644 --- a/cspell.json +++ b/cspell.json @@ -84,6 +84,7 @@ "src/test/feature-strings.spec.ts", "src/test/features/intrinsics.tact", "src/test/features/strings.tact", + "src/test/compilation-fail/fail-const-eval.spec.ts", "stdlib/stdlib.fc" ] }