Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/impl/encoded-types/encoded-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,21 @@ export const getArc4Encoded = (value: DeliberateAny, sourceTypeInfoString?: stri
name: `Struct<${value.constructor.name}>`,
genericArgs: Object.fromEntries(Object.keys(value).map((x, i) => [x, genericArgs[i]])),
}
return new Struct(typeInfo, Object.fromEntries(Object.keys(value).map((x, i) => [x, result[i]])))
let s = Object.fromEntries(Object.keys(typeInfo.genericArgs).map((x, i) => [x, result[i]]))
if (propTypeInfos) {
// if source type info is provided, reorder the struct properties to match the expected type schema
s = Object.fromEntries(Object.keys(propTypeInfos).map((x) => [x, s[x]]))
typeInfo.genericArgs = propTypeInfos
} else {
// if not, reorder the struct properties alphabetically
typeInfo.genericArgs = Object.fromEntries(
Object.keys(typeInfo.genericArgs)
.sort()
.map((key) => [key, typeInfo.genericArgs[key]]),
)
s = Object.fromEntries(Object.keys(typeInfo.genericArgs).map((key) => [key, s[key]]))
}
return new Struct(typeInfo, s)
}

throw new CodeError(`Unsupported type for encoding: ${typeof value}`)
Expand Down
8 changes: 4 additions & 4 deletions tests/arc4/encode-decode-arc4.algo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const testData = [
new Tuple<[Uint<512>, DynamicBytes, Swapped1]>(
abiUint512,
abiBytes,
new Swapped1({ b: abiUint64, c: abiBool, d: abiString, a: new Tuple<[Uint<64>, Bool, Bool]>(abiUint64, abiBool, abiBool) }),
new Swapped1({ a: new Tuple<[Uint<64>, Bool, Bool]>(abiUint64, abiBool, abiBool), b: abiUint64, c: abiBool, d: abiString }),
),
] as readonly [Tuple<[Bool, Tuple<[Str, Bool]>]>, Tuple<[Uint<64>, Uint<64>]>, Tuple<[Uint<512>, DynamicBytes, Swapped1]>]
},
Expand Down Expand Up @@ -122,15 +122,15 @@ const testData = [
},
{
nativeValues() {
return { b: nativeNumber, c: nativeBool, d: nativeString, a: [nativeNumber, nativeBool, nativeBool] } as {
return { a: [nativeNumber, nativeBool, nativeBool], b: nativeNumber, c: nativeBool, d: nativeString } as {
b: uint64
c: boolean
d: string
a: [uint64, boolean, boolean]
}
},
abiValues() {
return { b: abiUint64, c: abiBool, d: abiString, a: new Tuple<[Uint<64>, Bool, Bool]>(abiUint64, abiBool, abiBool) }
return { a: new Tuple<[Uint<64>, Bool, Bool]>(abiUint64, abiBool, abiBool), b: abiUint64, c: abiBool, d: abiString }
},
arc4Value() {
return new Swapped1(this.abiValues())
Expand Down Expand Up @@ -167,7 +167,7 @@ describe('decodeArc4', () => {
...encodingUtil.utf8ToUint8Array('hello world'),
]),
)
const e = { a: new arc4.Uint64(50n), b: new DynamicBytes(asBytes(new Uint8Array([1, 2, 3, 4, 5]))) }
const e = { b: new DynamicBytes(asBytes(new Uint8Array([1, 2, 3, 4, 5]))), a: new arc4.Uint64(50n) }
const eBytes = asBytes(new Uint8Array([...encodingUtil.bigIntToUint8Array(50n, 8), 0, 10, 0, 5, 1, 2, 3, 4, 5]))
const f = new Address(Bytes.fromHex(`${'00'.repeat(31)}ff`))
const fBytes = Bytes.fromHex(`${'00'.repeat(31)}ff`)
Expand Down
12 changes: 11 additions & 1 deletion tests/native-mutable-object.algo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ describe('native mutable object', () => {
c: arc4.Str
d: arc4.DynamicBytes
}> {}
const obj: SimpleObj = { a: 1, b: true, c: 'hello', d: Bytes('world') }
const obj: SimpleObj = { a: 1, c: 'hello', b: true, d: Bytes('world') }
const encoded = encodeArc4(obj)
const interpreted = convertBytes<SimpleObjStruct>(encoded, { strategy: 'unsafe-cast' })
const decoded = decodeArc4<SimpleObj>(encoded)
Expand Down Expand Up @@ -789,4 +789,14 @@ describe('native mutable object', () => {
assertMatch(decoded, obj)
})
})

describe('clone', () => {
it('should work when property order is different', () => {
const obj1: NestedObj = { a: 1, b: true, c: 'hello', d: { x: 10, y: 'world', z: true } }
const obj2: NestedObj = { d: { x: 10, z: true, y: 'world' }, a: 1, c: 'hello', b: true }

expect(clone(obj2)).toEqual(obj2)
expect(clone(obj1)).toEqual(obj1)
})
})
})
4 changes: 2 additions & 2 deletions tests/references/box.algo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ describe('Box', () => {
},
},
{
value: { a: 'hello', b: Bytes('world'), c: true },
value: { a: 'hello', c: true, b: Bytes('world') },
newValue: { a: 'world', b: Bytes('hello'), c: false },
emptyValue: {},
withBoxContext: (test: (boxMap: Box<MyObject>) => void) => {
Expand All @@ -143,7 +143,7 @@ describe('Box', () => {
},
{
value: { a: 'hello', b: Bytes('world'), c: true },
newValue: { a: 'world', b: Bytes('hello'), c: false },
newValue: { a: 'world', c: false, b: Bytes('hello') },
emptyValue: {},
withBoxContext: (test: (boxMap: Box<Readonly<MyObject>>) => void) => {
ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => {
Expand Down