Skip to content

Commit 0dbb2fe

Browse files
authored
refactor(aci): rework Sophia Option type representation (#691)
Change Option type Representation from Promise to Value(Some) and undefined(None) BREAKING CHANGE: Change Sophia option type representation in ACI 689
1 parent 0d43804 commit 0dbb2fe

File tree

2 files changed

+34
-37
lines changed

2 files changed

+34
-37
lines changed

es/contract/aci/transformation.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,20 @@ export function readType (type, { bindings } = {}) {
9494
* @param bindings
9595
* @return {string}
9696
*/
97-
export async function transform (type, value, { bindings } = {}) {
97+
export function transform (type, value, { bindings } = {}) {
9898
const { t, generic } = readType(type, { bindings })
9999

100100
switch (t) {
101101
case SOPHIA_TYPES.string:
102102
return `"${value}"`
103103
case SOPHIA_TYPES.list:
104-
return `[${await Promise.all(value.map(async el => transform(generic, el, { bindings })))}]`
104+
return `[${value.map(el => transform(generic, el, { bindings }))}]`
105105
case SOPHIA_TYPES.tuple:
106-
return `(${await Promise.all(value.map(async (el, i) => transform(generic[i], el, {
106+
return `(${value.map((el, i) => transform(generic[i], el, {
107107
bindings
108-
})))})`
108+
}))})`
109109
case SOPHIA_TYPES.option: {
110-
const optionV = await value.catch(e => undefined)
111-
return optionV === undefined ? 'None' : `Some(${await transform(generic, optionV, {
110+
return value === undefined ? 'None' : `Some(${transform(generic, value, {
112111
bindings
113112
})})`
114113
}
@@ -117,10 +116,9 @@ export async function transform (type, value, { bindings } = {}) {
117116
case SOPHIA_TYPES.signature:
118117
return `#${typeof value === 'string' ? value : Buffer.from(value).toString('hex')}`
119118
case SOPHIA_TYPES.record:
120-
return `{${await generic.reduce(
121-
async (acc, { name, type }, i) => {
122-
acc = await acc
123-
acc += `${i !== 0 ? ',' : ''}${name} = ${await transform(type, value[name], {
119+
return `{${generic.reduce(
120+
(acc, { name, type }, i) => {
121+
acc += `${i !== 0 ? ',' : ''}${name} = ${transform(type, value[name], {
124122
bindings
125123
})}`
126124
return acc
@@ -136,33 +134,32 @@ export async function transform (type, value, { bindings } = {}) {
136134
return `${value}`
137135
}
138136

139-
async function transformVariant (value, generic, { bindings }) {
137+
function transformVariant (value, generic, { bindings }) {
140138
const [[variant, variantArgs]] = typeof value === 'string' ? [[value, []]] : Object.entries(value)
141139
const [[v, type]] = Object.entries(generic.find(o => Object.keys(o)[0].toLowerCase() === variant.toLowerCase()))
142140
return `${v}${!type.length
143141
? ''
144-
: `(${await Promise.all(variantArgs.slice(0, type.length).map(async (el, i) => transform(type[i], el, {
142+
: `(${variantArgs.slice(0, type.length).map((el, i) => transform(type[i], el, {
145143
bindings
146-
})))})`
144+
}))})`
147145
}`
148146
}
149147

150-
export async function transformMap (value, generic, { bindings }) {
148+
export function transformMap (value, generic, { bindings }) {
151149
if (value instanceof Map) {
152150
value = Array.from(value.entries())
153151
}
154152
if (!Array.isArray(value) && value instanceof Object) {
155153
value = Object.entries(value)
156154
}
157155

158-
return `{${await value
156+
return `{${value
159157
.reduce(
160-
async (acc, [key, value], i) => {
161-
acc = await acc
158+
(acc, [key, value], i) => {
162159
if (i !== 0) acc += ','
163-
acc += `[${await transform(generic[0], key, {
160+
acc += `[${transform(generic[0], key, {
164161
bindings
165-
})}] = ${await transform(generic[1], value, { bindings })}`
162+
})}] = ${transform(generic[1], value, { bindings })}`
166163
return acc
167164
},
168165
''
@@ -285,7 +282,7 @@ export function prepareSchema (type, { bindings } = {}) {
285282
case SOPHIA_TYPES.signature:
286283
return JoiBinary.binary().bufferCheck(64).error(getJoiErrorMsg)
287284
case SOPHIA_TYPES.option:
288-
return Joi.object().type(Promise).error(getJoiErrorMsg)
285+
return prepareSchema(generic, { bindings }).optional().error(getJoiErrorMsg)
289286
// @Todo Need to transform Map to Array of arrays before validating it
290287
// case SOPHIA_TYPES.map:
291288
// return Joi.array().items(Joi.array().ordered(generic.map(type => prepareSchema(type))))
@@ -373,7 +370,7 @@ export function validateArguments (aci, params) {
373370
const validationSchema = Joi.array().ordered(
374371
aci.arguments
375372
.map(({ type }, i) => prepareSchema(type, { bindings: aci.bindings }).label(`[${params[i]}]`))
376-
).label('Argument')
373+
).sparse(true).label('Argument')
377374
const { error } = Joi.validate(params, validationSchema, { abortEarly: false })
378375
if (error) {
379376
throw error

test/integration/contract.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -226,22 +226,22 @@ describe('Contract', function () {
226226
isCompiled.should.be.equal(true)
227227
})
228228
it('Dry-run deploy fn', async () => {
229-
const res = await contractObject.methods.init.get('123', 1, Promise.resolve('hahahaha'))
229+
const res = await contractObject.methods.init.get('123', 1, 'hahahaha')
230230
res.result.should.have.property('gasUsed')
231231
res.result.should.have.property('returnType')
232232
})
233233
it('Dry-run deploy fn on specific account', async () => {
234234
const current = await contract.address()
235235
const onAccount = contract.addresses().find(acc => acc !== current)
236-
const { result } = await contractObject.methods.init.get('123', 1, Promise.resolve('hahahaha'), { onAccount })
236+
const { result } = await contractObject.methods.init.get('123', 1, 'hahahaha', { onAccount })
237237
result.should.have.property('gasUsed')
238238
result.should.have.property('returnType')
239239
result.callerId.should.be.equal(onAccount)
240240
})
241241

242242
it('Deploy contract before compile', async () => {
243243
contractObject.compiled = null
244-
await contractObject.methods.init('123', 1, Promise.resolve('hahahaha'))
244+
await contractObject.methods.init('123', 1, 'hahahaha')
245245
const isCompiled = contractObject.compiled.length && contractObject.compiled.slice(0, 3) === 'cb_'
246246
isCompiled.should.be.equal(true)
247247
})
@@ -383,22 +383,22 @@ describe('Contract', function () {
383383
})
384384
it('Map With Option Value', async () => {
385385
const address = await contract.address()
386-
let mapArgWithSomeValue = new Map(
386+
const mapArgWithSomeValue = new Map(
387387
[
388-
[address, ['someStringV', Promise.resolve(123)]]
388+
[address, ['someStringV', 123]]
389389
]
390390
)
391-
let mapArgWithNoneValue = new Map(
391+
const mapArgWithNoneValue = new Map(
392392
[
393-
[address, ['someStringV', Promise.reject(Error()).catch(e => undefined)]]
393+
[address, ['someStringV', undefined]]
394394
]
395395
)
396-
let returnArgWithSomeValue = new Map(
396+
const returnArgWithSomeValue = new Map(
397397
[
398398
[address, ['someStringV', 123]]
399399
]
400400
)
401-
let returnArgWithNoneValue = new Map(
401+
const returnArgWithNoneValue = new Map(
402402
[
403403
[address, ['someStringV', undefined]]
404404
]
@@ -435,7 +435,7 @@ describe('Contract', function () {
435435
describe('RECORD/STATE', function () {
436436
const objEq = (obj, obj2) => !Object.entries(obj).find(([key, val]) => JSON.stringify(obj2[key]) !== JSON.stringify(val))
437437
it('Valid Set Record (Cast from JS object)', async () => {
438-
await contractObject.methods.setRecord({ value: 'qwe', key: 1234, testOption: Promise.resolve('test') })
438+
await contractObject.methods.setRecord({ value: 'qwe', key: 1234, testOption: 'test' })
439439
const state = await contractObject.methods.getRecord()
440440

441441
objEq(state.decodedResult, { value: 'qwe', key: 1234, testOption: 'test' }).should.be.equal(true)
@@ -445,7 +445,7 @@ describe('Contract', function () {
445445
objEq(result.decodedResult, { value: 'qwe', key: 1234, testOption: 'test' }).should.be.equal(true)
446446
})
447447
it('Get Record With Option (Convert to JS object)', async () => {
448-
await contractObject.methods.setRecord({ key: 1234, value: 'qwe', testOption: Promise.resolve('resolved string') })
448+
await contractObject.methods.setRecord({ key: 1234, value: 'qwe', testOption: 'resolved string' })
449449
const result = await contractObject.methods.getRecord()
450450
objEq(result.decodedResult, { value: 'qwe', key: 1234, testOption: 'resolved string' }).should.be.equal(true)
451451
})
@@ -459,25 +459,25 @@ describe('Contract', function () {
459459
})
460460
describe('OPTION', function () {
461461
it('Set Some Option Value(Cast from JS value/Convert result to JS)', async () => {
462-
const optionRes = await contractObject.methods.intOption(Promise.resolve(123))
462+
const optionRes = await contractObject.methods.intOption(123)
463463

464464
optionRes.decodedResult.should.be.equal(123)
465465
})
466466
it('Set Some Option List Value(Cast from JS value/Convert result to JS)', async () => {
467-
const optionRes = await contractObject.methods.listOption(Promise.resolve([[1, 'testString']]))
467+
const optionRes = await contractObject.methods.listOption([[1, 'testString']])
468468

469469
JSON.stringify(optionRes.decodedResult).should.be.equal(JSON.stringify([[1, 'testString']]))
470470
})
471471
it('Set None Option Value(Cast from JS value/Convert to JS)', async () => {
472-
const optionRes = await contractObject.methods.intOption(Promise.reject(Error()))
472+
const optionRes = await contractObject.methods.intOption(undefined)
473473
const isUndefined = optionRes.decodedResult === undefined
474474
isUndefined.should.be.equal(true)
475475
})
476476
it('Invalid option type', async () => {
477477
try {
478-
await contractObject.methods.intOption({ s: 2 })
478+
await contractObject.methods.intOption('string')
479479
} catch (e) {
480-
e.message.should.be.equal('"Argument" at position 0 fails because [Value \'[[object Object]]\' at path: [0] not a Promise]')
480+
e.message.should.be.equal('"Argument" at position 0 fails because [Value "[string]" at path: [0] not a number]')
481481
}
482482
})
483483
})

0 commit comments

Comments
 (0)