Merge branch 'react-plugin-manager' of https://github.com/ethereum/remix-project into react-plugin-manager

pull/1344/head
joseph izang 3 years ago
commit 64cf9f6a45
  1. 21
      apps/remix-ide/src/app/tabs/test-tab.js
  2. 5
      libs/remix-tests/src/runTestSources.ts
  3. 8
      libs/remix-tests/src/testRunner.ts
  4. 1
      libs/remix-tests/src/types.ts
  5. 5
      libs/remix-tests/tests/examples_0/assert_ok_test.sol
  6. 1532
      libs/remix-tests/tests/examples_0/hardhat/console.sol
  7. 0
      libs/remix-tests/tests/testRunner.cli.spec_disabled.ts
  8. 39
      libs/remix-tests/tests/testRunner.spec.ts

@ -1,6 +1,7 @@
import { ViewPlugin } from '@remixproject/engine-web' import { ViewPlugin } from '@remixproject/engine-web'
import { removeMultipleSlashes, removeTrailingSlashes } from '../../lib/helper' import { removeMultipleSlashes, removeTrailingSlashes } from '../../lib/helper'
import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity'
import { format } from 'util'
var yo = require('yo-yo') var yo = require('yo-yo')
var async = require('async') var async = require('async')
var tooltip = require('../ui/tooltip') var tooltip = require('../ui/tooltip')
@ -179,6 +180,24 @@ module.exports = class TestTab extends ViewPlugin {
} }
} }
printHHLogs (logsArr, testName) {
let finalLogs = `<b>${testName}:</b>\n`
for (const log of logsArr) {
let formattedLog
// Hardhat implements the same formatting options that can be found in Node.js' console.log,
// which in turn uses util.format: https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args
// For example: console.log("Name: %s, Age: %d", remix, 6) will log 'Name: remix, Age: 6'
// We check first arg to determine if 'util.format' is needed
if (typeof log[0] === 'string' && (log[0].includes('%s') || log[0].includes('%d'))) {
formattedLog = format(log[0], ...log.slice(1))
} else {
formattedLog = log.join(' ')
}
finalLogs = finalLogs + '&emsp;' + formattedLog + '\n'
}
this.call('terminal', 'log', { type: 'info', value: finalLogs })
}
testCallback (result, runningTests) { testCallback (result, runningTests) {
this.testsOutput.hidden = false this.testsOutput.hidden = false
if (result.type === 'contract') { if (result.type === 'contract') {
@ -197,6 +216,7 @@ module.exports = class TestTab extends ViewPlugin {
` `
this.testsOutput.appendChild(this.outputHeader) this.testsOutput.appendChild(this.outputHeader)
} else if (result.type === 'testPass') { } else if (result.type === 'testPass') {
if (result.hhLogs && result.hhLogs.length) this.printHHLogs(result.hhLogs, result.value)
this.testsOutput.appendChild(yo` this.testsOutput.appendChild(yo`
<div <div
id="${this.runningTestFileName}" id="${this.runningTestFileName}"
@ -208,6 +228,7 @@ module.exports = class TestTab extends ViewPlugin {
</div> </div>
`) `)
} else if (result.type === 'testFailure') { } else if (result.type === 'testFailure') {
if (result.hhLogs && result.hhLogs.length) this.printHHLogs(result.hhLogs, result.value)
if (!result.assertMethod) { if (!result.assertMethod) {
this.testsOutput.appendChild(yo` this.testsOutput.appendChild(yo`
<div <div

@ -5,7 +5,7 @@ import { deployAll } from './deployer'
import { runTest } from './testRunner' import { runTest } from './testRunner'
import Web3 from 'web3' import Web3 from 'web3'
import { Provider } from '@remix-project/remix-simulator' import { Provider, extend } from '@remix-project/remix-simulator'
import { import {
FinalResult, SrcIfc, compilationInterface, ASTInterface, Options, FinalResult, SrcIfc, compilationInterface, ASTInterface, Options,
TestResultInterface, AstNode, CompilerConfiguration TestResultInterface, AstNode, CompilerConfiguration
@ -17,6 +17,7 @@ const createWeb3Provider = async function () {
const provider: any = new Provider() const provider: any = new Provider()
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
extend(web3)
return web3 return web3
} }
@ -102,7 +103,7 @@ export async function runTestSources (contractSources: SrcIfc, compilerConfig: C
async.eachOfLimit(contractsToTest, 1, (contractName: string, index: string | number, cb: ErrorCallback) => { async.eachOfLimit(contractsToTest, 1, (contractName: string, index: string | number, cb: ErrorCallback) => {
const fileAST: AstNode = sourceASTs[contracts[contractName]['filename']] const fileAST: AstNode = sourceASTs[contracts[contractName]['filename']]
runTest(contractName, contracts[contractName], contractsToTestDetails[index], fileAST, { accounts }, _testCallback, (err, result) => { runTest(contractName, contracts[contractName], contractsToTestDetails[index], fileAST, { accounts, web3 }, _testCallback, (err, result) => {
if (err) { if (err) {
return cb(err) return cb(err)
} }

@ -217,7 +217,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
const isJSONInterfaceAvailable = testObject && testObject.options && testObject.options.jsonInterface const isJSONInterfaceAvailable = testObject && testObject.options && testObject.options.jsonInterface
if (!isJSONInterfaceAvailable) { return resultsCallback(new Error('Contract interface not available'), { passingNum, failureNum, timePassed }) } if (!isJSONInterfaceAvailable) { return resultsCallback(new Error('Contract interface not available'), { passingNum, failureNum, timePassed }) }
const runList: RunListInterface[] = createRunList(testObject.options.jsonInterface, fileAST, testName) const runList: RunListInterface[] = createRunList(testObject.options.jsonInterface, fileAST, testName)
const web3 = new Web3() const web3 = opts.web3 || new Web3()
const accts: TestResultInterface = { const accts: TestResultInterface = {
type: 'accountList', type: 'accountList',
value: opts.accounts value: opts.accounts
@ -282,8 +282,10 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
} }
if (!sendParams) sendParams = {} if (!sendParams) sendParams = {}
sendParams.gas = 10000000 * 8 sendParams.gas = 10000000 * 8
method.send(sendParams).on('receipt', (receipt) => { method.send(sendParams).on('receipt', async (receipt) => {
try { try {
let hhLogs
if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(receipt.transactionHash)
const time: number = (Date.now() - startTime) / 1000.0 const time: number = (Date.now() - startTime) / 1000.0
const assertionEventHashes = assertionEvents.map(e => Web3.utils.sha3(e.name + '(' + e.params.join() + ')')) const assertionEventHashes = assertionEvents.map(e => Web3.utils.sha3(e.name + '(' + e.params.join() + ')'))
let testPassed = false let testPassed = false
@ -313,6 +315,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
expected: testEvent[4], expected: testEvent[4],
location location
} }
if (hhLogs) resp.hhLogs = hhLogs
testCallback(undefined, resp) testCallback(undefined, resp)
failureNum += 1 failureNum += 1
timePassed += time timePassed += time
@ -331,6 +334,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
time: time, time: time,
context: testName context: testName
} }
if (hhLogs) resp.hhLogs = hhLogs
testCallback(undefined, resp) testCallback(undefined, resp)
passingNum += 1 passingNum += 1
timePassed += time timePassed += time

@ -36,6 +36,7 @@ export interface TestResultInterface {
returned?: string | number returned?: string | number
expected?: string | number expected?: string | number
location?: string location?: string
hhLogs?: []
} }
export interface TestCbInterface { export interface TestCbInterface {
(error: Error | null | undefined, result: TestResultInterface) : void; (error: Error | null | undefined, result: TestResultInterface) : void;

@ -1,12 +1,17 @@
import "remix_tests.sol"; // this import is automatically injected by Remix. import "remix_tests.sol"; // this import is automatically injected by Remix.
import "./hardhat/console.sol";
contract AssertOkTest { contract AssertOkTest {
function okPassTest() public { function okPassTest() public {
console.log("AssertOkTest", "okPassTest");
Assert.ok(true, "okPassTest passes"); Assert.ok(true, "okPassTest passes");
} }
function okFailTest() public { function okFailTest() public {
console.log("AssertOkTest", "okFailTest");
Assert.ok(false, "okFailTest fails"); Assert.ok(false, "okFailTest fails");
} }
} }

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
import * as async from 'async' import * as async from 'async'
import Web3 from 'web3'; import Web3 from 'web3';
import * as assert from 'assert' import * as assert from 'assert'
import { Provider } from '@remix-project/remix-simulator' import { Provider, extend } from '@remix-project/remix-simulator'
import { compileFileOrFiles } from '../src/compiler' import { compileFileOrFiles } from '../src/compiler'
import { deployAll } from '../src/deployer' import { deployAll } from '../src/deployer'
@ -47,6 +47,7 @@ async function compileAndDeploy(filename: string, callback: Function) {
let sourceASTs: any = {} let sourceASTs: any = {}
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
extend(web3)
let compilationData: object let compilationData: object
async.waterfall([ async.waterfall([
function getAccountList(next: Function): void { function getAccountList(next: Function): void {
@ -72,7 +73,7 @@ async function compileAndDeploy(filename: string, callback: Function) {
} }
} }
], function (_err: Error | null | undefined, contracts: any): void { ], function (_err: Error | null | undefined, contracts: any): void {
callback(null, compilationData, contracts, sourceASTs, accounts) callback(null, compilationData, contracts, sourceASTs, accounts, web3)
}) })
} }
@ -106,8 +107,8 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_0/assert_ok_test.sol' const filename: string = __dirname + '/examples_0/assert_ok_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertOkTest', contracts.AssertOkTest, compilationData[filename]['AssertOkTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertOkTest', contracts.AssertOkTest, compilationData[filename]['AssertOkTest'], asts[filename], { accounts, web3 }, testCallback, resultsCallback(done))
}) })
}) })
@ -121,12 +122,14 @@ describe('testRunner', () => {
assert.equal(results.failureNum, 1) assert.equal(results.failureNum, 1)
}) })
const hhLogs1 = [ [ "AssertOkTest", "okPassTest"]]
const hhLogs2 = [ [ "AssertOkTest", "okFailTest"]]
it('should return', () => { it('should return', () => {
deepEqualExcluding(tests, [ deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts }, { type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertOkTest', filename: __dirname + '/examples_0/assert_ok_test.sol' }, { type: 'contract', value: 'AssertOkTest', filename: __dirname + '/examples_0/assert_ok_test.sol' },
{ type: 'testPass', value: 'Ok pass test', filename: __dirname + '/examples_0/assert_ok_test.sol', context: 'AssertOkTest' }, { type: 'testPass', value: 'Ok pass test', filename: __dirname + '/examples_0/assert_ok_test.sol', context: 'AssertOkTest', hhLogs: hhLogs1 },
{ type: 'testFailure', value: 'Ok fail test', filename: __dirname + '/examples_0/assert_ok_test.sol', errMsg: 'okFailTest fails', context: 'AssertOkTest', assertMethod: 'ok', location: '234:36:0', expected: 'true', returned: 'false'}, { type: 'testFailure', value: 'Ok fail test', filename: __dirname + '/examples_0/assert_ok_test.sol', errMsg: 'okFailTest fails', context: 'AssertOkTest', hhLogs: hhLogs2, assertMethod: 'ok', location: '370:36:0', expected: 'true', returned: 'false'},
], ['time']) ], ['time'])
}) })
@ -136,7 +139,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_0/assert_equal_test.sol' const filename: string = __dirname + '/examples_0/assert_equal_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertEqualTest', contracts.AssertEqualTest, compilationData[filename]['AssertEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertEqualTest', contracts.AssertEqualTest, compilationData[filename]['AssertEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -175,7 +178,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_0/assert_notEqual_test.sol' const filename: string = __dirname + '/examples_0/assert_notEqual_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertNotEqualTest', contracts.AssertNotEqualTest, compilationData[filename]['AssertNotEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertNotEqualTest', contracts.AssertNotEqualTest, compilationData[filename]['AssertNotEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -214,7 +217,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_0/assert_greaterThan_test.sol' const filename: string = __dirname + '/examples_0/assert_greaterThan_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertGreaterThanTest', contracts.AssertGreaterThanTest, compilationData[filename]['AssertGreaterThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertGreaterThanTest', contracts.AssertGreaterThanTest, compilationData[filename]['AssertGreaterThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -248,7 +251,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_0/assert_lesserThan_test.sol' const filename: string = __dirname + '/examples_0/assert_lesserThan_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertLesserThanTest', contracts.AssertLesserThanTest, compilationData[filename]['AssertLesserThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertLesserThanTest', contracts.AssertLesserThanTest, compilationData[filename]['AssertLesserThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -283,7 +286,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_1/simple_storage_test.sol' const filename: string = __dirname + '/examples_1/simple_storage_test.sol'
beforeAll((done) => { beforeAll((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -314,7 +317,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_2/simple_storage_test.sol' const filename: string = __dirname + '/examples_2/simple_storage_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -344,7 +347,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_3/simple_string_test.sol' const filename: string = __dirname + '/examples_3/simple_string_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -370,7 +373,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_5/test/simple_storage_test.sol' const filename: string = __dirname + '/examples_5/test/simple_storage_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -397,7 +400,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/examples_4/SafeMath_test.sol' const filename: string = __dirname + '/examples_4/SafeMath_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SafeMathTest', contracts.SafeMathTest, compilationData[filename]['SafeMathTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('SafeMathTest', contracts.SafeMathTest, compilationData[filename]['SafeMathTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -417,7 +420,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/number/number_test.sol' const filename: string = __dirname + '/number/number_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -437,7 +440,7 @@ describe('testRunner', () => {
const filename: string = __dirname + '/various_sender/sender_and_value_test.sol' const filename: string = __dirname + '/various_sender/sender_and_value_test.sol'
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SenderAndValueTest', contracts.SenderAndValueTest, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('SenderAndValueTest', contracts.SenderAndValueTest, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
@ -465,7 +468,7 @@ describe('testRunner', () => {
} }
} }
beforeAll(done => { beforeAll(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SenderAndValueTest', undefined, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, errorCallback(done)) runTest('SenderAndValueTest', undefined, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, errorCallback(done))
}) })
}) })

Loading…
Cancel
Save