-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* web3Function tests, bug fix (#172) * Test contract decoration matches snapshot * Update yarn.lock * Improve Contract test coverage * Classify existing Contract tests as unit tests * Run contract tests with multiple web3 versions * Clear localStorage between contract tests * Improve comment * Remove redundant comment * Mock websocket in contract test * Remove mock-socket from contract tests * Only snapshot test a subset of decoratedContract * Remove redundant logic * Mock the web3 websocket connection * Cleanup * Use a complex ABI for contract decoration tests * Refactor contract delegation for web3 >beta.37 * Improve comments * Hardcode userAgent in tests * Setup a ganache instance for use in the test env * Improve ganache error handling * Create web3.js test structure * - Add test for web3Func bigNumber - Add test for web3Func gasPrice * Handle restarting ganache when jest is watching * Add test for web3Funcs.contractGas * Set ganache account generation to be deterministic * - Add test for web3Func txGas - Add test for web3Func balance - Add test for web3Func accounts - Add test for web3Func txReceipt * Create ganacheConfig.js * Deploy contract to testing ganache chain * Remove redundant console.log * Add truffle-contract dependency * Change the contract deployed to test ganache chain * Test estimating gas of a truffle method call * Reduce logic duplication * Improve comments * Explicitly end tests once ganache is shutdown * Fix estimateGas on truffle contract methods * use latest web3 beta 55 in tests * update to 0.7.3
- Loading branch information
Showing
11 changed files
with
1,656 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const port = 8546 | ||
const accounts = [ | ||
'0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1', | ||
'0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' | ||
] | ||
const args = ['-i 5', `-p ${port}`, '-a 2', '--deterministic'] | ||
const convertLibAddress = '0xe78a0f7e598cc8b0bb87894b0f60dd2a88d6a8ab' | ||
|
||
module.exports = { | ||
args, | ||
port, | ||
accounts, | ||
convertLibAddress | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* eslint-disable import/no-extraneous-dependencies */ | ||
/* eslint-disable no-console */ | ||
/* eslint-disable class-methods-use-this */ | ||
const kill = require('kill-port') | ||
const Web3 = require('web3') | ||
const { spawn } = require('child_process') | ||
const convertLib = require('../src/__tests__/res/ConvertLib.json') | ||
const { args, port, accounts } = require('./ganacheConfig.js') | ||
|
||
class Reporter { | ||
constructor(globalConfig) { | ||
this._globalConfig = globalConfig | ||
} | ||
|
||
// checks if jest was run with --watch or --watchall | ||
watching() { | ||
return this._globalConfig.watch || this._globalConfig.watchAll | ||
} | ||
|
||
// start a ganache instance before test run starts | ||
async onRunStart() { | ||
console.log(`Starting Ganache on port ${port}`) | ||
await kill(port) | ||
this.ganacheProcess = spawn('./node_modules/.bin/ganache-cli', args) | ||
|
||
this.ganacheProcess.on('close', code => { | ||
if (code !== 0 && code !== 137) { | ||
console.log(`Ganache process closed with code ${code}`) | ||
process.exit(code) | ||
} | ||
!this.watching() && process.exit(code) | ||
}) | ||
this.ganacheProcess.on('error', code => { | ||
console.error(`ERROR: Ganache exited with code ${code}`) | ||
process.exit(code) | ||
}) | ||
this.ganacheProcess.on('exit', code => { | ||
if (code === 1) { | ||
console.error(`ERROR: Ganache exited with code ${code}`) | ||
console.error( | ||
`Is there already a process already running on port ${port}?` | ||
) | ||
process.exit(code) | ||
} | ||
!this.watching() && process.exit(code) | ||
}) | ||
|
||
// Wait until ganache is running | ||
await new Promise(resolve => { | ||
this.ganacheProcess.stdout.setEncoding('utf8') | ||
this.ganacheProcess.stdout.on('data', chunk => { | ||
if (chunk.includes('Listening')) { | ||
console.log(`Ganache running on port ${chunk.split(':')[1]}`) | ||
resolve() | ||
} | ||
}) | ||
}) | ||
|
||
// Deploy a contract for truffle testing | ||
this.web3 = new Web3(`ws://localhost:${port}`) | ||
const convertLibWeb3 = await new this.web3.eth.Contract(convertLib.abi) | ||
convertLibWeb3 | ||
.deploy({ data: convertLib.bytecode }) | ||
.send({ from: accounts[0], gasLimit: 1500000 }) | ||
|
||
// Ganache setup done, tests will now execute | ||
} | ||
|
||
// On completion kill the ganache instance and exit the test run | ||
async onRunComplete() { | ||
this.web3.currentProvider.connection.close() | ||
kill(port) | ||
.then(() => !this.watching() && process.exit(0)) | ||
.catch(() => console.error(`Failed to kill ganache on port ${port}`)) | ||
} | ||
} | ||
|
||
module.exports = Reporter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
import truffleContract from 'truffle-contract' | ||
import da from '~/js' | ||
import abi from '~/__tests__/res/dstoken.json' | ||
import { state, initialState, updateState } from '~/js/helpers/state' | ||
import * as websockets from '~/js/helpers/websockets' | ||
import { web3Functions } from '~/js/helpers/web3' | ||
import convertLibJson from '~/__tests__/res/ConvertLib' | ||
import { | ||
accounts, | ||
convertLibAddress, | ||
port | ||
} from '../../../internals/ganacheConfig' | ||
|
||
const multidepRequire = require('multidep')('multidep.json') | ||
|
||
const Web3v0p20 = multidepRequire('web3', '0.20.6') | ||
|
||
const zeroAddress = '0x0000000000000000000000000000000000000000' | ||
|
||
const initWeb3 = (simpleVersion, Web3) => { | ||
if (simpleVersion === '1.0') { | ||
return new Web3(`ws://localhost:${port}`) | ||
} | ||
const provider = new Web3.providers.HttpProvider(`http://localhost:${port}`) | ||
return new Web3(provider) | ||
} | ||
|
||
describe(`web3.js tests`, () => { | ||
multidepRequire.forEachVersion('web3', (version, Web3) => { | ||
describe(`using web3 ${version}`, () => { | ||
describe('assist is initialised correctly', () => { | ||
let web3 | ||
let config | ||
let simpleVersion | ||
beforeEach(() => { | ||
jest | ||
.spyOn(websockets, 'openWebsocketConnection') | ||
.mockImplementation(() => {}) | ||
simpleVersion = version.slice(0, 3) | ||
web3 = initWeb3(simpleVersion, Web3) | ||
config = { dappId: '123', web3, networkId: '5' } | ||
da.init(config) | ||
}) | ||
afterEach(() => { | ||
// need to close any websocket connection | ||
if (simpleVersion === '1.0') { | ||
web3.currentProvider.connection.close() | ||
} | ||
}) | ||
describe('web3Functions', () => { | ||
describe('networkId', () => { | ||
test('should return the expected networkId', async () => { | ||
const networkId = await web3Functions.networkId(simpleVersion)() | ||
if (simpleVersion === '1.0') expect(networkId).toEqual(5) | ||
else expect(networkId).toEqual('5') // 0.20 returns networkId as a string | ||
}) | ||
}) | ||
describe('bigNumber', () => { | ||
test('should return the expected bigNumber', async () => { | ||
const bigNum1 = await web3Functions.bigNumber(simpleVersion)(5) | ||
const bigNum2 = await web3Functions.bigNumber(simpleVersion)('10') | ||
expect(typeof bigNum1).toEqual('object') | ||
expect(bigNum1.toString()).toEqual('5') | ||
expect(bigNum1.toNumber()).toEqual(5) | ||
expect(bigNum1.add(bigNum2).toString()).toEqual('15') | ||
}) | ||
}) | ||
describe('gasPrice', () => { | ||
test('should return the expected gasPrice', async () => { | ||
const expected = '20000000000' // recommended gasPrice should be 20000000000 | ||
const gasPrice = await web3Functions.gasPrice(simpleVersion)() | ||
expect(gasPrice.toString()).toEqual(expected) | ||
}) | ||
}) | ||
describe('contractGas', () => { | ||
let contract | ||
describe('from a web3 contract', () => { | ||
beforeEach(() => { | ||
contract = web3.eth.contract | ||
? web3.eth.contract(abi).at(zeroAddress) // web3 0.20 | ||
: new web3.eth.Contract(abi, zeroAddress) // web3 1.0 | ||
}) | ||
test('should return the expected gas cost', async () => { | ||
const expected = 21400 // gas the setOwner call should cost | ||
const contract = web3.eth.contract | ||
? web3.eth.contract(abi).at(zeroAddress) // web3 0.20 | ||
: new web3.eth.Contract(abi, zeroAddress) // web3 1.0 | ||
const contractMethod = contract.methods | ||
? contract.methods.setOwner // web3 1.0 | ||
: contract.setOwner // web3 0.20 | ||
const parameters = [zeroAddress] | ||
const contractGas = await web3Functions.contractGas( | ||
simpleVersion | ||
)(contractMethod, parameters, {}) | ||
expect(contractGas).toEqual(expected) | ||
}) | ||
}) | ||
describe('from a truffle contract', () => { | ||
let contractInstance | ||
beforeEach(async () => { | ||
state.config.truffleContract = true | ||
contract = truffleContract(convertLibJson) | ||
contract.setProvider( | ||
new Web3v0p20.providers.HttpProvider( | ||
`http://localhost:${port}` | ||
) | ||
) | ||
contractInstance = await contract.at(convertLibAddress) | ||
}) | ||
afterEach(() => { | ||
state.config.truffleContract = false | ||
}) | ||
// doesn't seem to work | ||
// see https://github.com/blocknative/assist/issues/171 | ||
test('should return the expected gas cost', async () => { | ||
const expected = 21988 // gas the convert call should cost | ||
const contractMethod = contractInstance.convert | ||
const parameters = [5, 10] | ||
const contractGas = await web3Functions.contractGas( | ||
simpleVersion | ||
)(contractMethod, parameters) | ||
expect(contractGas).toEqual(expected) | ||
}) | ||
}) | ||
}) | ||
describe('transactionGas', () => { | ||
test('should return the expected gas cost', async () => { | ||
const expected = 21464 // gas this tx should cost | ||
const estimate = await web3Functions.transactionGas( | ||
simpleVersion | ||
)({ | ||
to: '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe', | ||
data: | ||
'0xc6888fa10000000000000000000000000000000000000000000000000000000000000003' | ||
}) | ||
expect(estimate).toEqual(expected) | ||
}) | ||
}) | ||
describe('balance', () => { | ||
test(`should return an address's balance`, async () => { | ||
const expected = '100000000000000000000' // 100 ETH | ||
const balance = await web3Functions.balance(simpleVersion)( | ||
accounts[1] | ||
) | ||
expect(balance.toString()).toEqual(expected) | ||
}) | ||
}) | ||
describe('accounts', () => { | ||
test(`should return the correct list of accounts`, async () => { | ||
const expected = | ||
simpleVersion === '1.0' | ||
? accounts | ||
: accounts.map(a => a.toLowerCase()) | ||
const res = await web3Functions.accounts(simpleVersion)() | ||
expect(res).toEqual(expected) | ||
}) | ||
}) | ||
describe('txReceipt', () => { | ||
test(`should return the correct receipt`, async () => { | ||
const hash = await new Promise(resolve => { | ||
if (simpleVersion === '1.0') { | ||
web3.eth | ||
.sendTransaction({ | ||
from: accounts[0], | ||
to: zeroAddress, | ||
value: 10 | ||
}) | ||
.on('transactionHash', hash => { | ||
resolve(hash) | ||
}) | ||
} else { | ||
web3.eth.sendTransaction( | ||
{ | ||
from: accounts[0], | ||
to: zeroAddress, | ||
value: 10 | ||
}, | ||
(err, hash) => resolve(hash) | ||
) | ||
} | ||
}) | ||
const receipt = await web3Functions.txReceipt(hash) | ||
expect(receipt.to).toEqual(zeroAddress) | ||
expect(receipt).toHaveProperty('blockNumber') | ||
expect(receipt).toHaveProperty('transactionHash') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
|
||
afterEach(() => { | ||
document.body.innerHTML = '' | ||
updateState(initialState) | ||
window.localStorage.clear() | ||
jest.clearAllMocks() | ||
}) |
Oops, something went wrong.