@layerzerolabs/layerzero-v2-ton 3.0.72 → 3.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/layerzero-v2-ton",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.74",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"tests/testMain.fc",
|
|
38
38
|
"tests/baseContractTest.fc",
|
|
39
39
|
"tests/baseSerdeTest.fc",
|
|
40
|
+
"tests/utils/**/*.ts",
|
|
40
41
|
"src/multisig/bocs/MultiSig.compiled.json",
|
|
41
42
|
"src/multisig/bocs/MultiSigOrder.compiled.json"
|
|
42
43
|
],
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Cell, toNano } from '@ton/core'
|
|
2
|
+
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox'
|
|
3
|
+
|
|
4
|
+
import { UnitTestWrapper } from './UnitTestWrapper'
|
|
5
|
+
import { GlobalTestResults } from './types/GlobalTestResults'
|
|
6
|
+
|
|
7
|
+
import '@ton/test-utils'
|
|
8
|
+
|
|
9
|
+
export const throwIfFailedTest = (testName: string, testCases: { [key: string]: boolean }): string => {
|
|
10
|
+
const passedTests = Object.keys(testCases).filter((test) => testCases[test])
|
|
11
|
+
const failedTests = Object.keys(testCases).filter((test) => !testCases[test])
|
|
12
|
+
|
|
13
|
+
let printStr = testName + '\n'
|
|
14
|
+
if (passedTests.length > 0) {
|
|
15
|
+
printStr += `\x1b[32m ✓ ${passedTests.length} tests passed.\n`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (failedTests.length > 0) {
|
|
19
|
+
printStr += `\x1b[31m ❌ ${failedTests.length} tests failed:\n`
|
|
20
|
+
failedTests.forEach((test) => {
|
|
21
|
+
printStr += ` - ${test}\n`
|
|
22
|
+
})
|
|
23
|
+
throw new Error(printStr)
|
|
24
|
+
}
|
|
25
|
+
return printStr
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const getTestSummary = (testName: string, testCases: { [key: string]: boolean }): string => {
|
|
29
|
+
const passedTests = Object.keys(testCases).filter((test) => testCases[test])
|
|
30
|
+
const failedTests = Object.keys(testCases).filter((test) => !testCases[test])
|
|
31
|
+
|
|
32
|
+
let printStr = testName + '\n'
|
|
33
|
+
if (passedTests.length > 0) {
|
|
34
|
+
printStr += `\x1b[32m ✓ ${passedTests.length} tests passed.\n`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (failedTests.length > 0) {
|
|
38
|
+
printStr += `\x1b[31m ❌ ${failedTests.length} tests failed:\n`
|
|
39
|
+
failedTests.forEach((test) => {
|
|
40
|
+
printStr += ` - ${test}\n`
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
return printStr
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const runUnitTests = (testName: string, code: Cell, globalTestResults: GlobalTestResults): GlobalTestResults => {
|
|
47
|
+
describe(testName, () => {
|
|
48
|
+
let blockchain: Blockchain
|
|
49
|
+
let testCase: SandboxContract<UnitTestWrapper>
|
|
50
|
+
let deployer: SandboxContract<TreasuryContract>
|
|
51
|
+
|
|
52
|
+
beforeEach(async () => {
|
|
53
|
+
blockchain = await Blockchain.create()
|
|
54
|
+
|
|
55
|
+
testCase = blockchain.openContract(UnitTestWrapper.createFromConfig({}, code))
|
|
56
|
+
|
|
57
|
+
deployer = await blockchain.treasury('deployer')
|
|
58
|
+
|
|
59
|
+
const deployResult = await testCase.sendDeploy(deployer.getSender(), toNano('1'))
|
|
60
|
+
|
|
61
|
+
expect(deployResult.transactions).toHaveTransaction({
|
|
62
|
+
from: deployer.address,
|
|
63
|
+
to: testCase.address,
|
|
64
|
+
deploy: true,
|
|
65
|
+
success: true,
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it(testName, async () => {
|
|
70
|
+
let done = false
|
|
71
|
+
const test_results: { [key: string]: boolean } = {}
|
|
72
|
+
for (let testNum = 0n; !done; testNum++) {
|
|
73
|
+
// the check is done inside beforeEach
|
|
74
|
+
// blockchain and testCase are ready to use
|
|
75
|
+
const result = await testCase.sendTest(deployer.getSender(), toNano('10000'), testNum)
|
|
76
|
+
// search the json stringified result for the string "unhandled out-of-gas exception"
|
|
77
|
+
const txns = result.transactions
|
|
78
|
+
|
|
79
|
+
let unhandledException = false
|
|
80
|
+
// starting from -1 because the first one is the external message from wallet to contract
|
|
81
|
+
txns.forEach((item) => {
|
|
82
|
+
if (item.vmLogs.toString().includes('unhandled out-of-gas exception')) {
|
|
83
|
+
console.log(`Test number ${testNum} OUT OF GAS`)
|
|
84
|
+
}
|
|
85
|
+
if (item.vmLogs.toString().includes('default exception handler')) {
|
|
86
|
+
console.error(`Unhandled exception in ${testName} test ${testNum}`)
|
|
87
|
+
unhandledException = true
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
done = result.externals.some((item) => {
|
|
92
|
+
const event_topic = item.info.dest?.value
|
|
93
|
+
if (event_topic == 1n) {
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
return false
|
|
97
|
+
})
|
|
98
|
+
if (!done) {
|
|
99
|
+
const contractTestName = await testCase.getTestName(deployer.getSender(), testNum)
|
|
100
|
+
let success = true
|
|
101
|
+
result.events.forEach((item) => {
|
|
102
|
+
// TODO fix this
|
|
103
|
+
// @ts-expect-error type mismatch
|
|
104
|
+
if (item.bounced as boolean) {
|
|
105
|
+
success = false
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
if (contractTestName in test_results) {
|
|
109
|
+
throw new Error(`Duplicate test name ${contractTestName}`)
|
|
110
|
+
}
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
112
|
+
test_results[contractTestName] = success && !unhandledException
|
|
113
|
+
globalTestResults[testName] = test_results
|
|
114
|
+
expect(success)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
return globalTestResults
|
|
121
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Address, Cell, Contract, ContractProvider, SendMode, Sender, beginCell, contractAddress } from '@ton/core'
|
|
2
|
+
|
|
3
|
+
export interface UnitTestConfig {}
|
|
4
|
+
|
|
5
|
+
export function testCaseConfigToCell(config: UnitTestConfig): Cell {
|
|
6
|
+
return beginCell().endCell()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class UnitTestWrapper implements Contract {
|
|
10
|
+
constructor(
|
|
11
|
+
readonly address: Address,
|
|
12
|
+
readonly init?: { code: Cell; data: Cell }
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
static createFromAddress(address: Address): UnitTestWrapper {
|
|
16
|
+
return new UnitTestWrapper(address)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static createFromConfig(config: UnitTestConfig, code: Cell, workchain = 0): UnitTestWrapper {
|
|
20
|
+
const data = testCaseConfigToCell(config)
|
|
21
|
+
const init = { code, data }
|
|
22
|
+
return new UnitTestWrapper(contractAddress(workchain, init), init)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async sendDeploy(provider: ContractProvider, via: Sender, value: bigint): Promise<void> {
|
|
26
|
+
await provider.internal(via, {
|
|
27
|
+
value,
|
|
28
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
29
|
+
body: beginCell().endCell(),
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async sendTest(provider: ContractProvider, via: Sender, value: bigint, testNum = 0n): Promise<void> {
|
|
34
|
+
await provider.internal(via, {
|
|
35
|
+
value,
|
|
36
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
37
|
+
// opcode, query_id, failed_count, success_count
|
|
38
|
+
body: beginCell()
|
|
39
|
+
.storeUint(testNum, 32)
|
|
40
|
+
.storeUint(1, 64) // query_id
|
|
41
|
+
.storeUint(BigInt('0x' + via.address!.hash.toString('hex')), 256)
|
|
42
|
+
.storeCoins(0)
|
|
43
|
+
.storeRef(beginCell().endCell())
|
|
44
|
+
.endCell(),
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async getTestName(provider: ContractProvider, via: Sender, testNum = 0n): Promise<string> {
|
|
49
|
+
const { stack } = await provider.get('get_test_name', [{ type: 'int', value: testNum }])
|
|
50
|
+
return stack.readString()
|
|
51
|
+
}
|
|
52
|
+
}
|