Skip to content

Commit 1e6ae8d

Browse files
authored
Merge pull request #42 from algorandfoundation/refactor/fixture
refactor: use algorandFixture for more reliable test execution
2 parents 848d011 + 70f5fc7 commit 1e6ae8d

File tree

98 files changed

+7304
-6070
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+7304
-6070
lines changed

package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"build-examples": "rollup --config examples/rollup.config.ts --configPlugin typescript"
2626
},
2727
"devDependencies": {
28-
"@algorandfoundation/algokit-utils": "^8.0.3",
28+
"@algorandfoundation/algokit-utils": "^8.1.0",
2929
"@commitlint/cli": "^19.5.0",
3030
"@commitlint/config-conventional": "^19.5.0",
3131
"@eslint/eslintrc": "3.1.0",
@@ -64,8 +64,8 @@
6464
"tslib": "^2.6.2"
6565
},
6666
"dependencies": {
67-
"@algorandfoundation/algorand-typescript": "^1.0.0-beta.11",
68-
"@algorandfoundation/puya-ts": "^1.0.0-beta.13",
67+
"@algorandfoundation/algorand-typescript": "^1.0.0-beta.13",
68+
"@algorandfoundation/puya-ts": "^1.0.0-beta.15",
6969
"elliptic": "^6.5.7",
7070
"js-sha256": "^0.11.0",
7171
"js-sha3": "^0.9.3",

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { internal } from '@algorandfoundation/algorand-typescript'
22

3+
export { addEqualityTesters } from './set-up'
34
export { TestExecutionContext } from './test-execution-context'
45
export const encodingUtil = {
56
...internal.encodingUtil,

src/set-up.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ interface ExpectObj {
1111
addEqualityTesters: (testers: Array<Tester>) => void
1212
}
1313

14-
function addEqualityTesters(expectObj: ExpectObj) {
14+
function doAddEqualityTesters(expectObj: ExpectObj) {
1515
expectObj.addEqualityTesters([
1616
function IsSamePrimitiveTypeAndValue(this: TesterContext, subject, test, customTesters): boolean | undefined {
1717
const subjectIsPrimitive = subject instanceof internal.primitives.AlgoTsPrimitiveCls
@@ -44,7 +44,8 @@ function addEqualityTesters(expectObj: ExpectObj) {
4444
},
4545
function BytesPrimitiveIsArray(this: TesterContext, subject, test, customTesters): boolean | undefined {
4646
if (subject instanceof internal.primitives.BytesCls) {
47-
const testValue = Array.isArray(test) && test.every((i) => typeof i === 'number') ? new Uint8Array(test) : undefined
47+
const testValue =
48+
Array.isArray(test) && test.every((i) => typeof i === 'number' && i >= 0 && i < 256) ? new Uint8Array(test) : undefined
4849
if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters)
4950
return undefined
5051
}
@@ -108,6 +109,6 @@ function addEqualityTesters(expectObj: ExpectObj) {
108109
])
109110
}
110111

111-
export function setUpTests({ expect }: { expect: ExpectObj }) {
112-
addEqualityTesters(expect)
112+
export function addEqualityTesters({ expect }: { expect: ExpectObj }) {
113+
doAddEqualityTesters(expect)
113114
}

src/test-execution-context.ts

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,7 @@ import { internal } from '@algorandfoundation/algorand-typescript'
33
import { captureMethodConfig } from './abi-metadata'
44
import { DEFAULT_TEMPLATE_VAR_PREFIX } from './constants'
55
import type { DecodedLogs, LogDecoding } from './decode-logs'
6-
import { ApplicationTxn, AssetConfigTxn, AssetFreezeTxn, AssetTransferTxn, KeyRegistrationTxn, PaymentTxn, Transaction } from './impl/gtxn'
7-
import {
8-
applicationCall as itxnApplicationCall,
9-
assetConfig as itxnAssetConfig,
10-
assetFreeze as itxnAssetFreeze,
11-
assetTransfer as itxnAssetTransfer,
12-
keyRegistration as itxnKeyRegistration,
13-
payment as itxnPayment,
14-
submitGroup as itxnSubmitGroup,
15-
} from './impl/inner-transactions'
16-
import { Account } from './impl/reference'
17-
import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state'
6+
import { Account, AccountCls } from './impl/reference'
187
import { ContractContext } from './subcontexts/contract-context'
198
import { LedgerContext } from './subcontexts/ledger-context'
209
import { TransactionContext } from './subcontexts/transaction-context'
@@ -67,47 +56,14 @@ export class TestExecutionContext implements internal.ExecutionContext {
6756
return this.#defaultSender
6857
}
6958

70-
/* @internal */
71-
get abiMetadata() {
72-
return {
73-
captureMethodConfig,
74-
}
59+
set defaultSender(val: bytes | AccountType) {
60+
this.#defaultSender = val instanceof AccountCls ? val : Account(val as bytes)
7561
}
7662

7763
/* @internal */
78-
get gtxn() {
79-
return {
80-
Transaction,
81-
PaymentTxn,
82-
KeyRegistrationTxn,
83-
AssetConfigTxn,
84-
AssetTransferTxn,
85-
AssetFreezeTxn,
86-
ApplicationTxn,
87-
}
88-
}
89-
90-
/* @internal */
91-
get itxn() {
92-
return {
93-
submitGroup: itxnSubmitGroup,
94-
payment: itxnPayment,
95-
keyRegistration: itxnKeyRegistration,
96-
assetConfig: itxnAssetConfig,
97-
assetTransfer: itxnAssetTransfer,
98-
assetFreeze: itxnAssetFreeze,
99-
applicationCall: itxnApplicationCall,
100-
}
101-
}
102-
103-
/* @internal */
104-
get state() {
64+
get abiMetadata() {
10565
return {
106-
GlobalState,
107-
LocalState,
108-
Box,
109-
BoxMap,
110-
BoxRef,
66+
captureMethodConfig,
11167
}
11268
}
11369

tests/arc4/bool.spec.ts

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,66 @@
1-
import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec'
21
import { Bytes } from '@algorandfoundation/algorand-typescript'
32
import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing'
43
import { Bool, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4'
5-
import { afterEach, describe, expect, test } from 'vitest'
4+
import { afterEach, beforeAll, describe, expect } from 'vitest'
65
import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants'
76
import { asUint8Array } from '../../src/util'
8-
import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json'
9-
import { getAlgorandAppClient, getAvmResult } from '../avm-invoker'
7+
import { getAvmResult } from '../avm-invoker'
8+
import { createArc4TestFixture } from '../test-fixture'
109

1110
describe('arc4.Bool', async () => {
12-
const appClient = await getAlgorandAppClient(appSpecJson as AppSpec)
11+
const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json', {
12+
Arc4PrimitiveOpsContract: { deployParams: { createParams: { extraProgramPages: undefined } } },
13+
})
1314
const ctx = new TestExecutionContext()
1415

16+
beforeAll(async () => {
17+
await localnetFixture.newScope()
18+
})
19+
1520
afterEach(() => {
1621
ctx.reset()
1722
})
1823

19-
test.each([true, false])('should be able to get bytes representation of %s', async (value) => {
20-
const avmResult = await getAvmResult({ appClient }, 'verify_bool_bytes', value)
21-
const result = new Bool(value)
22-
expect(result.bytes).toEqual(avmResult)
23-
})
24+
test.for([true, false])(
25+
'should be able to get bytes representation of %s',
26+
async (value, { appClientArc4PrimitiveOpsContract: appClient }) => {
27+
const avmResult = await getAvmResult({ appClient }, 'verify_bool_bytes', value)
28+
const result = new Bool(value)
29+
expect(result.bytes).toEqual(avmResult)
30+
},
31+
)
2432

25-
test.each([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])('create Bool from bytes', async (value) => {
26-
const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_bytes', value)
27-
const result = interpretAsArc4<Bool>(Bytes(value))
28-
expect(result.native).toEqual(avmResult)
29-
})
33+
test.for([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])(
34+
'create Bool from bytes',
35+
async (value, { appClientArc4PrimitiveOpsContract: appClient }) => {
36+
const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_bytes', value)
37+
const result = interpretAsArc4<Bool>(Bytes(value))
38+
expect(result.native).toEqual(avmResult)
39+
},
40+
)
3041

31-
test.each([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])('create Bool from log', async (value) => {
32-
const paddedValue = new Uint8Array([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...value])
33-
const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)
34-
const result = interpretAsArc4<Bool>(Bytes(paddedValue), 'log')
35-
expect(result.native).toEqual(avmResult)
36-
})
42+
test.for([asUint8Array(Bytes.fromHex('00')), asUint8Array(Bytes.fromHex('80'))])(
43+
'create Bool from log',
44+
async (value, { appClientArc4PrimitiveOpsContract: appClient }) => {
45+
const paddedValue = new Uint8Array([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...value])
46+
const avmResult = await getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)
47+
const result = interpretAsArc4<Bool>(Bytes(paddedValue), 'log')
48+
expect(result.native).toEqual(avmResult)
49+
},
50+
)
3751

38-
test.each([
52+
test.for([
3953
[asUint8Array(Bytes.fromHex('00')), asUint8Array('')],
4054
[asUint8Array(Bytes.fromHex('80')), asUint8Array(Bytes.fromHex('ff000102'))],
4155
[asUint8Array(Bytes.fromHex('00')), asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.slice(0, 3))],
42-
])('should throw error when log prefix is invalid for Bool', async (value, prefix) => {
43-
const paddedValue = new Uint8Array([...prefix, ...value])
44-
await expect(() => getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)).rejects.toThrowError(
45-
new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'),
46-
)
47-
expect(() => interpretAsArc4<Bool>(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found')
48-
})
56+
])(
57+
'should throw error when log prefix is invalid for Bool',
58+
async ([value, prefix], { appClientArc4PrimitiveOpsContract: appClient }) => {
59+
const paddedValue = new Uint8Array([...prefix, ...value])
60+
await expect(() => getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)).rejects.toThrowError(
61+
new RegExp('(has valid prefix)|(extraction start \\d+ is beyond length)'),
62+
)
63+
expect(() => interpretAsArc4<Bool>(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found')
64+
},
65+
)
4966
})

0 commit comments

Comments
 (0)