Skip to content

Commit ddb009d

Browse files
authored
fix: mock internal functions without parameters (#33)
1 parent 431a158 commit ddb009d

File tree

4 files changed

+40
-29
lines changed

4 files changed

+40
-29
lines changed

solidity/contracts/utils/ContractB.sol

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,4 @@ contract ContractB is IContractB {
99
stringVariable = _stringVariable;
1010
_result = true;
1111
}
12-
13-
function _internalNoReturn() internal {
14-
stringVariable = 'internalNoReturn';
15-
}
1612
}

solidity/contracts/utils/ContractD.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,12 @@ contract ContractD {
1515
function _getVariables(uint256 _uintVariable) internal view virtual returns (bool, uint256, string memory) {
1616
return (true, 111, 'test');
1717
}
18+
19+
function _internalNoInputNoOutput() internal virtual {
20+
_internalUintVar = 11;
21+
}
22+
23+
function _internalViewNoInputNoOutput() internal view virtual {
24+
uint256 __internalUintVar = _internalUintVar;
25+
}
1826
}

src/templates/mockInternalFunctionTemplate.hbs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
{{#if isView}}
2+
{{#if outputs}}
23
struct {{functionName}}Output {
34
{{#each outputTypes}}
45
{{this}} {{lookup ../outputNames @index}};
56
{{/each}}
67
}
78

89
mapping(bytes32 => {{functionName}}Output) private {{functionName}}Outputs;
10+
{{/if}}
911
bytes32[] private {{functionName}}InputHashes;
1012
{{/if}}
1113

1214
function mock_call_{{functionName}}({{parameters}}) public {
1315
{{#if isView}}
1416
bytes32 _key = keccak256(abi.encode({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}));
17+
{{#if outputs}}
1518
{{functionName}}Outputs[_key] = {{functionName}}Output({{#each outputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}});
19+
{{/if}}
1620
for (uint256 _i; _i < {{functionName}}InputHashes.length; ++_i) {
1721
if (_key == {{functionName}}InputHashes[_i]) {
1822
return;
@@ -22,7 +26,7 @@ function mock_call_{{functionName}}({{parameters}}) public {
2226
{{else}}
2327
vm.mockCall(
2428
address(this),
25-
abi.encodeWithSignature("{{signature}}", {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}),
29+
abi.encodeWithSignature("{{signature}}"{{#if inputs}}, {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}}),
2630
abi.encode({{#each outputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}})
2731
);
2832
{{/if}}
@@ -33,14 +37,17 @@ function {{functionName}}({{inputs}}) internal {{#if isView}}view {{/if}}overrid
3337
bytes32 _key = keccak256(abi.encode({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}));
3438
for (uint256 _i; _i < {{functionName}}InputHashes.length; ++_i) {
3539
if (_key == {{functionName}}InputHashes[_i]) {
40+
{{#if outputs}}
3641
{{functionName}}Output memory _output = {{functionName}}Outputs[_key];
42+
{{/if}}
3743
return ({{#each outputNames}}_output.{{this}}{{#unless @last}}, {{/unless}}{{/each}});
3844
}
3945
}
4046
return super.{{functionName}}({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}});
4147
{{else}}
42-
(bool _success, bytes memory _data) = address(this).call(abi.encodeWithSignature("{{signature}}", {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}));
43-
({{#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}});
48+
(bool _success, bytes memory _data) = address(this).call(abi.encodeWithSignature("{{signature}}"{{#if inputs}}, {{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}}));
49+
if (_success) return abi.decode(_data, ({{#each outputTypes}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}));
50+
else return super.{{functionName}}({{#each inputNames}}{{this}}{{#unless @last}}, {{/unless}}{{/each}});
4451
{{/if}}
4552
}
4653
{{nl}}

test/e2e/get-internal-functions.spec.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,18 @@ describe('E2E: getInternalMockFunctions', () => {
9797
expect(param1).to.not.be.undefined;
9898
expect(param1?.typeDescriptions.typeString).to.equal('uint256');
9999

100-
const return0 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0');
101-
expect(return0).to.not.be.undefined;
102-
expect(return0?.typeDescriptions.typeString).to.equal('bool');
103-
104-
const return1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1');
105-
expect(return1).to.not.be.undefined;
106-
expect(return1?.typeDescriptions.typeString).to.equal('uint256');
107-
108-
const return2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2');
109-
expect(return2).to.not.be.undefined;
110-
expect(return2?.typeDescriptions.typeString).to.equal('string');
111-
expect(return2?.storageLocation).to.equal('memory');
100+
const returnParam1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0');
101+
expect(returnParam1).to.not.be.undefined;
102+
expect(returnParam1?.typeDescriptions.typeString).to.equal('bool');
103+
104+
const returnParam2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1');
105+
expect(returnParam2).to.not.be.undefined;
106+
expect(returnParam2?.typeDescriptions.typeString).to.equal('uint256');
107+
108+
const returnParam3 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2');
109+
expect(returnParam3).to.not.be.undefined;
110+
expect(returnParam3?.typeDescriptions.typeString).to.equal('string');
111+
expect(returnParam3?.storageLocation).to.equal('memory');
112112
});
113113

114114
it('MockContractD must include internal view function mock call', async () => {
@@ -150,17 +150,17 @@ describe('E2E: getInternalMockFunctions', () => {
150150
expect(param1).to.not.be.undefined;
151151
expect(param1?.typeDescriptions.typeString).to.equal('uint256');
152152

153-
const return0 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0');
154-
expect(return0).to.not.be.undefined;
155-
expect(return0?.typeDescriptions.typeString).to.equal('bool');
153+
const returnParam1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam0');
154+
expect(returnParam1).to.not.be.undefined;
155+
expect(returnParam1?.typeDescriptions.typeString).to.equal('bool');
156156

157-
const return1 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1');
158-
expect(return1).to.not.be.undefined;
159-
expect(return1?.typeDescriptions.typeString).to.equal('uint256');
157+
const returnParam2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam1');
158+
expect(returnParam2).to.not.be.undefined;
159+
expect(returnParam2?.typeDescriptions.typeString).to.equal('uint256');
160160

161-
const return2 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2');
162-
expect(return2).to.not.be.undefined;
163-
expect(return2?.typeDescriptions.typeString).to.equal('string');
164-
expect(return2?.storageLocation).to.equal('memory');
161+
const returnParam3 = func.returnParameters.parameters.find((param) => param.name === '_returnParam2');
162+
expect(returnParam3).to.not.be.undefined;
163+
expect(returnParam3?.typeDescriptions.typeString).to.equal('string');
164+
expect(returnParam3?.storageLocation).to.equal('memory');
165165
});
166166
});

0 commit comments

Comments
 (0)