lint working for remix-tests

pull/5/head
aniket-engg 4 years ago
parent fb478a8da7
commit 1cc0ba34e0
  1. 17
      libs/remix-tests/.eslintrc
  2. 8
      libs/remix-tests/package.json
  3. 42
      libs/remix-tests/src/compiler.ts
  4. 58
      libs/remix-tests/src/deployer.ts
  5. 4
      libs/remix-tests/src/fileSystem.ts
  6. 2
      libs/remix-tests/src/logger.ts
  7. 6
      libs/remix-tests/src/run.ts
  8. 24
      libs/remix-tests/src/runTestFiles.ts
  9. 22
      libs/remix-tests/src/runTestSources.ts
  10. 22
      libs/remix-tests/src/testRunner.ts
  11. 8
      libs/remix-tests/src/types.ts
  12. 10
      libs/remix-tests/tests/testRunner.ts
  13. 25
      libs/remix-tests/tsconfig.json
  14. 15
      libs/remix-tests/tsconfig.lib.json
  15. 31
      workspace.json

@ -0,0 +1,17 @@
{
"extends": "../../.eslintrc",
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-ts-comment": "off"
},
"env": {
"browser": true,
"amd": true,
"node": true,
"es6": true
},
"ignorePatterns": ["!**/*"]
}

