From 9346c49ba8a3e585524b3d75642bab32f0183c4d Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 Sep 2018 10:46:43 +0200 Subject: [PATCH] add test for libraries deployment --- src/app/tabs/run-tab.js | 4 +- test-browser/helpers/contracts.js | 46 ++++++++++-- test-browser/tests/simpleContract.js | 105 ++++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 8 deletions(-) diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index 11a092f544..377e953b68 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -403,7 +403,7 @@ function contractDropdown (events, self) { } else { if (Object.keys(selectedContract.contract.object.evm.bytecode.linkReferences).length) self._deps.logCallback(`linking ${JSON.stringify(selectedContract.contract.object.evm.bytecode.linkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`) txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.contract.object, args, constructor, contractMetadata.linkReferences, selectedContract.contract.object.evm.bytecode.linkReferences, (error, data) => { - data.contractName = selectedContract.name + if (data) data.contractName = selectedContract.name createInstanceCallback(error, selectedContract, data) }) } @@ -464,7 +464,7 @@ function contractDropdown (events, self) { if (success) { selectContractNames.removeAttribute('disabled') self._deps.compiler.visitContracts((contract) => { - contractNames.appendChild(yo``) + contractNames.appendChild(yo``) }) } else { selectContractNames.setAttribute('disabled', true) diff --git a/test-browser/helpers/contracts.js b/test-browser/helpers/contracts.js index 38456add66..aefeaaf58c 100644 --- a/test-browser/helpers/contracts.js +++ b/test-browser/helpers/contracts.js @@ -7,7 +7,9 @@ module.exports = { addFile: addFile, switchFile: switchFile, verifyContract: verifyContract, + selectContract, testFunction, + testConstantFunction, checkDebug, goToVMtraceStep, useFilter, @@ -20,7 +22,8 @@ module.exports = { getEditorValue, testEditorValue, renameFile, - removeFile + removeFile, + getAddressAtPosition } function getCompiledContracts (browser, compiled, callback) { @@ -40,6 +43,13 @@ function getCompiledContracts (browser, compiled, callback) { }) } +function selectContract (browser, contractName, callback) { + browser.click('.runView') + .setValue('#runTabView select[class^="contractNames"]', contractName).perform(() => { + callback() + }) +} + function createContract (browser, inputParams, callback) { browser.click('.runView') .setValue('div[class^="contractActionsContainerSingle"] input', inputParams, function () { @@ -115,6 +125,34 @@ function verifyCallReturnValue (browser, address, checks, done) { }) } +function getAddressAtPosition (browser, index, callback) { + index = index + 2 + browser.execute(function (index) { + return document.querySelector('.instance:nth-of-type(' + index + ')').getAttribute('id').replace('instance', '') + }, [index], function (result) { + callback(result.value) + }) +} + +function testConstantFunction (browser, address, fnFullName, expectedInput, expectedOutput, cb) { + browser.waitForElementPresent('.instance button[title="' + fnFullName + '"]').perform(function (client, done) { + client.execute(function () { + document.querySelector('#optionViews').scrollTop = document.querySelector('#optionViews').scrollHeight + }, [], function () { + if (expectedInput) { + client.setValue('#runTabView input[title="' + expectedInput.types + '"]', expectedInput.values, function () {}) + } + done() + }) + }) + .click('.instance button[title="' + fnFullName + '"]') + .pause(1000) + .waitForElementPresent('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') + .assert.containsText('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]', expectedOutput).perform(() => { + cb() + }) +} + function testFunction (fnFullName, txHash, log, expectedInput, expectedReturn, expectedEvent, callback) { // this => browser this.waitForElementPresent('.instance button[title="' + fnFullName + '"]') @@ -330,11 +368,9 @@ function useFilter (browser, filter, test, done) { function switchFile (browser, name, done) { browser - .useXpath() - .click('//ul[@id="files"]//span[text()="' + name + '"]') - .useCss() + .click('li[key="' + name + '"]') .pause(2000) - .perform(function () { + .perform(() => { done() }) } diff --git a/test-browser/tests/simpleContract.js b/test-browser/tests/simpleContract.js index ef08304112..b45ed10210 100644 --- a/test-browser/tests/simpleContract.js +++ b/test-browser/tests/simpleContract.js @@ -19,6 +19,7 @@ module.exports = { function runTests (browser) { browser.setEditorValue = contractHelper.setEditorValue + browser.getEditorValue = contractHelper.getEditorValue browser .waitForElementVisible('.newFile', 10000) .click('.compileView') @@ -28,7 +29,10 @@ function runTests (browser) { async.waterfall([function (callback) { callback(null, browser) }, testSimpleContract, testSuccessImport, - testFailedImport /* testGitHubImport */ + testFailedImport, /* testGitHubImport */ + addDeployLibTestFile, + testAutoDeployLib, + testManualDeployLib ], function () { browser.end() @@ -66,6 +70,92 @@ function testFailedImport (browser, callback) { }) } +function addDeployLibTestFile (browser, callback) { + contractHelper.addFile(browser, 'Untitled5.sol', sources[5]['browser/Untitled5.sol'], () => { + callback(null, browser) + }) +} + +function testAutoDeployLib (browser, callback) { + console.log('testAutoDeployLib') + contractHelper.verifyContract(browser, ['test'], () => { + contractHelper.selectContract(browser, 'test', () => { + contractHelper.createContract(browser, '', () => { + contractHelper.getAddressAtPosition(browser, 0, (address) => { + console.log(address) + browser.waitForElementPresent('.instance:nth-of-type(2)').click('.instance:nth-of-type(2)').perform(() => { + contractHelper.testConstantFunction(browser, address, 'get - call', '', '0: uint256: 45', () => { callback(null, browser) }) + }) + }) + }) + }) + }) +} + +function testManualDeployLib (browser, callback) { + console.log('testManualDeployLib') + browser.click('i[class^="clearinstance"]').pause(5000).click('.settingsView').click('#generatecontractmetadata').perform(() => { + browser.click('.compileView').click('#compile').perform(() => { // that should generate the JSON artefact + contractHelper.verifyContract(browser, ['test'], () => { + contractHelper.selectContract(browser, 'lib', () => { // deploy lib + contractHelper.createContract(browser, '', () => { + contractHelper.getAddressAtPosition(browser, 0, (address) => { + console.log('address:', address) + checkDeployShouldFail(browser, () => { + checkDeployShouldSucceed(browser, address, () => { + callback(null, browser) + }) + }) + }) + }) + }) + }) + }) + }) +} + +function checkDeployShouldFail (browser, callback) { + contractHelper.switchFile(browser, 'browser/test.json', () => { + browser.getEditorValue((content) => { + var config = JSON.parse(content) + config['VM:-'].autoDeployLib = false + browser.setEditorValue(JSON.stringify(config), () => { + contractHelper.switchFile(browser, 'browser/Untitled5.sol', () => { + contractHelper.selectContract(browser, 'test', () => { // deploy lib + contractHelper.createContract(browser, '', () => { + browser.assert.containsText('div[class^="terminal"]', '
is not a valid address').perform(() => { callback() }) + }) + }) + }) + }) + }) + }) +} + +function checkDeployShouldSucceed (browser, address, callback) { + contractHelper.switchFile(browser, 'browser/test.json', () => { + browser.getEditorValue((content) => { + var config = JSON.parse(content) + config['VM:-'].autoDeployLib = false + config['VM:-']['linkReferences']['browser/Untitled5.sol'].lib = address + browser.setEditorValue(JSON.stringify(config), () => { + contractHelper.switchFile(browser, 'browser/Untitled5.sol', () => { + contractHelper.selectContract(browser, 'test', () => { // deploy lib + contractHelper.createContract(browser, '', () => { + contractHelper.getAddressAtPosition(browser, 1, (address) => { + browser.waitForElementPresent('.instance:nth-of-type(3)') + .click('.instance:nth-of-type(3)').perform(() => { + contractHelper.testConstantFunction(browser, address, 'get - call', '', '0: uint256: 45', () => { callback(null, browser) }) + }) + }) + }) + }) + }) + }) + }) + }) +} + /* function testGitHubImport (browser, callback) { contractHelper.addFile(browser, 'Untitled4.sol', sources[3]['browser/Untitled4.sol'], () => { @@ -217,5 +307,18 @@ var sources = [ 'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'}, 'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS}, 'github.com/ethereum/ens/contracts/AbstractENS.sol': {content: abstractENS} + }, + { + 'browser/Untitled5.sol': {content: `library lib { + function get () returns (uint) { + return 45; + } + } + + contract test { + function get () constant returns (uint) { + return lib.get(); + } +}`} } ]