diff --git a/remix-tests/src/compiler.ts b/remix-tests/src/compiler.ts index d2d5ed253e..6f0298fc11 100644 --- a/remix-tests/src/compiler.ts +++ b/remix-tests/src/compiler.ts @@ -125,7 +125,7 @@ export function compileFileOrFiles(filename: string, isDirectory: boolean, opts: if (!isBrowser) require('signale').fatal(errors) return cb(errors) } - cb(err, result.contracts) + cb(err, result.contracts, result.sources) }) } } diff --git a/remix-tests/src/runTestFiles.ts b/remix-tests/src/runTestFiles.ts index cffcee9028..a4d283c21f 100644 --- a/remix-tests/src/runTestFiles.ts +++ b/remix-tests/src/runTestFiles.ts @@ -10,6 +10,7 @@ import { deployAll } from './deployer' export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, opts?: object) { opts = opts || {} + let sourceASTs: any = {} const { Signale } = require('signale') // signale configuration const options = { @@ -44,7 +45,12 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, function compile(next: Function) { compileFileOrFiles(filepath, isDirectory, { accounts }, next) }, - function deployAllContracts (compilationResult, next: Function) { + function deployAllContracts (compilationResult, asts, next: Function) { + for(const filename in asts) + { + if(filename.includes('_test.sol')) + sourceASTs[filename] = asts[filename].ast + } deployAll(compilationResult, web3, (err, contracts) => { if (err) { next(err) @@ -60,10 +66,10 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, return } try { - Object.keys(compilationResult[filename]).forEach(contractName => { - contractsToTest.push(contractName) - contractsToTestDetails.push(compilationResult[filename][contractName]) - }) + Object.keys(compilationResult[filename]).forEach(contractName => { + contractsToTest.push(contractName) + contractsToTestDetails.push(compilationResult[filename][contractName]) + }) } catch (e) { console.error(e) } @@ -103,7 +109,7 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, async.eachOfLimit(contractsToTest, 1, (contractName: string, index, cb) => { try { - runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { + runTest(contractName, contracts[contractName], contractsToTestDetails[index], sourceASTs[contracts[contractName]['filename']], { accounts }, _testCallback, (err, result) => { if (err) { console.log(err) return cb(err) diff --git a/remix-tests/src/runTestSources.ts b/remix-tests/src/runTestSources.ts index adb89529ce..c6407b06e9 100644 --- a/remix-tests/src/runTestSources.ts +++ b/remix-tests/src/runTestSources.ts @@ -79,7 +79,8 @@ export async function runTestSources(contractSources, versionUrl, usingWorker, t } async.eachOfLimit(contractsToTest, 1, (contractName: string, index: string | number, cb: ErrorCallback) => { - runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { + // todo: pass AST + runTest(contractName, contracts[contractName], contractsToTestDetails[index], [], { accounts }, _testCallback, (err, result) => { if (err) { return cb(err) } diff --git a/remix-tests/src/testRunner.ts b/remix-tests/src/testRunner.ts index 2675ce0190..299a023d0e 100644 --- a/remix-tests/src/testRunner.ts +++ b/remix-tests/src/testRunner.ts @@ -19,25 +19,34 @@ function getOverridedSender (userdoc, signature: string, methodIdentifiers) { return fullName && accountIndex ? accountIndex[1] : null } -function getAvailableFunctions (jsonInterface) { - return jsonInterface.reverse().filter((x) => x.type === 'function').map((x) => x.name) +function getAvailableFunctions (fileAST, testContractName) { + let contractAST: any[] = fileAST.nodes.filter(node => node.name === testContractName && node.nodeType === 'ContractDefinition') + let funcNodes: any[] = contractAST[0].nodes.filter(node => node.kind === 'function' && node.nodeType === "FunctionDefinition") + let funcList: string[] = funcNodes.map(node => node.name) + return funcList; } -function getTestFunctions (jsonInterface) { +function getTestFunctionsInterface (jsonInterface, funcList: string[]) { + let resutantInterface: any[] = [] let specialFunctions = ['beforeAll', 'beforeEach', 'afterAll', 'afterEach'] - return jsonInterface.filter((x) => specialFunctions.indexOf(x.name) < 0 && x.type === 'function') + for(const func of funcList){ + if(!specialFunctions.includes(func)) + resutantInterface.push(jsonInterface.find(node => node.type === 'function' && node.name === func)) + } + return resutantInterface } -function createRunList (jsonInterface): RunListInterface[] { - let availableFunctions = getAvailableFunctions(jsonInterface) - let testFunctions = getTestFunctions(jsonInterface) +function createRunList (jsonInterface, fileAST, testContractName): RunListInterface[] { + let availableFunctions = getAvailableFunctions(fileAST, testContractName) + let testFunctionsInterface = getTestFunctionsInterface(jsonInterface, availableFunctions) + let runList: RunListInterface[] = [] if (availableFunctions.indexOf('beforeAll') >= 0) { runList.push({ name: 'beforeAll', type: 'internal', constant: false }) } - for (let func of testFunctions) { + for (let func of testFunctionsInterface) { if (availableFunctions.indexOf('beforeEach') >= 0) { runList.push({ name: 'beforeEach', type: 'internal', constant: false }) } @@ -54,9 +63,8 @@ function createRunList (jsonInterface): RunListInterface[] { return runList } -export function runTest (testName, testObject: any, contractDetails: any, opts: any, testCallback: TestCbInterface, resultsCallback: ResultCbInterface) { - let runList = createRunList(testObject._jsonInterface) - +export function runTest (testName, testObject: any, contractDetails: any, fileAST: any, opts: any, testCallback: TestCbInterface, resultsCallback: ResultCbInterface) { + let runList = createRunList(testObject._jsonInterface, fileAST, testName) let passingNum: number = 0 let failureNum: number = 0 let timePassed: number = 0 diff --git a/remix-tests/tests/examples_2/simple_storage_test.sol b/remix-tests/tests/examples_2/simple_storage_test.sol index cc4ab325ae..a073d15f69 100644 --- a/remix-tests/tests/examples_2/simple_storage_test.sol +++ b/remix-tests/tests/examples_2/simple_storage_test.sol @@ -13,11 +13,11 @@ contract MyTest { i += 1; } - function initialValueShouldBe200() public returns (bool) { - return Assert.equal(foo.get(), 200, "initial value is not correct"); + function initialValueShouldBe100() public returns (bool) { + return Assert.equal(foo.get(), 100, "initial value is not correct"); } - function valueShouldBe100() public returns (bool) { - return Assert.equal(foo.get(), 100, "value is not correct after first execution"); + function valueIsSet200() public returns (bool) { + return Assert.equal(foo.get(), 200, "value is not correct after first execution"); } } diff --git a/remix-tests/tests/testRunner.ts b/remix-tests/tests/testRunner.ts index ba79ca8b54..ff7151bded 100644 --- a/remix-tests/tests/testRunner.ts +++ b/remix-tests/tests/testRunner.ts @@ -37,7 +37,6 @@ function deepEqualExcluding(a: any, b: any, excludedKeys: string[]) { let aStripped: any = removeKeysFromObject(a, excludedKeys); let bStripped: any = removeKeysFromObject(b, excludedKeys); - assert.deepEqual(aStripped, bStripped) } @@ -46,6 +45,7 @@ let provider = new Provider() async function compileAndDeploy(filename: string, callback: Function) { let web3: Web3 = new Web3() + let sourceASTs: any = {} await provider.init() web3.setProvider(provider) let compilationData: object @@ -60,7 +60,12 @@ async function compileAndDeploy(filename: string, callback: Function) { function compile(next: Function): void { compileFileOrFiles(filename, false, { accounts }, next) }, - function deployAllContracts(compilationResult: object, next: Function): void { + function deployAllContracts(compilationResult: object, asts, next: Function): void { + for(const filename in asts) + { + if(filename.includes('_test.sol')) + sourceASTs[filename] = asts[filename].ast + } try { compilationData = compilationResult deployAll(compilationResult, web3, next) @@ -69,7 +74,7 @@ async function compileAndDeploy(filename: string, callback: Function) { } } ], function (_err: Error | null | undefined, contracts: any): void { - callback(null, compilationData, contracts, accounts) + callback(null, compilationData, contracts, sourceASTs, accounts) }) } @@ -101,8 +106,8 @@ describe('testRunner', () => { let filename: string = 'tests/examples_1/simple_storage_test.sol' before((done) => { - compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, accounts: string[]) => { - runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) => { + runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) }) @@ -120,11 +125,11 @@ describe('testRunner', () => { deepEqualExcluding(tests, [ { type: 'accountList', value: accounts }, { type: 'contract', value: 'MyTest', filename: 'tests/examples_1/simple_storage_test.sol' }, + { type: 'testPass', value: 'Initial value should be100', context: 'MyTest' }, { type: 'testPass', value: 'Initial value should not be200', context: 'MyTest' }, { type: 'testFailure', value: 'Should trigger one fail', errMsg: 'uint test 1 fails', context: 'MyTest' }, - { type: 'testPass', value: 'Should trigger one pass', context: 'MyTest' }, - { type: 'testPass', value: 'Initial value should be100', context: 'MyTest' } - ], ['time', 'value']) + { type: 'testPass', value: 'Should trigger one pass', context: 'MyTest' } + ], ['time']) }) }) @@ -132,8 +137,8 @@ describe('testRunner', () => { let filename = 'tests/examples_2/simple_storage_test.sol' before(function (done) { - compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, accounts: string[]) { - runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { + runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) }) @@ -151,8 +156,8 @@ describe('testRunner', () => { deepEqualExcluding(tests, [ { type: 'accountList', value: accounts }, { type: 'contract', value: 'MyTest', filename: 'tests/examples_2/simple_storage_test.sol' }, - { type: 'testPass', value: 'Value should be100', context: 'MyTest' }, - { type: 'testPass', value: 'Initial value should be200', context: 'MyTest' } + { type: 'testPass', value: 'Initial value should be100', context: 'MyTest' }, + { type: 'testPass', value: 'Value is set200', context: 'MyTest' } ], ['time']) }) }) @@ -162,8 +167,8 @@ describe('testRunner', () => { let filename = 'tests/examples_3/simple_string_test.sol' before(function (done) { - compileAndDeploy(filename, (_err, compilationData, contracts, accounts) => { - runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { + runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) }) @@ -177,8 +182,8 @@ describe('testRunner', () => { deepEqualExcluding(tests, [ { type: 'accountList', value: accounts }, { type: 'contract', value: 'StringTest', filename: 'tests/examples_3/simple_string_test.sol' }, - { type: 'testPass', value: 'Value should not be hello wordl', context: 'StringTest' }, - { type: 'testPass', value: 'Initial value should be hello world', context: 'StringTest' } + { type: 'testPass', value: 'Initial value should be hello world', context: 'StringTest' }, + { type: 'testPass', value: 'Value should not be hello wordl', context: 'StringTest' } ], ['time']) }) }) @@ -188,8 +193,8 @@ describe('testRunner', () => { let filename = 'tests/examples_5/test/simple_storage_test.sol' before(function (done) { - compileAndDeploy(filename, (_err, compilationData, contracts, accounts) => { - runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { + runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) }) @@ -204,8 +209,8 @@ describe('testRunner', () => { { type: 'accountList', value: accounts }, { type: 'contract', value: 'StorageResolveTest', filename: 'tests/examples_5/test/simple_storage_test.sol' }, { type: 'testPass', value: 'Initial value should be100', context: 'StorageResolveTest' }, - { type: 'testPass', value: 'Check if odd', context: 'StorageResolveTest' }, - { type: 'testPass', value: 'Check if even', context: 'StorageResolveTest' } + { type: 'testPass', value: 'Check if even', context: 'StorageResolveTest' }, + { type: 'testPass', value: 'Check if odd', context: 'StorageResolveTest' } ], ['time']) }) }) @@ -215,8 +220,8 @@ describe('testRunner', () => { let filename = 'tests/number/number_test.sol' before(function (done) { - compileAndDeploy(filename, (_err, compilationData, contracts, accounts) => { - runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { + runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) }) @@ -235,8 +240,8 @@ describe('testRunner', () => { let filename = 'tests/various_sender/sender_test.sol' before(function (done) { - compileAndDeploy(filename, (_err, compilationData, contracts, accounts) => { - runTest('SenderTest', contracts.SenderTest, compilationData[filename]['SenderTest'], { accounts }, testCallback, resultsCallback(done)) + compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: object, contracts: any, asts: any, accounts: string[]) { + runTest('SenderTest', contracts.SenderTest, compilationData[filename]['SenderTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) }) })