@ -1,5 +1,5 @@
{ {
"name": "remix-tests", "name": "@remix-project/remix-tests",
"version": "0.1.33", "version": "0.1.33",
"description": "Tool to test Solidity smart contracts", "description": "Tool to test Solidity smart contracts",
"main": "./dist/index.js", "main": "./dist/index.js",
@ -44,9 +44,9 @@
"change-case": "^3.0.1", "change-case": "^3.0.1",
"colors": "^1.1.2", "colors": "^1.1.2",
"commander": "^2.13.0", "commander": "^2.13.0",
"remix-lib": "0.4.29", "@remix-project/remix-lib": "0.4.29",
"remix-simulator": "0.1.9-beta.5", "@remix-project/remix-simulator": "0.1.9-beta.5",
"remix-solidity": "0.3.30", "@remix-project/remix-solidity": "0.3.30",
"signale": "^1.4.0", "signale": "^1.4.0",
"web3": "^1.2.4", "web3": "^1.2.4",
"winston": "^3.0.0" "winston": "^3.0.0"

@ -1,10 +1,10 @@
import fs from './fileSystem' import fs from './fileSystem'
import async from 'async' import async from 'async'
import path from 'path' import path from 'path'
let RemixCompiler = require('remix-solidity').Compiler const RemixCompiler = require('@remix-project/remix-solidity').Compiler
import { SrcIfc, CompilerConfiguration, CompilationErrors } from './types' import { SrcIfc, CompilerConfiguration, CompilationErrors } from './types'
function regexIndexOf (inputString: string, regex: RegExp, startpos: number = 0) { function regexIndexOf (inputString: string, regex: RegExp, startpos = 0) {
const indexOf = inputString.substring(startpos).search(regex) const indexOf = inputString.substring(startpos).search(regex)
return (indexOf >= 0) ? (indexOf + (startpos)) : indexOf return (indexOf >= 0) ? (indexOf + (startpos)) : indexOf
} }
@ -41,8 +41,8 @@ function isRemixTestFile(path: string) {
* @param isRoot True, If file is a root test contract file which is getting processed, not an imported file * @param isRoot True, If file is a root test contract file which is getting processed, not an imported file
*/ */
function processFile(filePath: string, sources: SrcIfc, isRoot: boolean = false) { function processFile(filePath: string, sources: SrcIfc, isRoot = false) {
const importRegEx: RegExp = /import ['"](.+?)['"];/g; const importRegEx = /import ['"](.+?)['"];/g;
let group: RegExpExecArray| null = null; let group: RegExpExecArray| null = null;
const isFileAlreadyInSources: boolean = Object.keys(sources).includes(filePath) const isFileAlreadyInSources: boolean = Object.keys(sources).includes(filePath)
@ -51,18 +51,18 @@ function processFile(filePath: string, sources: SrcIfc, isRoot: boolean = false)
return return
let content: string = fs.readFileSync(filePath, { encoding: 'utf-8' }); let content: string = fs.readFileSync(filePath, { encoding: 'utf-8' });
const testFileImportRegEx: RegExp = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm const testFileImportRegEx = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm
// import 'remix_tests.sol', if file is a root test contract file and doesn't already have it // import 'remix_tests.sol', if file is a root test contract file and doesn't already have it
if (isRoot && filePath.endsWith('_test.sol') && regexIndexOf(content, testFileImportRegEx) < 0) { if (isRoot && filePath.endsWith('_test.sol') && regexIndexOf(content, testFileImportRegEx) < 0) {
const includeTestLibs: string = '\nimport \'remix_tests.sol\';\n' const includeTestLibs = '\nimport \'remix_tests.sol\';\n'
content = includeTestLibs.concat(content) content = includeTestLibs.concat(content)
} }
sources[filePath] = {content}; sources[filePath] = {content};
importRegEx.exec(''); // Resetting state of RegEx importRegEx.exec(''); // Resetting state of RegEx
// Process each 'import' in file content // Process each 'import' in file content
while (group = importRegEx.exec(content)) { while ((group = importRegEx.exec(content))) {
const importedFile: string = group[1]; const importedFile: string = group[1];
const importedFilePath: string = path.join(path.dirname(filePath), importedFile); const importedFilePath: string = path.join(path.dirname(filePath), importedFile);
processFile(importedFilePath, sources) processFile(importedFilePath, sources)
@ -82,7 +82,7 @@ const isBrowser = !(typeof (window) === 'undefined' || userAgent.indexOf(' elect
* TODO: replace this with remix's own compiler code * TODO: replace this with remix's own compiler code
*/ */
export function compileFileOrFiles(filename: string, isDirectory: boolean, opts: any, cb: Function) { export function compileFileOrFiles(filename: string, isDirectory: boolean, opts: any, cb): void {
let compiler: any let compiler: any
const accounts: string[] = opts.accounts || [] const accounts: string[] = opts.accounts || []
const sources: SrcIfc = { const sources: SrcIfc = {
@ -108,18 +108,18 @@ export function compileFileOrFiles(filename: string, isDirectory: boolean, opts:
}) })
} }
} catch (e) { } catch (e) { // eslint-disable-line no-useless-catch
throw e throw e
} finally { } finally {
async.waterfall([ async.waterfall([
function loadCompiler(next: Function) { function loadCompiler(next) {
compiler = new RemixCompiler() compiler = new RemixCompiler()
compiler.onInternalCompilerLoaded() compiler.onInternalCompilerLoaded()
// compiler.event.register('compilerLoaded', this, function (version) { // compiler.event.register('compilerLoaded', this, function (version) {
next() next()
// }); // });
}, },
function doCompilation(next: Function) { function doCompilation(next) {
// @ts-ignore // @ts-ignore
compiler.event.register('compilationFinished', this, (success, data, source) => { compiler.event.register('compilationFinished', this, (success, data, source) => {
next(null, data) next(null, data)
@ -127,9 +127,9 @@ export function compileFileOrFiles(filename: string, isDirectory: boolean, opts:
compiler.compile(sources, filepath) compiler.compile(sources, filepath)
} }
], function (err: Error | null | undefined, result: any) { ], function (err: Error | null | undefined, result: any) {
let error: Error[] = [] const error: Error[] = []
if (result.error) error.push(result.error) if (result.error) error.push(result.error)
let errors = (result.errors || error).filter((e) => e.type === 'Error' || e.severity === 'error') const errors = (result.errors || error).filter((e) => e.type === 'Error' || e.severity === 'error')
if (errors.length > 0) { if (errors.length > 0) {
if (!isBrowser) require('signale').fatal(errors) if (!isBrowser) require('signale').fatal(errors)
return cb(new CompilationErrors(errors)) return cb(new CompilationErrors(errors))
@ -147,7 +147,7 @@ export function compileFileOrFiles(filename: string, isDirectory: boolean, opts:
* @param opts Options * @param opts Options
* @param cb Callback * @param cb Callback
*/ */
export function compileContractSources(sources: SrcIfc, compilerConfig: CompilerConfiguration, importFileCb: any, opts: any, cb: Function) { export function compileContractSources(sources: SrcIfc, compilerConfig: CompilerConfiguration, importFileCb: any, opts: any, cb): void {
let compiler, filepath: string let compiler, filepath: string
const accounts: string[] = opts.accounts || [] const accounts: string[] = opts.accounts || []
// Iterate over sources keys. Inject test libraries. Inject test library import statements. // Iterate over sources keys. Inject test libraries. Inject test library import statements.
@ -156,10 +156,10 @@ export function compileContractSources(sources: SrcIfc, compilerConfig: Compiler
sources['remix_tests.sol'] = { content: require('../sol/tests.sol.js') } sources['remix_tests.sol'] = { content: require('../sol/tests.sol.js') }
sources['remix_accounts.sol'] = { content: writeTestAccountsContract(accounts) } sources['remix_accounts.sol'] = { content: writeTestAccountsContract(accounts) }
} }
const testFileImportRegEx: RegExp = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm const testFileImportRegEx = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm
let includeTestLibs: string = '\nimport \'remix_tests.sol\';\n' const includeTestLibs = '\nimport \'remix_tests.sol\';\n'
for (let file in sources) { for (const file in sources) {
const c: string = sources[file].content const c: string = sources[file].content
if (file.endsWith('_test.sol') && c && regexIndexOf(c, testFileImportRegEx) < 0) { if (file.endsWith('_test.sol') && c && regexIndexOf(c, testFileImportRegEx) < 0) {
sources[file].content = includeTestLibs.concat(c) sources[file].content = includeTestLibs.concat(c)
@ -167,7 +167,7 @@ export function compileContractSources(sources: SrcIfc, compilerConfig: Compiler
} }
async.waterfall([ async.waterfall([
function loadCompiler (next: Function) { function loadCompiler (next) {
const {currentCompilerUrl, evmVersion, optimize, usingWorker} = compilerConfig const {currentCompilerUrl, evmVersion, optimize, usingWorker} = compilerConfig
compiler = new RemixCompiler(importFileCb) compiler = new RemixCompiler(importFileCb)
compiler.set('evmVersion', evmVersion) compiler.set('evmVersion', evmVersion)
@ -178,7 +178,7 @@ export function compileContractSources(sources: SrcIfc, compilerConfig: Compiler
next() next()
}) })
}, },
function doCompilation (next: Function) { function doCompilation (next) {
// @ts-ignore // @ts-ignore
compiler.event.register('compilationFinished', this, (success, data, source) => { compiler.event.register('compilationFinished', this, (success, data, source) => {
next(null, data) next(null, data)
@ -186,9 +186,9 @@ export function compileContractSources(sources: SrcIfc, compilerConfig: Compiler
compiler.compile(sources, filepath) compiler.compile(sources, filepath)
} }
], function (err: Error | null | undefined , result: any) { ], function (err: Error | null | undefined , result: any) {
let error: Error[] = [] const error: Error[] = []
if (result.error) error.push(result.error) if (result.error) error.push(result.error)
let errors = (result.errors || error).filter((e) => e.type === 'Error' || e.severity === 'error') const errors = (result.errors || error).filter((e) => e.type === 'Error' || e.severity === 'error')
if (errors.length > 0) { if (errors.length > 0) {
if (!isBrowser) require('signale').fatal(errors) if (!isBrowser) require('signale').fatal(errors)
return cb(new CompilationErrors(errors)) return cb(new CompilationErrors(errors))

@ -1,5 +1,5 @@
import async from 'async' import async from 'async'
import { execution } from 'remix-lib' import { execution } from '@remix-project/remix-lib'
import Web3 from 'web3' import Web3 from 'web3'
import { compilationInterface } from 'types' import { compilationInterface } from 'types'
@ -12,27 +12,27 @@ import { compilationInterface } from 'types'
*/ */
export function deployAll(compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) { export function deployAll(compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) {
let compiledObject = {} const compiledObject = {}
let contracts = {} const contracts = {}
let accounts: string[] = [] let accounts: string[] = []
async.waterfall([ async.waterfall([
function getAccountList(next: Function) { function getAccountList(next) {
web3.eth.getAccounts((_err, _accounts) => { web3.eth.getAccounts((_err, _accounts) => {
accounts = _accounts accounts = _accounts
next() next()
}) })
}, },
function getContractData(next: Function) { function getContractData(next) {
for (let contractFile in compileResult) { for (const contractFile in compileResult) {
for (let contractName in compileResult[contractFile]) { for (const contractName in compileResult[contractFile]) {
let contract = compileResult[contractFile][contractName] const contract = compileResult[contractFile][contractName]
const className = contractName const className = contractName
const filename = contractFile const filename = contractFile
let abi = contract.abi const abi = contract.abi
let code = contract.evm.bytecode.object const code = contract.evm.bytecode.object
compiledObject[className] = {} compiledObject[className] = {}
compiledObject[className].abi = abi compiledObject[className].abi = abi
@ -48,11 +48,11 @@ export function deployAll(compileResult: compilationInterface, web3: Web3, withD
} }
next() next()
}, },
function determineContractsToDeploy(next: Function) { function determineContractsToDeploy(next) {
let contractsToDeploy: string[] = ['Assert'] const contractsToDeploy: string[] = ['Assert']
let allContracts = Object.keys(compiledObject) const allContracts = Object.keys(compiledObject)
for (let contractName of allContracts) { for (const contractName of allContracts) {
if (contractName === 'Assert') { if (contractName === 'Assert') {
continue continue
} }
@ -62,7 +62,7 @@ export function deployAll(compileResult: compilationInterface, web3: Web3, withD
} }
next(null, contractsToDeploy) next(null, contractsToDeploy)
}, },
function deployContracts(contractsToDeploy: string[], next: Function) { function deployContracts(contractsToDeploy: string[], next) {
const deployRunner = (deployObject, contractObject, contractName, filename, callback) => { const deployRunner = (deployObject, contractObject, contractName, filename, callback) => {
deployObject.estimateGas().then((gasValue) => { deployObject.estimateGas().then((gasValue) => {
const gasBase = Math.ceil(gasValue * 1.2) const gasBase = Math.ceil(gasValue * 1.2)
@ -88,30 +88,26 @@ export function deployAll(compileResult: compilationInterface, web3: Web3, withD
} }
async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) { async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) {
let contract = compiledObject[contractName] const contract = compiledObject[contractName]
let encodeDataFinalCallback = (error, contractDeployData) => { const encodeDataFinalCallback = (error, contractDeployData) => {
if (error) return nextEach(error) if (error) return nextEach(error)
try { const contractObject = new web3.eth.Contract(contract.abi)
let contractObject = new web3.eth.Contract(contract.abi) const deployObject = contractObject.deploy({arguments: [], data: '0x' + contractDeployData.dataHex})
let deployObject = contractObject.deploy({arguments: [], data: '0x' + contractDeployData.dataHex})
deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) }) deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) })
} catch (e) {
throw e
}
} }
let encodeDataStepCallback = (msg) => { console.dir(msg) } const encodeDataStepCallback = (msg) => { console.dir(msg) }
let encodeDataDeployLibraryCallback = (libData, callback) => { const encodeDataDeployLibraryCallback = (libData, callback) => {
let abi = compiledObject[libData.data.contractName].abi const abi = compiledObject[libData.data.contractName].abi
let code = compiledObject[libData.data.contractName].code const code = compiledObject[libData.data.contractName].code
let libraryObject = new web3.eth.Contract(abi) const libraryObject = new web3.eth.Contract(abi)
let deployObject = libraryObject.deploy({arguments: [], data: '0x' + code}) const deployObject = libraryObject.deploy({arguments: [], data: '0x' + code})
deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback) deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback)
} }
let funAbi = null // no need to set the abi for encoding the constructor const funAbi = null // no need to set the abi for encoding the constructor
let params = '' // we suppose that the test contract does not have any param in the constructor const params = '' // we suppose that the test contract does not have any param in the constructor
execution.txFormat.encodeConstructorCallAndDeployLibraries(contractName, contract.raw, compileResult, params, funAbi, encodeDataFinalCallback, encodeDataStepCallback, encodeDataDeployLibraryCallback) execution.txFormat.encodeConstructorCallAndDeployLibraries(contractName, contract.raw, compileResult, params, funAbi, encodeDataFinalCallback, encodeDataStepCallback, encodeDataDeployLibraryCallback)
}, function (err) { }, function (err) {
if(err) next(err) if(err) next(err)

@ -1,9 +1,9 @@
// Extend fs // Extend fs
let fs: any = require('fs') const fs: any = require('fs')
import path from 'path' import path from 'path'
// https://github.com/mikeal/node-utils/blob/master/file/lib/main.js // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js
fs.walkSync = function (start: string, callback: Function) { fs.walkSync = function (start: string, callback) {
fs.readdirSync(start).forEach((name: string) => { fs.readdirSync(start).forEach((name: string) => {
if (name === 'node_modules') { if (name === 'node_modules') {
return // hack return // hack

@ -42,7 +42,7 @@ class Log {
) )
}) })
} }
setVerbosity (v: LoggerOptions["level"]) { setVerbosity (v: LoggerOptions["level"]): void {
this.logger.configure({ this.logger.configure({
level: v, level: v,
transports: [new winston.transports.Console()], transports: [new winston.transports.Console()],

@ -2,7 +2,7 @@ import commander from 'commander'
import Web3 from 'web3'; import Web3 from 'web3';
import { runTestFiles } from './runTestFiles' import { runTestFiles } from './runTestFiles'
import fs from './fileSystem' import fs from './fileSystem'
import { Provider } from 'remix-simulator' import { Provider } from '@remix-project/remix-simulator'
import Log from './logger' import Log from './logger'
const logger = new Log() const logger = new Log()
const log = logger.logger const log = logger.logger
@ -47,7 +47,7 @@ commander
logger.setVerbosity(commander.verbose) logger.setVerbosity(commander.verbose)
log.info('verbosity level set to ' + commander.verbose.blue) log.info('verbosity level set to ' + commander.verbose.blue)
} }
let web3 = new Web3() const web3 = new Web3()
const provider = new Provider() const provider = new Provider()
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
@ -57,7 +57,7 @@ commander
process.exit(1) process.exit(1)
} }
let isDirectory = fs.lstatSync(filename).isDirectory() const isDirectory = fs.lstatSync(filename).isDirectory()
runTestFiles(filename, isDirectory, web3) runTestFiles(filename, isDirectory, web3)
}) })

@ -17,7 +17,7 @@ import { deployAll } from './deployer'
* @param opts Options * @param opts Options
*/ */
export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, finalCallback: any = () => {}, opts?: Options) { export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3, finalCallback, opts?: Options) {
opts = opts || {} opts = opts || {}
const sourceASTs: any = {} const sourceASTs: any = {}
const { Signale } = require('signale') const { Signale } = require('signale')
@ -44,17 +44,17 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3,
const signale = new Signale(options) const signale = new Signale(options)
let accounts = opts['accounts'] || null let accounts = opts['accounts'] || null
async.waterfall([ async.waterfall([
function getAccountList (next: Function) { function getAccountList (next) {
if (accounts) return next(null) if (accounts) return next(null)
web3.eth.getAccounts((_err: Error | null | undefined, _accounts) => { web3.eth.getAccounts((_err: Error | null | undefined, _accounts) => {
accounts = _accounts accounts = _accounts
next(null) next(null)
}) })
}, },
function compile(next: Function) { function compile(next) {
compileFileOrFiles(filepath, isDirectory, { accounts }, next) compileFileOrFiles(filepath, isDirectory, { accounts }, next)
}, },
function deployAllContracts (compilationResult: compilationInterface, asts: ASTInterface, next: Function) { function deployAllContracts (compilationResult: compilationInterface, asts: ASTInterface, next) {
// Extract AST of test contract file source // Extract AST of test contract file source
for(const filename in asts) { for(const filename in asts) {
if(filename.endsWith('_test.sol')) if(filename.endsWith('_test.sol'))
@ -67,9 +67,9 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3,
next(null, compilationResult, contracts) next(null, compilationResult, contracts)
}) })
}, },
function determineTestContractsToRun (compilationResult: compilationInterface, contracts: any, next: Function) { function determineTestContractsToRun (compilationResult: compilationInterface, contracts: any, next) {
let contractsToTest: string[] = [] const contractsToTest: string[] = []
let contractsToTestDetails: any[] = [] const contractsToTestDetails: any[] = []
const gatherContractsFrom = function(filename: string) { const gatherContractsFrom = function(filename: string) {
if (!filename.endsWith('_test.sol')) { if (!filename.endsWith('_test.sol')) {
return return
@ -92,11 +92,11 @@ export function runTestFiles(filepath: string, isDirectory: boolean, web3: Web3,
} }
next(null, contractsToTest, contractsToTestDetails, contracts) next(null, contractsToTest, contractsToTestDetails, contracts)
}, },
function runTests(contractsToTest: string[], contractsToTestDetails: any[], contracts: any, next: Function) { function runTests(contractsToTest: string[], contractsToTestDetails: any[], contracts: any, next) {
let totalPassing: number = 0 let totalPassing = 0
let totalFailing: number = 0 let totalFailing = 0
let totalTime: number = 0 let totalTime = 0
let errors: any[] = [] const errors: any[] = []
const _testCallback = function (err: Error | null | undefined, result: TestResultInterface) { const _testCallback = function (err: Error | null | undefined, result: TestResultInterface) {
if(err) throw err; if(err) throw err;

@ -6,13 +6,13 @@ import { deployAll } from './deployer'
import { runTest } from './testRunner' import { runTest } from './testRunner'
import Web3 from 'web3'; import Web3 from 'web3';
import { Provider } from 'remix-simulator' import { Provider } from '@remix-project/remix-simulator'
import { FinalResult, SrcIfc, compilationInterface, ASTInterface, Options, import { FinalResult, SrcIfc, compilationInterface, ASTInterface, Options,
TestResultInterface, AstNode, CompilerConfiguration } from './types' TestResultInterface, AstNode, CompilerConfiguration } from './types'
const createWeb3Provider = async function () { const createWeb3Provider = async function () {
let web3 = new Web3() const web3 = new Web3()
let provider = new Provider() const provider = new Provider()
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
return web3 return web3
@ -28,10 +28,10 @@ const createWeb3Provider = async function () {
* @param importFileCb Import file callback * @param importFileCb Import file callback
* @param opts Options * @param opts Options
*/ */
export async function runTestSources(contractSources: SrcIfc, compilerConfig: CompilerConfiguration, testCallback: Function, resultCallback: Function, finalCallback: any, importFileCb: Function, opts: Options) { export async function runTestSources(contractSources: SrcIfc, compilerConfig: CompilerConfiguration, testCallback, resultCallback, finalCallback: any, importFileCb, opts: Options) {
opts = opts || {} opts = opts || {}
const sourceASTs: any = {} const sourceASTs: any = {}
let web3 = opts.web3 || await createWeb3Provider() const web3 = opts.web3 || await createWeb3Provider()
let accounts: string[] | null = opts.accounts || null let accounts: string[] | null = opts.accounts || null
async.waterfall([ async.waterfall([
function getAccountList (next) { function getAccountList (next) {
@ -66,10 +66,10 @@ export async function runTestSources(contractSources: SrcIfc, compilerConfig: Co
}) })
}, },
function determineTestContractsToRun (compilationResult: compilationInterface, contracts: any, next) { function determineTestContractsToRun (compilationResult: compilationInterface, contracts: any, next) {
let contractsToTest: string[] = [] const contractsToTest: string[] = []
let contractsToTestDetails: any[] = [] const contractsToTestDetails: any[] = []
for (let filename in compilationResult) { for (const filename in compilationResult) {
if (!filename.endsWith('_test.sol')) { if (!filename.endsWith('_test.sol')) {
continue continue
} }
@ -84,7 +84,7 @@ export async function runTestSources(contractSources: SrcIfc, compilerConfig: Co
let totalPassing = 0 let totalPassing = 0
let totalFailing = 0 let totalFailing = 0
let totalTime = 0 let totalTime = 0
let errors: any[] = [] const errors: any[] = []
const _testCallback = function (err: Error | null | undefined, result: TestResultInterface) { const _testCallback = function (err: Error | null | undefined, result: TestResultInterface) {
if (result.type === 'testFailure') { if (result.type === 'testFailure') {
@ -94,7 +94,7 @@ export async function runTestSources(contractSources: SrcIfc, compilerConfig: Co
} }
const _resultsCallback = function (_err, result, cb) { const _resultsCallback = function (_err, result, cb) {
resultCallback(_err, result, () => {}) resultCallback(_err, result, () => {}) //eslint-disable-line @typescript-eslint/no-empty-function
totalPassing += result.passingNum totalPassing += result.passingNum
totalFailing += result.failureNum totalFailing += result.failureNum
totalTime += result.timePassed totalTime += result.timePassed
@ -114,7 +114,7 @@ export async function runTestSources(contractSources: SrcIfc, compilerConfig: Co
return next(err) return next(err)
} }
let finalResults: FinalResult = { const finalResults: FinalResult = {
totalPassing: 0, totalPassing: 0,
totalFailing: 0, totalFailing: 0,
totalTime: 0, totalTime: 0,

@ -46,7 +46,7 @@ function isPayable(funcABI: FunctionDescription): boolean {
function getOverridedSender (userdoc: UserDocumentation, signature: string, methodIdentifiers: Record <string, string>): string | null { function getOverridedSender (userdoc: UserDocumentation, signature: string, methodIdentifiers: Record <string, string>): string | null {
const fullName: string | null = getFunctionFullName(signature, methodIdentifiers) const fullName: string | null = getFunctionFullName(signature, methodIdentifiers)
const senderRegex: RegExp = /#sender: account-+(\d)/g const senderRegex = /#sender: account-+(\d)/g
const accountIndex: RegExpExecArray | null = fullName && userdoc.methods[fullName] ? senderRegex.exec(userdoc.methods[fullName].notice) : null const accountIndex: RegExpExecArray | null = fullName && userdoc.methods[fullName] ? senderRegex.exec(userdoc.methods[fullName].notice) : null
return fullName && accountIndex ? accountIndex[1] : null return fullName && accountIndex ? accountIndex[1] : null
} }
@ -60,7 +60,7 @@ function getOverridedSender (userdoc: UserDocumentation, signature: string, meth
function getProvidedValue (userdoc: UserDocumentation, signature: string, methodIdentifiers: Record <string, string>): string | null { function getProvidedValue (userdoc: UserDocumentation, signature: string, methodIdentifiers: Record <string, string>): string | null {
const fullName: string | null = getFunctionFullName(signature, methodIdentifiers) const fullName: string | null = getFunctionFullName(signature, methodIdentifiers)
const valueRegex: RegExp = /#value: (\d+)/g const valueRegex = /#value: (\d+)/g
const value: RegExpExecArray | null = fullName && userdoc.methods[fullName] ? valueRegex.exec(userdoc.methods[fullName].notice) : null const value: RegExpExecArray | null = fullName && userdoc.methods[fullName] ? valueRegex.exec(userdoc.methods[fullName].notice) : null
return fullName && value ? value[1] : null return fullName && value ? value[1] : null
} }
@ -129,27 +129,27 @@ function createRunList (jsonInterface: FunctionDescription[], fileAST: AstNode,
const availableFunctions: string[] = getAvailableFunctions(fileAST, testContractName) const availableFunctions: string[] = getAvailableFunctions(fileAST, testContractName)
const testFunctionsInterface: FunctionDescription[] = getTestFunctionsInterface(jsonInterface, availableFunctions) const testFunctionsInterface: FunctionDescription[] = getTestFunctionsInterface(jsonInterface, availableFunctions)
const specialFunctionsInterface: Record<string, FunctionDescription> = getSpecialFunctionsInterface(jsonInterface) const specialFunctionsInterface: Record<string, FunctionDescription> = getSpecialFunctionsInterface(jsonInterface)
let runList: RunListInterface[] = [] const runList: RunListInterface[] = []
if (availableFunctions.includes('beforeAll')) { if (availableFunctions.includes('beforeAll')) {
let func = specialFunctionsInterface['beforeAll'] const func = specialFunctionsInterface['beforeAll']
runList.push({ name: 'beforeAll', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) }) runList.push({ name: 'beforeAll', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) })
} }
for (const func of testFunctionsInterface) { for (const func of testFunctionsInterface) {
if (availableFunctions.includes('beforeEach')) { if (availableFunctions.includes('beforeEach')) {
let func = specialFunctionsInterface['beforeEach'] const func = specialFunctionsInterface['beforeEach']
runList.push({ name: 'beforeEach', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) }) runList.push({ name: 'beforeEach', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) })
} }
if(func.name && func.inputs) runList.push({ name: func.name, inputs: func.inputs, signature: func.signature, type: 'test', constant: isConstant(func), payable: isPayable(func) }) if(func.name && func.inputs) runList.push({ name: func.name, inputs: func.inputs, signature: func.signature, type: 'test', constant: isConstant(func), payable: isPayable(func) })
if (availableFunctions.indexOf('afterEach') >= 0) { if (availableFunctions.indexOf('afterEach') >= 0) {
let func = specialFunctionsInterface['afterEach'] const func = specialFunctionsInterface['afterEach']
runList.push({ name: 'afterEach', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) }) runList.push({ name: 'afterEach', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) })
} }
} }
if (availableFunctions.indexOf('afterAll') >= 0) { if (availableFunctions.indexOf('afterAll') >= 0) {
let func = specialFunctionsInterface['afterAll'] const func = specialFunctionsInterface['afterAll']
runList.push({ name: 'afterAll', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) }) runList.push({ name: 'afterAll', inputs: func.inputs, signature: func.signature, type: 'internal', constant: isConstant(func), payable: isPayable(func) })
} }
@ -157,9 +157,9 @@ function createRunList (jsonInterface: FunctionDescription[], fileAST: AstNode,
} }
export function runTest (testName: string, testObject: any, contractDetails: CompiledContract, fileAST: AstNode, opts: Options, testCallback: TestCbInterface, resultsCallback: ResultCbInterface): void { export function runTest (testName: string, testObject: any, contractDetails: CompiledContract, fileAST: AstNode, opts: Options, testCallback: TestCbInterface, resultsCallback: ResultCbInterface): void {
let passingNum: number = 0 let passingNum = 0
let failureNum: number = 0 let failureNum = 0
let timePassed: number = 0 let timePassed = 0
const isJSONInterfaceAvailable = testObject && testObject.options && testObject.options.jsonInterface const isJSONInterfaceAvailable = testObject && testObject.options && testObject.options.jsonInterface
if(!isJSONInterfaceAvailable) if(!isJSONInterfaceAvailable)
return resultsCallback(new Error('Contract interface not available'), { passingNum, failureNum, timePassed }) return resultsCallback(new Error('Contract interface not available'), { passingNum, failureNum, timePassed })
@ -229,7 +229,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
try { try {
const time: number = (Date.now() - startTime) / 1000.0 const time: number = (Date.now() - startTime) / 1000.0
const topic = Web3.utils.sha3('AssertionEvent(bool,string)') const topic = Web3.utils.sha3('AssertionEvent(bool,string)')
let testPassed: boolean = false let testPassed = false
for (const i in receipt.events) { for (const i in receipt.events) {
const event = receipt.events[i] const event = receipt.events[i]

@ -59,7 +59,7 @@ export interface CompilationErrors {
} }
export class CompilationErrors extends Error { export class CompilationErrors extends Error {
constructor(errors) { constructor(errors: Array<any>) {
const mapError = errors.map((e) => { return e.formattedMessage || e.message }) const mapError = errors.map((e) => { return e.formattedMessage || e.message })
super(mapError.join('\n')) super(mapError.join('\n'))
this.errors = errors this.errors = errors
@ -97,7 +97,7 @@ export interface AstNodeAtt {
constant?: boolean constant?: boolean
name?: string name?: string
public?: boolean public?: boolean
exportedSymbols?: Object exportedSymbols?: Record<string, unknown>
argumentTypes?: null argumentTypes?: null
absolutePath?: string absolutePath?: string
[x: string]: any [x: string]: any
@ -105,7 +105,7 @@ export interface AstNodeAtt {
export interface AstNode { export interface AstNode {
absolutePath?: string absolutePath?: string
exportedSymbols?: Object exportedSymbols?: Record<string, unknown>
id: number id: number
nodeType: string nodeType: string
nodes?: Array<AstNode> nodes?: Array<AstNode>
@ -142,7 +142,7 @@ export interface CompiledContract {
/** EVM-related outputs */ /** EVM-related outputs */
evm: { evm: {
assembly: string assembly: string
legacyAssembly: {} legacyAssembly: Record<string, unknown>
/** Bytecode and related details. */ /** Bytecode and related details. */
bytecode: BytecodeObject bytecode: BytecodeObject
deployedBytecode: BytecodeObject deployedBytecode: BytecodeObject

@ -2,12 +2,12 @@ import 'mocha'
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-simulator' import { Provider } from '@remix-project/remix-simulator'
import { compileFileOrFiles } from '../dist/compiler' import { compileFileOrFiles } from '../src/compiler'
import { deployAll } from '../dist/deployer' import { deployAll } from '../src/deployer'
import { runTest, compilationInterface } from '../dist/index' import { runTest, compilationInterface } from '../src/index'
import { ResultsInterface, TestCbInterface, ResultCbInterface } from '../dist/index' import { ResultsInterface, TestCbInterface, ResultCbInterface } from '../src/index'
// deepEqualExcluding allows us to exclude specific keys whose values vary. // deepEqualExcluding allows us to exclude specific keys whose values vary.
// In this specific test, we'll use this helper to exclude `time` keys. // In this specific test, we'll use this helper to exclude `time` keys.

@ -1,24 +1,7 @@
{ {
"include": ["src"], "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "types": ["node"]
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ },
"lib": ["dom", "es2018"], /* Specify library files to be included in the compilation. */ "include": ["**/*.ts"]
"declaration": true, /* Generates corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
/* Module Resolution Options */
"baseUrl": "./src", /* Base directory to resolve non-absolute module names. */
"paths": { "remix-tests": ["./"] }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"typeRoots": [
"./@types",
"./node_modules/@types"
],
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
}
} }

@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"declaration": true,
"rootDir": "./src",
"types": ["node"]
},
"exclude": [
"**/*.spec.ts"
],
"include": ["**/*.ts"]
}

@ -314,23 +314,20 @@
"schematics": {}, "schematics": {},
"architect": { "architect": {
"lint": { "lint": {
"builder": "@nrwl/workspace:run-commands", "builder": "@nrwl/linter:lint",
"options": { "options": {
"commands": [ "linter": "eslint",
{ "config": "libs/remix-tests/.eslintrc",
"command": "./../../node_modules/.bin/npm-run-all lint" "tsConfig": [
} "libs/remix-tests/tsconfig.lib.json"
], ],
"cwd": "libs/remix-tests" "exclude": ["**/node_modules/**", "libs/remix-tests/tests/**/*"]
} }
}, },
"test": { "test": {
"builder": "@nrwl/workspace:run-commands", "builder": "@nrwl/workspace:run-commands",
"options": { "options": {
"commands": [ "commands": [
{
"command": "rm -rf ../../dist"
},
{ {
"command": "./../../node_modules/.bin/npm-run-all test" "command": "./../../node_modules/.bin/npm-run-all test"
} }
@ -339,17 +336,13 @@
} }
}, },
"build": { "build": {
"builder": "@nrwl/workspace:run-commands", "builder": "@nrwl/node:package",
"options": { "options": {
"commands": [ "outputPath": "dist/libs/remix-tests",
{ "tsConfig": "libs/remix-tests/tsconfig.lib.json",
"command": "rm -rf ../../dist" "packageJson": "libs/remix-tests/package.json",
}, "main": "libs/remix-tests/src/index.ts",
{ "assets": ["libs/remix-tests/*.md"]
"command": "./../../node_modules/.bin/npm-run-all build"
}
],
"cwd": "libs/remix-tests"
} }
} }
} }

Loading…
Cancel
Save