Commit 28773548 authored by aniket-engg's avatar aniket-engg

linting for remix-tests fixed

parent 84d0bac2
{ {
"extends": "../../.eslintrc", "extends": "../../.eslintrc",
"rules": { "rules": {
"@typescript-eslint/no-explicit-any": "off", "dot-notation": "off",
"@typescript-eslint/no-var-requires": "off", "no-unused-vars": "off"
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-ts-comment": "off"
}, },
"env": { "env": {
"browser": true, "browser": true,
......
const assertionEvents = [ const assertionEvents = [
{ {
name: 'AssertionEvent', name: 'AssertionEvent',
params: ['bool', 'string', 'string'] params: ['bool', 'string', 'string']
}, },
{ {
name: 'AssertionEventUint', name: 'AssertionEventUint',
params: ['bool', 'string', 'string', 'uint256', 'uint256'] params: ['bool', 'string', 'string', 'uint256', 'uint256']
}, },
{ {
name: 'AssertionEventInt', name: 'AssertionEventInt',
params: ['bool', 'string', 'string', 'int256', 'int256'] params: ['bool', 'string', 'string', 'int256', 'int256']
}, },
{ {
name: 'AssertionEventBool', name: 'AssertionEventBool',
params: ['bool', 'string', 'string', 'bool', 'bool'] params: ['bool', 'string', 'string', 'bool', 'bool']
}, },
{ {
name: 'AssertionEventAddress', name: 'AssertionEventAddress',
params: ['bool', 'string', 'string', 'address', 'address'] params: ['bool', 'string', 'string', 'address', 'address']
}, },
{ {
name: 'AssertionEventBytes32', name: 'AssertionEventBytes32',
params: ['bool', 'string', 'string', 'bytes32', 'bytes32'] params: ['bool', 'string', 'string', 'bytes32', 'bytes32']
}, },
{ {
name: 'AssertionEventString', name: 'AssertionEventString',
params: ['bool', 'string', 'string', 'string', 'string'] params: ['bool', 'string', 'string', 'string', 'string']
}, },
{ {
name: 'AssertionEventUintInt', name: 'AssertionEventUintInt',
params: ['bool', 'string', 'string', 'uint256', 'int256'] params: ['bool', 'string', 'string', 'uint256', 'int256']
}, },
{ {
name: 'AssertionEventIntUint', name: 'AssertionEventIntUint',
params: ['bool', 'string', 'string', 'int256', 'uint256'] params: ['bool', 'string', 'string', 'int256', 'uint256']
} }
] ]
export default assertionEvents export default assertionEvents
\ No newline at end of file
This diff is collapsed.
...@@ -11,108 +11,108 @@ import { compilationInterface } from './types' ...@@ -11,108 +11,108 @@ import { compilationInterface } from './types'
* @param callback Callback * @param callback Callback
*/ */
export function deployAll(compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) { export function deployAll (compileResult: compilationInterface, web3: Web3, withDoubleGas: boolean, callback) {
const compiledObject = {} const compiledObject = {}
const contracts = {} const contracts = {}
let accounts: string[] = [] let accounts: string[] = []
async.waterfall([ async.waterfall([
function getAccountList(next) { function getAccountList (next) {
web3.eth.getAccounts((_err, _accounts) => { web3.eth.getAccounts((_err, _accounts) => {
accounts = _accounts accounts = _accounts
next() next()
}) })
}, },
function getContractData(next) { function getContractData (next) {
for (const contractFile in compileResult) { for (const contractFile in compileResult) {
for (const contractName in compileResult[contractFile]) { for (const contractName in compileResult[contractFile]) {
const contract = compileResult[contractFile][contractName] const contract = compileResult[contractFile][contractName]
const className = contractName const className = contractName
const filename = contractFile const filename = contractFile
const abi = contract.abi const abi = contract.abi
const code = contract.evm.bytecode.object const code = contract.evm.bytecode.object
compiledObject[className] = {} compiledObject[className] = {}
compiledObject[className].abi = abi compiledObject[className].abi = abi
compiledObject[className].code = code compiledObject[className].code = code
compiledObject[className].filename = filename compiledObject[className].filename = filename
compiledObject[className].className = className compiledObject[className].className = className
compiledObject[className].raw = contract compiledObject[className].raw = contract
if (contractFile.endsWith('_test.sol')) { if (contractFile.endsWith('_test.sol')) {
compiledObject[className].isTest = true compiledObject[className].isTest = true
} }
} }
} }
next() next()
}, },
function determineContractsToDeploy(next) { function determineContractsToDeploy (next) {
const contractsToDeploy: string[] = ['Assert'] const contractsToDeploy: string[] = ['Assert']
const allContracts = Object.keys(compiledObject) const allContracts = Object.keys(compiledObject)
for (const contractName of allContracts) {
if (contractName === 'Assert') {
continue
}
if (compiledObject[contractName].isTest) {
contractsToDeploy.push(contractName)
}
}
next(null, contractsToDeploy)
},
function deployContracts(contractsToDeploy: string[], next) {
const deployRunner = (deployObject, contractObject, contractName, filename, callback) => {
deployObject.estimateGas().then((gasValue) => {
const gasBase = Math.ceil(gasValue * 1.2)
const gas = withDoubleGas ? gasBase * 2 : gasBase
deployObject.send({
from: accounts[0],
gas: gas
}).on('receipt', function (receipt) {
contractObject.options.address = receipt.contractAddress
contractObject.options.from = accounts[0]
contractObject.options.gas = 5000 * 1000
compiledObject[contractName].deployedAddress = receipt.contractAddress
contracts[contractName] = contractObject for (const contractName of allContracts) {
contracts[contractName].filename = filename if (contractName === 'Assert') {
continue
}
if (compiledObject[contractName].isTest) {
contractsToDeploy.push(contractName)
}
}
next(null, contractsToDeploy)
},
function deployContracts (contractsToDeploy: string[], next) {
const deployRunner = (deployObject, contractObject, contractName, filename, callback) => {
deployObject.estimateGas().then((gasValue) => {
const gasBase = Math.ceil(gasValue * 1.2)
const gas = withDoubleGas ? gasBase * 2 : gasBase
deployObject.send({
from: accounts[0],
gas: gas
}).on('receipt', function (receipt) {
contractObject.options.address = receipt.contractAddress
contractObject.options.from = accounts[0]
contractObject.options.gas = 5000 * 1000
compiledObject[contractName].deployedAddress = receipt.contractAddress
callback(null, { result: { createdAddress: receipt.contractAddress } }) // TODO this will only work with JavaScriptV VM contracts[contractName] = contractObject
}).on('error', function (err) { contracts[contractName].filename = filename
console.error(err)
callback(err)
})
})
}
async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) { callback(null, { result: { createdAddress: receipt.contractAddress } }) // TODO this will only work with JavaScriptV VM
const contract = compiledObject[contractName] }).on('error', function (err) {
const encodeDataFinalCallback = (error, contractDeployData) => { console.error(err)
if (error) return nextEach(error) callback(err)
const contractObject = new web3.eth.Contract(contract.abi) })
const deployObject = contractObject.deploy({arguments: [], data: '0x' + contractDeployData.dataHex}) })
deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) }) }
}
const encodeDataStepCallback = (msg) => { console.dir(msg) } async.eachOfLimit(contractsToDeploy, 1, function (contractName, index, nextEach) {
const contract = compiledObject[contractName]
const encodeDataFinalCallback = (error, contractDeployData) => {
if (error) return nextEach(error)
const contractObject = new web3.eth.Contract(contract.abi)
const deployObject = contractObject.deploy({ arguments: [], data: '0x' + contractDeployData.dataHex })
deployRunner(deployObject, contractObject, contractName, contract.filename, (error) => { nextEach(error) })
}
const encodeDataDeployLibraryCallback = (libData, callback) => { const encodeDataStepCallback = (msg) => { console.dir(msg) }
const abi = compiledObject[libData.data.contractName].abi
const code = compiledObject[libData.data.contractName].code
const libraryObject = new web3.eth.Contract(abi)
const deployObject = libraryObject.deploy({arguments: [], data: '0x' + code})
deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback)
}
const funAbi = null // no need to set the abi for encoding the constructor const encodeDataDeployLibraryCallback = (libData, callback) => {
const params = '' // we suppose that the test contract does not have any param in the constructor const abi = compiledObject[libData.data.contractName].abi
execution.txFormat.encodeConstructorCallAndDeployLibraries(contractName, contract.raw, compileResult, params, funAbi, encodeDataFinalCallback, encodeDataStepCallback, encodeDataDeployLibraryCallback) const code = compiledObject[libData.data.contractName].code
}, function (err) { const libraryObject = new web3.eth.Contract(abi)
if(err) next(err) const deployObject = libraryObject.deploy({ arguments: [], data: '0x' + code })
next(null, contracts) deployRunner(deployObject, libraryObject, libData.data.contractName, contract.filename, callback)
})
} }
], callback)
const funAbi = null // no need to set the abi for encoding 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)
}, function (err) {
if (err) next(err)
next(null, contracts)
})
}
], callback)
} }
// Extend fs // Extend fs
const fs: any = require('fs')
import path from 'path' import path from 'path'
const fs: any = require('fs')
// 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) { 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
} }
const abspath = path.join(start, name) const abspath = path.join(start, name)
if (fs.statSync(abspath).isDirectory()) { if (fs.statSync(abspath).isDirectory()) {
fs.walkSync(abspath, callback) fs.walkSync(abspath, callback)
} else { } else {
callback(abspath) callback(abspath)
} }
}) })
} }
export = fs export = fs
import colors from 'colors' import colors from 'colors'
import winston, { Logger, LoggerOptions } from 'winston' import winston, { Logger, LoggerOptions } from 'winston'
import timestamp from 'time-stamp'; import timestamp from 'time-stamp'
import supportsColor from 'color-support' import supportsColor from 'color-support'
function hasFlag (flag: string) { function hasFlag (flag: string) {
return ((typeof (process) !== 'undefined') && (process.argv.indexOf('--' + flag) !== -1)) return ((typeof (process) !== 'undefined') && (process.argv.indexOf('--' + flag) !== -1))
} }
function addColor (str: string) { function addColor (str: string) {
if (hasFlag('no-color')) { if (hasFlag('no-color')) {
return str return str
} }
if (hasFlag('color')) { if (hasFlag('color')) {
return colors.gray(str) return colors.gray(str)
} }
if (supportsColor()) { if (supportsColor()) {
return colors.gray(str) return colors.gray(str)
} }
return str return str
} }
function getTimestamp () { function getTimestamp () {
return '[' + addColor(timestamp('HH:mm:ss')) + ']' return '[' + addColor(timestamp('HH:mm:ss')) + ']'
} }
// create winston logger format // create winston logger format
const logFmt = winston.format.printf((info) => { const logFmt = winston.format.printf((info) => {
return `${getTimestamp()} ${info.level}: ${info.message}` return `${getTimestamp()} ${info.level}: ${info.message}`
}) })
class Log { class Log {
logger: Logger; logger: Logger;
constructor () { constructor () {
this.logger = winston.createLogger({ this.logger = winston.createLogger({
level: 'info', level: 'info',
transports: [new winston.transports.Console()], transports: [new winston.transports.Console()],
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize({ all: true }), winston.format.colorize({ all: true }),
logFmt logFmt
) )
}) })
} }
setVerbosity (v: LoggerOptions["level"]): void {
this.logger.configure({ setVerbosity (v: LoggerOptions['level']): void {
level: v, this.logger.configure({
transports: [new winston.transports.Console()], level: v,
format: winston.format.combine( transports: [new winston.transports.Console()],
winston.format.colorize({ all: true }), format: winston.format.combine(
logFmt winston.format.colorize({ all: true }),
) logFmt
}) )
})
} }
} }
......
...@@ -7,29 +7,29 @@ import fs from './fileSystem' ...@@ -7,29 +7,29 @@ import fs from './fileSystem'
import { Provider } from '@remix-project/remix-simulator' import { Provider } from '@remix-project/remix-simulator'
import { CompilerConfiguration } from './types' import { CompilerConfiguration } from './types'
import Log from './logger' import Log from './logger'
import colors from 'colors'
const logger = new Log() const logger = new Log()
const log = logger.logger const log = logger.logger
import colors from 'colors'
// parse verbosity // parse verbosity
function mapVerbosity (v: number) { function mapVerbosity (v: number) {
const levels = { const levels = {
0: 'error', 0: 'error',
1: 'warn', 1: 'warn',
2: 'info', 2: 'info',
3: 'verbose', 3: 'verbose',
4: 'debug', 4: 'debug',
5: 'silly' 5: 'silly'
} }
return levels[v] return levels[v]
} }
function mapOptimize (v: string) { function mapOptimize (v: string) {
const optimize = { const optimize = {
'true': true, true: true,
'false': false false: false
} }
return optimize[v]; return optimize[v]
} }
const version = require('../package.json').version const version = require('../package.json').version
...@@ -37,92 +37,91 @@ const version = require('../package.json').version ...@@ -37,92 +37,91 @@ const version = require('../package.json').version
commander.version(version) commander.version(version)
commander.command('version').description('output the version number').action(function () { commander.command('version').description('output the version number').action(function () {
console.log(version) console.log(version)
}) })
commander.command('help').description('output usage information').action(function () { commander.command('help').description('output usage information').action(function () {
commander.help() commander.help()
}) })
// get current version // get current version
commander commander
.option('-c, --compiler <string>', 'set compiler version (e.g: 0.6.1, 0.7.1 etc)') .option('-c, --compiler <string>', 'set compiler version (e.g: 0.6.1, 0.7.1 etc)')
.option('-e, --evm <string>', 'set EVM version (e.g: petersburg, istanbul etc)') .option('-e, --evm <string>', 'set EVM version (e.g: petersburg, istanbul etc)')
.option('-o, --optimize <bool>', 'enable/disable optimization', mapOptimize) .option('-o, --optimize <bool>', 'enable/disable optimization', mapOptimize)
.option('-r, --runs <number>', 'set runs (e.g: 150, 250 etc)') .option('-r, --runs <number>', 'set runs (e.g: 150, 250 etc)')
.option('-v, --verbose <level>', 'set verbosity level (0 to 5)', mapVerbosity) .option('-v, --verbose <level>', 'set verbosity level (0 to 5)', mapVerbosity)
.action(async (testsPath) => { .action(async (testsPath) => {
// Check if path exists
// Check if path exists if (!fs.existsSync(testsPath)) {
if (!fs.existsSync(testsPath)) { log.error(testsPath + ' not found')
log.error(testsPath + ' not found') process.exit(1)
process.exit(1) }
}
// Check if path is for a directory
// Check if path is for a directory const isDirectory = fs.lstatSync(testsPath).isDirectory()
const isDirectory = fs.lstatSync(testsPath).isDirectory()
// If path is for a file, file name must have `_test.sol` suffix
// If path is for a file, file name must have `_test.sol` suffix if (!isDirectory && !testsPath.endsWith('_test.sol')) {
if(!isDirectory && !testsPath.endsWith('_test.sol')) { log.error('Test filename should end with "_test.sol"')
log.error('Test filename should end with "_test.sol"') process.exit()
process.exit() }
}
// Console message
// Console message console.log(colors.white('\n\t👁\t:: Running remix-tests - Unit testing for solidity ::\t👁\n'))
console.log(colors.white('\n\t👁\t:: Running remix-tests - Unit testing for solidity ::\t👁\n'))
// Set logger verbosity
// Set logger verbosity if (commander.verbose) {
if (commander.verbose) { 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) }
}
const compilerConfig = {} as CompilerConfiguration
let compilerConfig = {} as CompilerConfiguration if (commander.compiler) {
if (commander.compiler) { const compVersion = commander.compiler
const compVersion = commander.compiler const baseURL = 'https://binaries.soliditylang.org/wasm/'
const baseURL = 'https://binaries.soliditylang.org/wasm/' const response: AxiosResponse = await axios.get(baseURL + 'list.json')
const response: AxiosResponse = await axios.get(baseURL + 'list.json') const { releases, latestRelease } = response.data
const { releases, latestRelease } = response.data const compString = releases[compVersion]
const compString = releases[compVersion] if (!compString) {
if(!compString) { log.error(`No compiler found in releases with version ${compVersion}`)
log.error(`No compiler found in releases with version ${compVersion}`) process.exit()
process.exit() } else {
} else { compilerConfig.currentCompilerUrl = compString.replace('soljson-', '').replace('.js', '')
compilerConfig.currentCompilerUrl = compString.replace('soljson-', '').replace('.js', '') log.info(`Compiler version set to ${compVersion}. Latest version is ${latestRelease}`)
log.info(`Compiler version set to ${compVersion}. Latest version is ${latestRelease}`) }
} }
}
if (commander.evm) {
if (commander.evm) { compilerConfig.evmVersion = commander.evm
compilerConfig.evmVersion = commander.evm log.info(`EVM set to ${compilerConfig.evmVersion}`)
log.info(`EVM set to ${compilerConfig.evmVersion}`) }
}
if (commander.optimize) {
if (commander.optimize) { compilerConfig.optimize = commander.optimize
compilerConfig.optimize = commander.optimize log.info(`Optimization is ${compilerConfig.optimize ? 'enabled' : 'disabled'}`)
log.info(`Optimization is ${compilerConfig.optimize ? 'enabled' : 'disabled'}`) }
}
if (commander.runs) {
if (commander.runs) { if (!commander.optimize) {
if(!commander.optimize) { log.error('Optimization should be enabled for runs')
log.error(`Optimization should be enabled for runs`) process.exit()
process.exit() }
} compilerConfig.runs = commander.runs
compilerConfig.runs = commander.runs log.info(`Runs set to ${compilerConfig.runs}`)
log.info(`Runs set to ${compilerConfig.runs}`) }
}
const web3 = new Web3()
const web3 = new Web3() const provider: any = new Provider()
const provider: any = new Provider() await provider.init()
await provider.init() web3.setProvider(provider)
web3.setProvider(provider)
runTestFiles(path.resolve(testsPath), isDirectory, web3, compilerConfig)
runTestFiles(path.resolve(testsPath), isDirectory, web3, compilerConfig) })
})
if (!process.argv.slice(2).length) { if (!process.argv.slice(2).length) {
log.error('Please specify a file or directory path') log.error('Please specify a file or directory path')
process.exit() process.exit()
} }
commander.parse(process.argv) commander.parse(process.argv)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -51,8 +51,8 @@ export interface Options { ...@@ -51,8 +51,8 @@ export interface Options {
export interface CompilerConfiguration { export interface CompilerConfiguration {
currentCompilerUrl: string, currentCompilerUrl: string,
evmVersion: string, evmVersion: string,
optimize: boolean, optimize: boolean,
usingWorker?: boolean, usingWorker?: boolean,
runs: number runs: number
} }
...@@ -64,7 +64,7 @@ export interface CompilationErrors { ...@@ -64,7 +64,7 @@ export interface CompilationErrors {
} }
export class CompilationErrors extends Error { export class CompilationErrors extends Error {
constructor(errors: Array<any>) { 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
...@@ -74,9 +74,9 @@ export class CompilationErrors extends Error { ...@@ -74,9 +74,9 @@ export class CompilationErrors extends Error {
/** sources object with name of the file and content **/ /** sources object with name of the file and content **/
//////////// /// /////////
// SOURCE // // SOURCE //
//////////// /// /////////
export interface CompilationSource { export interface CompilationSource {
/** Identifier of the source (used in source maps) */ /** Identifier of the source (used in source maps) */
id: number id: number
...@@ -162,9 +162,9 @@ export interface CompiledContract { ...@@ -162,9 +162,9 @@ export interface CompiledContract {
} }
} }
///////// /// //////
// ABI // // ABI //
///////// /// //////
export type ABIDescription = FunctionDescription | EventDescription export type ABIDescription = FunctionDescription | EventDescription
export interface FunctionDescription { export interface FunctionDescription {
...@@ -227,9 +227,9 @@ export type ABITypeParameter = ...@@ -227,9 +227,9 @@ export type ABITypeParameter =
| 'tuple[]' | 'tuple[]'
| string // Fallback | string // Fallback
/////////////////////////// /// ////////////////////////
// NATURAL SPECIFICATION // // NATURAL SPECIFICATION //
/////////////////////////// /// ////////////////////////
// Userdoc // Userdoc
export interface UserDocumentation { export interface UserDocumentation {
...@@ -267,9 +267,9 @@ export interface DevMethodDoc { ...@@ -267,9 +267,9 @@ export interface DevMethodDoc {
} }
} }
////////////// /// ///////////
// BYTECODE // // BYTECODE //
////////////// /// ///////////
export interface BytecodeObject { export interface BytecodeObject {
/** The bytecode as a hex string. */ /** The bytecode as a hex string. */
object: string object: string
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
"workspace-schematic": "nx workspace-schematic", "workspace-schematic": "nx workspace-schematic",
"dep-graph": "nx dep-graph", "dep-graph": "nx dep-graph",
"help": "nx help", "help": "nx help",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui", "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs",
......
...@@ -347,7 +347,7 @@ ...@@ -347,7 +347,7 @@
"linter": "eslint", "linter": "eslint",
"config": "libs/remix-tests/.eslintrc", "config": "libs/remix-tests/.eslintrc",
"tsConfig": ["libs/remix-tests/tsconfig.lib.json"], "tsConfig": ["libs/remix-tests/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "libs/remix-tests/tests/**/*"] "exclude": ["**/node_modules/**", "libs/remix-tests/tests/**/*", "**/dist/**"]
} }
}, },
"test": { "test": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment