( struct: ProcessedStruct, fn: CodeGenFunction, libraryName: string )
| 115 | ]); |
| 116 | |
| 117 | export function generateFoundryTestForFunction( |
| 118 | struct: ProcessedStruct, |
| 119 | fn: CodeGenFunction, |
| 120 | libraryName: string |
| 121 | ) { |
| 122 | const contractName = `external${libraryName}`; |
| 123 | const testCode: ArrayJoinInput<string>[] = []; |
| 124 | const generateCall = (args: string[]) => _generateCall(contractName, fn, args) |
| 125 | const getOverflowTest = (args: string[], field: ProcessedField) => _getOverflowTest(contractName, fn, args, field) |
| 126 | const getUnderflowTest = (args: string[], field: ProcessedField) => _getUnderflowTest(contractName, fn, args, field) |
| 127 | |
| 128 | const fields = fn.internalType === 'getter' ? fn.outputFields : fn.inputFields; |
| 129 | const {minValues, maxValues} = getMinMaxValues(fields) |
| 130 | |
| 131 | const minMax = minValues.map((f, i) => i % 2 ? minValues[i] : maxValues[i]); |
| 132 | const maxMin = minValues.map((f, i) => i % 2 ? maxValues[i] : minValues[i]); |
| 133 | if (fn.internalType === 'setter') { |
| 134 | for (let i = 0; i < fields.length; i++) { |
| 135 | const inputs = [...minValues]; |
| 136 | const field = fields[i]; |
| 137 | if (shouldCheckForOverflow(field)) { |
| 138 | inputs[i] = getFieldValue(field, 'overflow'); |
| 139 | testCode.push(getOverflowTest(inputs, field), '') |
| 140 | if (field.type.meta === 'elementary' && field.type.type === 'int') { |
| 141 | inputs[i] = getFieldValue(field, 'underflow'); |
| 142 | testCode.push(getUnderflowTest(inputs, field), '') |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | const getGetter = _env.findGetterOrSetterForFields(struct, fields, fn, contractName, 'getter'); |
| 147 | if (!getGetter) { |
| 148 | console.log(`Could not find a way to get all fields updated by ${fn.name}`) |
| 149 | return undefined; |
| 150 | } |
| 151 | const getterCode = getGetter(); |
| 152 | const testSetMinMax = getSetterTest( |
| 153 | `Should be able to set ${fields.length === 1 ? 'min value' : 'min/max values'}`, |
| 154 | fields, |
| 155 | [generateCall(minMax)], |
| 156 | getterCode, |
| 157 | minMax |
| 158 | ) |
| 159 | testCode.push(testSetMinMax, '') |
| 160 | const testSetMaxMin = getSetterTest( |
| 161 | `Should be able to set ${fields.length === 1 ? 'max value' : 'max/min values'}`, |
| 162 | fields, |
| 163 | [generateCall(maxMin)], |
| 164 | getterCode, |
| 165 | maxMin |
| 166 | ) |
| 167 | testCode.push(testSetMaxMin, '') |
| 168 | } else { |
| 169 | const destructuredDecodeParams = fn.outputFields.length > 1 |
| 170 | ? `{ ${fn.outputFields.map(f => f.name).join(", ")} }` |
| 171 | : `${fn.outputFields[0].name}` |
| 172 | const getterCode = [`const ${destructuredDecodeParams} = await ${contractName}.${fn.name}()`] |
| 173 | |
| 174 | const getSetter = _env.findGetterOrSetterForFields(struct, fields, fn, contractName, 'setter'); |
no test coverage detected