diff --git a/solidity/contracts/utils/ContractB.sol b/solidity/contracts/utils/ContractB.sol index f7c2da4..6d70bc0 100644 --- a/solidity/contracts/utils/ContractB.sol +++ b/solidity/contracts/utils/ContractB.sol @@ -9,8 +9,4 @@ contract ContractB is IContractB { stringVariable = _stringVariable; _result = true; } - - function _internalNoReturn() internal { - stringVariable = 'internalNoReturn'; - } } diff --git a/solidity/contracts/utils/ContractD.sol b/solidity/contracts/utils/ContractD.sol index 95400df..9a16a7d 100644 --- a/solidity/contracts/utils/ContractD.sol +++ b/solidity/contracts/utils/ContractD.sol @@ -15,4 +15,12 @@ contract ContractD { function _getVariables(uint256 _uintVariable) internal view virtual returns (bool, uint256, string memory) { return (true, 111, 'test'); } + + function _internalNoInputNoOutput() internal virtual { + _internalUintVar = 11; + } + + function _internalViewNoInputNoOutput() internal view virtual { + uint256 __internalUintVar = _internalUintVar; + } } diff --git a/src/templates/mockInternalFunctionTemplate.hbs b/src/templates/mockInternalFunctionTemplate.hbs index 1df5dc5..a26c3fc 100644 --- a/src/templates/mockInternalFunctionTemplate.hbs +++ b/src/templates/mockInternalFunctionTemplate.hbs @@ -1,4 +1,5 @@ {{#if isView}} +{{#if outputs}} struct {{functionName}}Output { {{#each outputTypes}} {{this}} {{lookup ../outputNames @index}}; @@ -6,13 +7,16 @@ struct {{functionName}}Output { } mapping(bytes32 => {{functionName}}Output) private {{functionName}}Outputs; +{{/if}} bytes32[] private {{functionName}}InputHashes; {{/if}} function mock_call_{{functionName}}({{parameters}}) public { {{#if isView}} bytes32 _key = keccak256(abi.encode({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})); + {{#if outputs}} {{functionName}}Outputs[_key] = {{functionName}}Output({{#each outputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}); + {{/if}} for (uint256 _i; _i < {{functionName}}InputHashes.length; ++_i) { if (_key == {{functionName}}InputHashes[_i]) { return; @@ -22,7 +26,7 @@ function mock_call_{{functionName}}({{parameters}}) public { {{else}} vm.mockCall( address(this), - abi.encodeWithSignature("{{signature}}", {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}), + abi.encodeWithSignature("{{signature}}"{{#if inputs}}, {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}}), abi.encode({{#each outputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}) ); {{/if}} @@ -33,14 +37,17 @@ function {{functionName}}({{inputs}}) internal {{#if isView}}view {{/if}}overrid bytes32 _key = keccak256(abi.encode({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})); for (uint256 _i; _i < {{functionName}}InputHashes.length; ++_i) { if (_key == {{functionName}}InputHashes[_i]) { + {{#if outputs}} {{functionName}}Output memory _output = {{functionName}}Outputs[_key]; + {{/if}} return ({{#each outputNames}}_output.{{this}}{{#unless @last}}, {{/unless}}{{/each}}); } } return super.{{functionName}}({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}); {{else}} - (bool _success, bytes memory _data) = address(this).call(abi.encodeWithSignature("{{signature}}", {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})); - ({{#each outputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}) = _success ? abi.decode(_data, ({{#each outputTypes}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})) : super.{{functionName}}({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}); + (bool _success, bytes memory _data) = address(this).call(abi.encodeWithSignature("{{signature}}"{{#if inputs}}, {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}})); + if (_success) return abi.decode(_data, ({{#each outputTypes}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})); + else return super.{{functionName}}({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}); {{/if}} } {{nl}} diff --git a/test/e2e/get-internal-functions.spec.ts b/test/e2e/get-internal-functions.spec.ts index d3b753c..5e26541 100644 --- a/test/e2e/get-internal-functions.spec.ts +++ b/test/e2e/get-internal-functions.spec.ts @@ -97,18 +97,18 @@ describe('E2E: getInternalMockFunctions', () => { expect(param1).to.not.be.undefined; expect(param1?.typeDescriptions.typeString).to.equal('uint256'); - const return0 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0'); - expect(return0).to.not.be.undefined; - expect(return0?.typeDescriptions.typeString).to.equal('bool'); - - const return1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1'); - expect(return1).to.not.be.undefined; - expect(return1?.typeDescriptions.typeString).to.equal('uint256'); - - const return2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2'); - expect(return2).to.not.be.undefined; - expect(return2?.typeDescriptions.typeString).to.equal('string'); - expect(return2?.storageLocation).to.equal('memory'); + const returnParam1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0'); + expect(returnParam1).to.not.be.undefined; + expect(returnParam1?.typeDescriptions.typeString).to.equal('bool'); + + const returnParam2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1'); + expect(returnParam2).to.not.be.undefined; + expect(returnParam2?.typeDescriptions.typeString).to.equal('uint256'); + + const returnParam3 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2'); + expect(returnParam3).to.not.be.undefined; + expect(returnParam3?.typeDescriptions.typeString).to.equal('string'); + expect(returnParam3?.storageLocation).to.equal('memory'); }); it('MockContractD must include internal view function mock call', async () => { @@ -150,17 +150,17 @@ describe('E2E: getInternalMockFunctions', () => { expect(param1).to.not.be.undefined; expect(param1?.typeDescriptions.typeString).to.equal('uint256'); - const return0 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0'); - expect(return0).to.not.be.undefined; - expect(return0?.typeDescriptions.typeString).to.equal('bool'); + const returnParam1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0'); + expect(returnParam1).to.not.be.undefined; + expect(returnParam1?.typeDescriptions.typeString).to.equal('bool'); - const return1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1'); - expect(return1).to.not.be.undefined; - expect(return1?.typeDescriptions.typeString).to.equal('uint256'); + const returnParam2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1'); + expect(returnParam2).to.not.be.undefined; + expect(returnParam2?.typeDescriptions.typeString).to.equal('uint256'); - const return2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2'); - expect(return2).to.not.be.undefined; - expect(return2?.typeDescriptions.typeString).to.equal('string'); - expect(return2?.storageLocation).to.equal('memory'); + const returnParam3 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2'); + expect(returnParam3).to.not.be.undefined; + expect(returnParam3?.typeDescriptions.typeString).to.equal('string'); + expect(returnParam3?.storageLocation).to.equal('memory'); }); });