Skip to content

Commit 4edce80

Browse files
committed
add tests for circular reference
1 parent 782af0e commit 4edce80

File tree

4 files changed

+104
-13
lines changed

4 files changed

+104
-13
lines changed

src/subcontexts/contract-context.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import { BytesMap } from '../collections/custom-key-map'
1414
import { checkRoutingConditions } from '../context-helpers/context-util'
1515
import { lazyContext } from '../context-helpers/internal-context'
1616
import { CodeError } from '../errors'
17-
import { BaseContract, ContractOptionsSymbol } from '../impl/base-contract'
18-
import { Contract } from '../impl/contract'
17+
import type { BaseContract } from '../impl/base-contract'
18+
import { ContractOptionsSymbol } from '../impl/base-contract'
19+
import type { Contract } from '../impl/contract'
1920
import { getArc4Encoded, Uint, type TypeInfo } from '../impl/encoded-types'
2021
import { Bytes } from '../impl/primitives'
2122
import { AccountCls, ApplicationCls, AssetCls } from '../impl/reference'
@@ -222,18 +223,8 @@ export class ContractContext {
222223
if (result !== undefined && result !== null) {
223224
return result
224225
}
225-
// TODO: uncomment the following line once version puya-ts 1.0.0 is released and delete the rest of the function
226-
// throw new internal.errors.CodeError('Cannot create a contract for class as it does not extend Contract or BaseContract')
227226

228-
const proto = Object.getPrototypeOf(type)
229-
if (proto === BaseContract) {
230-
return false
231-
} else if (proto === Contract) {
232-
return true
233-
} else if (proto === Object || proto === null) {
234-
throw new CodeError('Cannot create a contract for class as it does not extend Contract or BaseContract')
235-
}
236-
return this.isArc4(proto)
227+
throw new CodeError('Cannot create a contract for class as it does not extend Contract or BaseContract')
237228
}
238229

239230
/**
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { algo } from '@algorandfoundation/algokit-utils'
2+
import { methodSelector } from '@algorandfoundation/algorand-typescript/arc4'
3+
import { afterEach, beforeAll, describe, expect } from 'vitest'
4+
import { ApplicationSpy } from '../../src/application-spy'
5+
import { TestExecutionContext } from '../../src/test-execution-context'
6+
import { ContractTwo } from '../artifacts/circurlar-reference/circular-reference-2.algo'
7+
import { ContractOne } from '../artifacts/circurlar-reference/circular-reference.algo'
8+
import { createArc4TestFixture } from '../test-fixture'
9+
10+
describe('circular reference', () => {
11+
const ctx = new TestExecutionContext()
12+
const [test, localnetFixture] = createArc4TestFixture('tests/artifacts/circurlar-reference', {
13+
ContractOne: { funding: algo(1) },
14+
ContractTwo: { funding: algo(1) },
15+
})
16+
17+
beforeAll(async () => {
18+
await localnetFixture.newScope()
19+
})
20+
21+
afterEach(() => {
22+
ctx.reset()
23+
})
24+
25+
test('test call contract one', async ({ appClientContractOne, appClientContractTwo }) => {
26+
const result = await appClientContractOne.send.call({
27+
method: 'test',
28+
args: [appClientContractTwo.appId],
29+
extraFee: algo(1),
30+
})
31+
expect(result.return).toEqual(appClientContractTwo.appId)
32+
33+
const contractOne = ctx.contract.create(ContractOne)
34+
const contractTwo = ctx.contract.create(ContractTwo)
35+
const contractTwoApp = ctx.ledger.getApplicationForContract(contractTwo)
36+
37+
const spy = new ApplicationSpy()
38+
spy.onAbiCall(methodSelector(ContractTwo.prototype.receiver), (itxnContext) => {
39+
itxnContext.setReturnValue(contractTwoApp.id)
40+
})
41+
ctx.addApplicationSpy(spy)
42+
43+
const output = contractOne.test(contractTwoApp)
44+
expect(output).toEqual(contractTwoApp.id)
45+
})
46+
47+
test('test call contract two', async ({ appClientContractOne, appClientContractTwo }) => {
48+
const result = await appClientContractTwo.send.call({
49+
method: 'test',
50+
args: [appClientContractOne.appId],
51+
extraFee: algo(1),
52+
})
53+
expect(result.return).toEqual(appClientContractOne.appId)
54+
55+
const contractOne = ctx.contract.create(ContractOne)
56+
const contractTwo = ctx.contract.create(ContractTwo)
57+
const contractOneApp = ctx.ledger.getApplicationForContract(contractOne)
58+
59+
const spy = new ApplicationSpy()
60+
spy.onAbiCall(methodSelector(ContractOne.prototype.receiver), (itxnContext) => {
61+
itxnContext.setReturnValue(contractOneApp.id)
62+
})
63+
ctx.addApplicationSpy(spy)
64+
65+
const output = contractTwo.test(contractOneApp)
66+
expect(output).toEqual(contractOneApp.id)
67+
})
68+
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Application } from '@algorandfoundation/algorand-typescript'
2+
import { Contract, log } from '@algorandfoundation/algorand-typescript'
3+
import { abiCall } from '@algorandfoundation/algorand-typescript/arc4'
4+
import type { ContractOne } from './circular-reference.algo'
5+
6+
export class ContractTwo extends Contract {
7+
test(appId: Application) {
8+
const result = abiCall<typeof ContractOne.prototype.receiver>({ appId, args: [appId] })
9+
return result.returnValue
10+
}
11+
12+
receiver(appId: Application) {
13+
log(appId.id)
14+
return appId.id
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Application } from '@algorandfoundation/algorand-typescript'
2+
import { Contract, log } from '@algorandfoundation/algorand-typescript'
3+
import { abiCall } from '@algorandfoundation/algorand-typescript/arc4'
4+
import type { ContractTwo } from './circular-reference-2.algo'
5+
6+
export class ContractOne extends Contract {
7+
test(appId: Application) {
8+
const result = abiCall<typeof ContractTwo.prototype.receiver>({ appId, args: [appId] })
9+
return result.returnValue
10+
}
11+
12+
receiver(appId: Application) {
13+
log(appId.id)
14+
return appId.id
15+
}
16+
}

0 commit comments

Comments
 (0)