Skip to content

Increase code coverage for older compiler versions #419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 9, 2019
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
4 changes: 4 additions & 0 deletions linker.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
var assert = require('assert');
var keccak256 = require('js-sha3').keccak256;

function libraryHashPlaceholder (input) {
return '$' + keccak256(input).slice(0, 34) + '$';
}

var linkBytecode = function (bytecode, libraries) {
assert(typeof bytecode === 'string');
assert(typeof libraries === 'object');
// NOTE: for backwards compatibility support old compiler which didn't use file names
var librariesComplete = {};
for (var libraryName in libraries) {
Expand Down Expand Up @@ -52,6 +55,7 @@ var linkBytecode = function (bytecode, libraries) {
};

var findLinkReferences = function (bytecode) {
assert(typeof bytecode === 'string');
// find 40 bytes in the pattern of __...<36 digits>...__
// e.g. __Lib.sol:L_____________________________
var linkReferences = {};
Expand Down
105 changes: 102 additions & 3 deletions test/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ function runTests (solc, versionText) {
error = output.errors[error];
if (error.type === errorType) {
if (message) {
return error.message.match(message) !== null;
if (error.message.match(message) !== null) {
return true;
}
} else {
return true;
}
return true;
}
}
}
Expand Down Expand Up @@ -421,7 +424,40 @@ function runTests (solc, versionText) {
st.end();
});

t.test('compiling standard JSON', function (st) {
t.test('compiling standard JSON (single file)', function (st) {
var input = {
'language': 'Solidity',
'settings': {
'outputSelection': {
'*': {
'*': [ 'evm.bytecode', 'evm.gasEstimates' ]
}
}
},
'sources': {
'c.sol': {
'content': 'contract C { function g() public { } function h() internal {} }'
}
}
};

var output = JSON.parse(solc.compile(JSON.stringify(input)));
st.ok(expectNoError(output));
var C = getBytecodeStandard(output, 'c.sol', 'C');
st.ok(typeof C === 'string');
st.ok(C.length > 0);
var CGas = getGasEstimate(output, 'c.sol', 'C');
st.ok(typeof CGas === 'object');
st.ok(typeof CGas['creation'] === 'object');
st.ok(typeof CGas['creation']['codeDepositCost'] === 'string');
st.ok(typeof CGas['external'] === 'object');
st.ok(typeof CGas['external']['g()'] === 'string');
st.ok(typeof CGas['internal'] === 'object');
st.ok(typeof CGas['internal']['h()'] === 'string');
st.end();
});

t.test('compiling standard JSON (multiple files)', function (st) {
// <0.1.6 doesn't have this
if (!solc.features.multipleInputs) {
st.skip('Not supported by solc');
Expand Down Expand Up @@ -468,6 +504,40 @@ function runTests (solc, versionText) {
st.end();
});

t.test('compiling standard JSON (abstract contract)', function (st) {
// <0.1.6 doesn't have this
if (!solc.features.multipleInputs) {
st.skip('Not supported by solc');
st.end();
return;
}

var isVersion6 = semver.gt(solc.semver(), '0.5.99');

var input = {
'language': 'Solidity',
'settings': {
'outputSelection': {
'*': {
'*': [ 'evm.bytecode', 'evm.gasEstimates' ]
}
}
},
'sources': {
'c.sol': {
'content': (isVersion6 ? 'abstract ' : '') + 'contract C { function f() public; }'
}
}
};

var output = JSON.parse(solc.compile(JSON.stringify(input)));
st.ok(expectNoError(output));
var C = getBytecodeStandard(output, 'c.sol', 'C');
st.ok(typeof C === 'string');
st.ok(C.length === 0);
st.end();
});

t.test('compiling standard JSON (with imports)', function (st) {
// <0.2.1 doesn't have this
if (!solc.features.importCallback) {
Expand Down Expand Up @@ -606,6 +676,35 @@ function runTests (solc, versionText) {
st.end();
});

t.test('compiling standard JSON (with warning >=0.4.0)', function (st) {
// In 0.4.0 "pragma solidity" was added. Not including it is a warning.
if (semver.lt(solc.semver(), '0.4.0')) {
st.skip('Not supported by solc');
st.end();
return;
}

var input = {
'language': 'Solidity',
'settings': {
'outputSelection': {
'*': {
'*': [ 'evm.bytecode' ]
}
}
},
'sources': {
'c.sol': {
'content': 'contract C { function f() public { } }'
}
}
};

var output = JSON.parse(solc.compile(JSON.stringify(input)));
st.ok(expectError(output, 'Warning', 'Source file does not specify required compiler version!'));
st.end();
});

t.test('compiling standard JSON (using libraries) (using lowlevel API)', function (st) {
// 0.4.0 has a bug with libraries
if (semver.eq(solc.semver(), '0.4.0')) {
Expand Down
8 changes: 4 additions & 4 deletions translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ function translateJsonCompilerOutput (output, libraries) {
'evm': {
'legacyAssembly': contractInput['assembly'],
'bytecode': {
'object': linker.linkBytecode(contractInput['bytecode'], libraries),
'object': contractInput['bytecode'] && linker.linkBytecode(contractInput['bytecode'], libraries || {}),
'opcodes': contractInput['opcodes'],
'sourceMap': contractInput['srcmap'],
'linkReferences': linker.findLinkReferences(contractInput['bytecode'])
'linkReferences': contractInput['bytecode'] && linker.findLinkReferences(contractInput['bytecode'])
},
'deployedBytecode': {
'object': linker.linkBytecode(contractInput['runtimeBytecode'], libraries),
'object': contractInput['runtimeBytecode'] && linker.linkBytecode(contractInput['runtimeBytecode'], libraries || {}),
'sourceMap': contractInput['srcmapRuntime'],
'linkReferences': linker.findLinkReferences(contractInput['runtimeBytecode'])
'linkReferences': contractInput['runtimeBytecode'] && linker.findLinkReferences(contractInput['runtimeBytecode'])
},
'methodIdentifiers': contractInput['functionHashes'],
'gasEstimates': translatedGasEstimates
Expand Down