Skip to content

Commit 495b669

Browse files
authored
Merge pull request #73 from algorandfoundation/feat/not
feat: support not expressions on match and assertMatch
2 parents d0e38f4 + 93c826b commit 495b669

File tree

5 files changed

+45
-15
lines changed

5 files changed

+45
-15
lines changed

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
"vitest": "3.0.9"
6767
},
6868
"dependencies": {
69-
"@algorandfoundation/algorand-typescript": "1.0.0-alpha.49",
70-
"@algorandfoundation/puya-ts": "1.0.0-alpha.49",
69+
"@algorandfoundation/algorand-typescript": "1.0.0-alpha.51",
70+
"@algorandfoundation/puya-ts": "1.0.0-alpha.51",
7171
"elliptic": "^6.6.1",
7272
"js-sha256": "^0.11.0",
7373
"js-sha3": "^0.9.3",

src/impl/match.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import type { StubBytesCompat, Uint64Cls } from './primitives'
77
import { BytesCls } from './primitives'
88

99
export const matchImpl: typeof match = (subject, test): boolean => {
10+
if (Object.hasOwn(test, 'not')) {
11+
return !matchImpl(subject, (test as DeliberateAny).not)
12+
}
1013
const bigIntSubjectValue = getBigIntValue(subject)
1114
if (bigIntSubjectValue !== undefined) {
1215
const bigIntTestValue = getBigIntValue(test)
@@ -31,9 +34,9 @@ export const matchImpl: typeof match = (subject, test): boolean => {
3134
} else if (subject instanceof BytesBackedCls) {
3235
return subject.bytes.equals((test as unknown as BytesBackedCls).bytes)
3336
} else if (subject instanceof Uint64BackedCls) {
34-
return (
35-
getBigIntValue(subject.uint64 as unknown as Uint64Cls) ===
36-
getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as Uint64Cls)
37+
return matchImpl(
38+
getBigIntValue(subject.uint64 as unknown as Uint64Cls),
39+
getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as Uint64Cls),
3740
)
3841
} else if (test instanceof ARC4Encoded) {
3942
return (subject as unknown as ARC4Encoded).bytes.equals(test.bytes)

tests/artifacts/state-ops/contract.algo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ export class ItxnDemoContract extends BaseContract {
585585
createAppParams = itxn.applicationCall({
586586
approvalProgram: APPROVE,
587587
clearStateProgram: APPROVE,
588-
appArgs: [Bytes('3'), '4', Bytes('5')],
588+
appArgs: [Bytes('3'), Bytes('4'), Bytes('5')],
589589
note: 'no args param set',
590590
})
591591
}

tests/match.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ describe('match', () => {
4444
expected: true,
4545
},
4646
{ subject: { a: 42 }, test: { a: { between: [BigUint(MAX_UINT64), BigUint(MAX_UINT512)] as [biguint, biguint] } }, expected: false },
47+
{ subject: 0, test: { not: 0 }, expected: false },
48+
{ subject: 0, test: { not: 1 }, expected: true },
49+
{ subject: 1, test: { not: 0 }, expected: true },
50+
{ subject: 1, test: { not: 1 }, expected: false },
51+
{ subject: 42n, test: { not: MAX_UINT512 }, expected: true },
52+
{ subject: MAX_UINT512, test: { not: MAX_UINT512 }, expected: false },
53+
{ subject: { a: 42 }, test: { a: { not: 3 } }, expected: true },
54+
{ subject: { a: 42 }, test: { a: { not: 42 } }, expected: false },
4755
]
4856

4957
const account1 = ctx.any.account()
@@ -64,31 +72,50 @@ describe('match', () => {
6472

6573
const testData = [
6674
{ subject: '', test: '', expected: true },
75+
{ subject: '', test: { not: '' }, expected: false },
6776
{ subject: 'hello', test: 'hello', expected: true },
6877
{ subject: 'hello', test: 'world', expected: false },
78+
{ subject: 'hello', test: { not: 'world' }, expected: true },
6979
{ subject: '', test: 'world', expected: false },
80+
{ subject: '', test: { not: 'world' }, expected: true },
7081
{ subject: Bytes(), test: Bytes(), expected: true },
82+
{ subject: Bytes(), test: { not: Bytes() }, expected: false },
7183
{ subject: Bytes('hello'), test: Bytes('hello'), expected: true },
84+
{ subject: Bytes('hello'), test: { not: Bytes('hello') }, expected: false },
7285
{ subject: Bytes('hello'), test: Bytes('world'), expected: false },
86+
{ subject: Bytes('hello'), test: { not: Bytes('world') }, expected: true },
7387
{ subject: Bytes(''), test: Bytes('world'), expected: false },
7488
{ subject: account1, test: account1, expected: true },
7589
{ subject: account1, test: sameAccount, expected: true },
90+
{ subject: account1, test: { not: sameAccount }, expected: false },
7691
{ subject: account1, test: differentAccount, expected: false },
92+
{ subject: account1, test: { not: differentAccount }, expected: true },
7793
{ subject: app1, test: app1, expected: true },
7894
{ subject: app1, test: sameApp, expected: true },
95+
{ subject: app1, test: { not: sameApp }, expected: false },
7996
{ subject: app1, test: differentApp, expected: false },
97+
{ subject: app1, test: { not: differentApp }, expected: true },
8098
{ subject: asset1, test: asset1, expected: true },
8199
{ subject: asset1, test: sameAsset, expected: true },
100+
{ subject: asset1, test: { not: sameAsset }, expected: false },
82101
{ subject: asset1, test: differentAsset, expected: false },
102+
{ subject: asset1, test: { not: differentAsset }, expected: true },
83103
{ subject: arc4Str1, test: arc4Str1, expected: true },
84104
{ subject: arc4Str1, test: sameArc4Str, expected: true },
85105
{ subject: arc4Str1, test: differentArc4Str, expected: false },
86106
{ subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { a: 'hello', b: { lessThanEq: 42 }, c: sameArc4Str }, expected: true },
107+
{ subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { not: { a: 'hello', b: { lessThanEq: 42 }, c: sameArc4Str } }, expected: false },
87108
{ subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: sameArc4Str }, expected: true },
88109
{ subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: differentArc4Str }, expected: false },
110+
{ subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { not: { c: differentArc4Str } }, expected: true },
89111
{ subject: ['hello', 42, arc4Str1], test: ['hello', { lessThanEq: 42 }, sameArc4Str], expected: true },
90112
{ subject: ['hello', 42, arc4Str1], test: ['hello'], expected: true },
113+
{ subject: ['hello', 42, arc4Str1], test: { not: ['hello'] }, expected: false },
91114
{ subject: ['hello', 42, arc4Str1], test: ['world'], expected: false },
115+
{ subject: ['hello', 42, arc4Str1], test: { not: ['world'] }, expected: true },
116+
{ subject: { x: 43 }, test: { not: { x: 3 } }, expected: true },
117+
{ subject: { x: 43 }, test: { x: { not: 3 } }, expected: true },
118+
{ subject: { x: 43 }, test: { not: { x: { not: 3 } } }, expected: false },
92119
]
93120

94121
test.each(numericTestData)('should be able to match numeric data %s', (data) => {

0 commit comments

Comments
 (0)