diff --git a/package-lock.json b/package-lock.json index d9d7e254..94859f0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.49", - "@algorandfoundation/puya-ts": "1.0.0-alpha.49", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.51", + "@algorandfoundation/puya-ts": "1.0.0-alpha.51", "elliptic": "^6.6.1", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -73,21 +73,21 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "1.0.0-alpha.49", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-1.0.0-alpha.49.tgz", - "integrity": "sha512-fZhuOGl9iAzeea7VvK0VCvi0aXy1yDjgIYKvNgG+4wwFNeUTVBDZGjwWspDYhlO5Jk+iaJX1kVLgwwh+/XG4+A==", + "version": "1.0.0-alpha.51", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-1.0.0-alpha.51.tgz", + "integrity": "sha512-r6QHmKvoO+//Vo3gM2vfjbAHBsUnrLTejNrGyETD1s/95hHAo5+VgqOIwo4fkfuvtErQXEj8hfCHcMtSO4MBGQ==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.49", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.49.tgz", - "integrity": "sha512-WV4nBLgJ1u/vMQja1c1K0UYFwmZlmzGDovBzR4AJkyq8+/GSwKviIC1c1/FbR6w4ibE/dlzDuZcc2AouY00gjg==", + "version": "1.0.0-alpha.51", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.51.tgz", + "integrity": "sha512-5rfhj4+DIKMRthqHaibiKBze0kQyLQuIalQ8Y6U6bEPYyItWWq7e7cyAcA1gmv87uGVYcQF3JN6O9S1a3f3l3w==", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.49", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.51", "arcsecond": "^5.0.0", "argparse": "^2.0.1", "chalk": "^5.4.1", diff --git a/package.json b/package.json index 1ab5a994..7894422f 100644 --- a/package.json +++ b/package.json @@ -66,8 +66,8 @@ "vitest": "3.0.9" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.49", - "@algorandfoundation/puya-ts": "1.0.0-alpha.49", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.51", + "@algorandfoundation/puya-ts": "1.0.0-alpha.51", "elliptic": "^6.6.1", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", diff --git a/src/impl/match.ts b/src/impl/match.ts index c1c2c105..ca553c95 100644 --- a/src/impl/match.ts +++ b/src/impl/match.ts @@ -7,6 +7,9 @@ import type { StubBytesCompat, Uint64Cls } from './primitives' import { BytesCls } from './primitives' export const matchImpl: typeof match = (subject, test): boolean => { + if (Object.hasOwn(test, 'not')) { + return !matchImpl(subject, (test as DeliberateAny).not) + } const bigIntSubjectValue = getBigIntValue(subject) if (bigIntSubjectValue !== undefined) { const bigIntTestValue = getBigIntValue(test) @@ -31,9 +34,9 @@ export const matchImpl: typeof match = (subject, test): boolean => { } else if (subject instanceof BytesBackedCls) { return subject.bytes.equals((test as unknown as BytesBackedCls).bytes) } else if (subject instanceof Uint64BackedCls) { - return ( - getBigIntValue(subject.uint64 as unknown as Uint64Cls) === - getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as Uint64Cls) + return matchImpl( + getBigIntValue(subject.uint64 as unknown as Uint64Cls), + getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as Uint64Cls), ) } else if (test instanceof ARC4Encoded) { return (subject as unknown as ARC4Encoded).bytes.equals(test.bytes) diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 840a54df..c45e0f22 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -585,7 +585,7 @@ export class ItxnDemoContract extends BaseContract { createAppParams = itxn.applicationCall({ approvalProgram: APPROVE, clearStateProgram: APPROVE, - appArgs: [Bytes('3'), '4', Bytes('5')], + appArgs: [Bytes('3'), Bytes('4'), Bytes('5')], note: 'no args param set', }) } diff --git a/tests/match.spec.ts b/tests/match.spec.ts index 901d2a82..2ced7493 100644 --- a/tests/match.spec.ts +++ b/tests/match.spec.ts @@ -44,6 +44,14 @@ describe('match', () => { expected: true, }, { subject: { a: 42 }, test: { a: { between: [BigUint(MAX_UINT64), BigUint(MAX_UINT512)] as [biguint, biguint] } }, expected: false }, + { subject: 0, test: { not: 0 }, expected: false }, + { subject: 0, test: { not: 1 }, expected: true }, + { subject: 1, test: { not: 0 }, expected: true }, + { subject: 1, test: { not: 1 }, expected: false }, + { subject: 42n, test: { not: MAX_UINT512 }, expected: true }, + { subject: MAX_UINT512, test: { not: MAX_UINT512 }, expected: false }, + { subject: { a: 42 }, test: { a: { not: 3 } }, expected: true }, + { subject: { a: 42 }, test: { a: { not: 42 } }, expected: false }, ] const account1 = ctx.any.account() @@ -64,31 +72,50 @@ describe('match', () => { const testData = [ { subject: '', test: '', expected: true }, + { subject: '', test: { not: '' }, expected: false }, { subject: 'hello', test: 'hello', expected: true }, { subject: 'hello', test: 'world', expected: false }, + { subject: 'hello', test: { not: 'world' }, expected: true }, { subject: '', test: 'world', expected: false }, + { subject: '', test: { not: 'world' }, expected: true }, { subject: Bytes(), test: Bytes(), expected: true }, + { subject: Bytes(), test: { not: Bytes() }, expected: false }, { subject: Bytes('hello'), test: Bytes('hello'), expected: true }, + { subject: Bytes('hello'), test: { not: Bytes('hello') }, expected: false }, { subject: Bytes('hello'), test: Bytes('world'), expected: false }, + { subject: Bytes('hello'), test: { not: Bytes('world') }, expected: true }, { subject: Bytes(''), test: Bytes('world'), expected: false }, { subject: account1, test: account1, expected: true }, { subject: account1, test: sameAccount, expected: true }, + { subject: account1, test: { not: sameAccount }, expected: false }, { subject: account1, test: differentAccount, expected: false }, + { subject: account1, test: { not: differentAccount }, expected: true }, { subject: app1, test: app1, expected: true }, { subject: app1, test: sameApp, expected: true }, + { subject: app1, test: { not: sameApp }, expected: false }, { subject: app1, test: differentApp, expected: false }, + { subject: app1, test: { not: differentApp }, expected: true }, { subject: asset1, test: asset1, expected: true }, { subject: asset1, test: sameAsset, expected: true }, + { subject: asset1, test: { not: sameAsset }, expected: false }, { subject: asset1, test: differentAsset, expected: false }, + { subject: asset1, test: { not: differentAsset }, expected: true }, { subject: arc4Str1, test: arc4Str1, expected: true }, { subject: arc4Str1, test: sameArc4Str, expected: true }, { subject: arc4Str1, test: differentArc4Str, expected: false }, { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { a: 'hello', b: { lessThanEq: 42 }, c: sameArc4Str }, expected: true }, + { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { not: { a: 'hello', b: { lessThanEq: 42 }, c: sameArc4Str } }, expected: false }, { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: sameArc4Str }, expected: true }, { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: differentArc4Str }, expected: false }, + { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { not: { c: differentArc4Str } }, expected: true }, { subject: ['hello', 42, arc4Str1], test: ['hello', { lessThanEq: 42 }, sameArc4Str], expected: true }, { subject: ['hello', 42, arc4Str1], test: ['hello'], expected: true }, + { subject: ['hello', 42, arc4Str1], test: { not: ['hello'] }, expected: false }, { subject: ['hello', 42, arc4Str1], test: ['world'], expected: false }, + { subject: ['hello', 42, arc4Str1], test: { not: ['world'] }, expected: true }, + { subject: { x: 43 }, test: { not: { x: 3 } }, expected: true }, + { subject: { x: 43 }, test: { x: { not: 3 } }, expected: true }, + { subject: { x: 43 }, test: { not: { x: { not: 3 } } }, expected: false }, ] test.each(numericTestData)('should be able to match numeric data %s', (data) => {