UNPKG

truffle

Version:

Truffle - Simple development framework for Ethereum

1,244 lines (1,146 loc) 69.2 kB
#!/usr/bin/env node /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 89244: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { __webpack_require__(20406); const pkg = __webpack_require__(73755); module.exports = { build: __webpack_require__(60627), create: __webpack_require__(89664), // TODO: update this to non-legacy the next breaking change contracts: __webpack_require__(81969), test: (__webpack_require__(26158).Test), version: pkg.version, ganache: __webpack_require__(11651) }; /***/ }), /***/ 60627: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const fse = __webpack_require__(55674); const del = __webpack_require__(95752); const WorkflowCompile = (__webpack_require__(37017)["default"]); const BuildError = __webpack_require__(42863); const { spawn } = __webpack_require__(32081); const spawnargs = __webpack_require__(72255); const _ = __webpack_require__(96486); const expect = __webpack_require__(14096); function CommandBuilder(command) { this.command = command; } CommandBuilder.prototype.build = function (options, callback) { console.log("Running `" + this.command + "`..."); const args = spawnargs(this.command); const ps = args.shift(); const cmd = spawn(ps, args, { detached: false, cwd: options.working_directory, env: _.merge(process.env, { WORKING_DIRECTORY: options.working_directory, BUILD_DESTINATION_DIRECTORY: options.destination_directory, BUILD_CONTRACTS_DIRECTORY: options.contracts_build_directory }) }); cmd.stdout.on("data", function (data) { console.log(data.toString()); }); cmd.stderr.on("data", function (data) { console.error(data); }); cmd.on("close", function (code) { let error = null; if (code !== 0) { error = "Command exited with code " + code; } callback(error); }); }; const Build = { clean: async function (options) { const destination = options.build_directory; const contracts_build_directory = options.contracts_build_directory; // Clean first. await del([destination + "/*", "!" + contracts_build_directory]); fse.ensureDirSync(destination); }, build: async function (options) { expect.options(options, [ "build_directory", "working_directory", "contracts_build_directory", "networks" ]); const logger = options.logger || console; let builder = options.build; // Duplicate build directory for legacy purposes options.destination_directory = options.build_directory; if (builder === null || typeof builder === "undefined") { logger.log( "No build configuration found. Preparing to compile contracts." ); } else if (typeof builder === "string") { builder = new CommandBuilder(builder); } else if (typeof builder === "function") { // If they've only provided a build function, use that. builder = { build: builder }; } else if (builder.build == null) { throw new BuildError( "Build configuration can no longer be specified as an object. Please see our documentation for an updated list of supported build configurations." ); } // Use our own clean method unless the builder supplies one. let clean = this.clean; if (builder && builder.hasOwnProperty("clean")) { clean = builder.clean; } await clean(options); // If necessary. This prevents errors due to the .sol.js files not existing. await WorkflowCompile.compileAndSave(options); if (builder) { builder.build(options, function (err) { if (typeof err === "string") { throw new BuildError(err); } }); } } }; module.exports = Build; /***/ }), /***/ 89664: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const path = __webpack_require__(71017); const fse = __webpack_require__(55674); const templates = { test: { filename: path.join(__dirname, "templates", "example.js"), variable: "example" }, contract: { filename: path.join(__dirname, "templates", "Example.sol"), name: "Example", license: "MIT", variable: "example" }, migration: { filename: path.join(__dirname, "templates", "migration.js") } }; const replaceContents = (filePath, find, replacement) => { const data = fse.readFileSync(filePath, { encoding: "utf8" }); if (typeof find === "string") { find = new RegExp(find, "g"); } const result = data.replace(find, replacement); fse.writeFileSync(filePath, result, { encoding: "utf8" }); }; const toUnderscoreFromCamel = (string) => { string = string.replace(/([A-Z])/g, function ($1) { return "_" + $1.toLowerCase(); }); if (string[0] === "_") { string = string.substring(1); } return string; }; // getLicense return the license property value from Truffle config first and // in case that the file doesn't exist it will fallback to package.json const getLicense = (options) => { try { const license = (__webpack_require__(20553).detect)(options).license; if (license) { return license; } } catch (err) { console.log(err); } try { return __webpack_require__(76775)(path.join(process.cwd(), "package.json")).license; } catch {} }; const Create = { contract: function (directory, name, options) { const from = templates.contract.filename; const to = path.join(directory, name + ".sol"); if (!options.force && fse.existsSync(to)) { throw new Error("Can not create " + name + ".sol: file exists"); } fse.copySync(from, to); replaceContents(to, templates.contract.name, name); const license = getLicense(options); if (license) { replaceContents(to, templates.contract.license, license); } }, test: function (directory, name, options) { let underscored = toUnderscoreFromCamel(name); underscored = underscored.replace(/\./g, "_"); const from = templates.test.filename; const to = path.join(directory, underscored + ".js"); if (!options.force && fse.existsSync(to)) { throw new Error("Can not create " + underscored + ".js: file exists"); } fse.copySync(from, to); replaceContents(to, templates.contract.name, name); replaceContents(to, templates.contract.variable, underscored); }, migration: function (directory, name, options) { let underscored = toUnderscoreFromCamel(name || ""); underscored = underscored.replace(/\./g, "_"); const from = templates.migration.filename; let filename = (new Date().getTime() / 1000) | 0; // Only do seconds. if (name != null && name !== "") { filename += "_" + underscored; } filename += ".js"; const to = path.join(directory, filename); if (!options.force && fse.existsSync(to)) { throw new Error("Can not create " + filename + ": file exists"); } fse.copySync(from, to); } }; module.exports = Create; /***/ }), /***/ 42863: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const colors = __webpack_require__(83196); const TruffleError = __webpack_require__(73321); class BuildError extends TruffleError { constructor(message) { message = "Error building:\n\n" + message + "\n\n" + colors.red("Build failed. See above."); super(message); } } module.exports = BuildError; /***/ }), /***/ 76775: /***/ ((module) => { function webpackEmptyContext(req) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } webpackEmptyContext.keys = () => ([]); webpackEmptyContext.resolve = webpackEmptyContext; webpackEmptyContext.id = 76775; module.exports = webpackEmptyContext; /***/ }), /***/ 48511: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Resolver = void 0; const resolver_1 = __webpack_require__(43563); Object.defineProperty(exports, "Resolver", ({ enumerable: true, get: function () { return resolver_1.Resolver; } })); exports["default"] = resolver_1.Resolver; //# sourceMappingURL=index.js.map /***/ }), /***/ 64956: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.SolidityTest = void 0; // @ts-ignore const test_js_1 = __importDefault(__webpack_require__(50210)); // @ts-ignore const suite_js_1 = __importDefault(__webpack_require__(83794)); const deployer_1 = __importDefault(__webpack_require__(669)); const compile_solidity_1 = __webpack_require__(4273); const compile_common_1 = __webpack_require__(29833); const debug_1 = __importDefault(__webpack_require__(15158)); const debug = (0, debug_1.default)("lib:testing:soliditytest"); exports.SolidityTest = { define(abstraction, dependencyPaths, runner, mocha) { return __awaiter(this, void 0, void 0, function* () { const self = this; const suite = new suite_js_1.default(abstraction.contract_name, {}); suite.timeout(runner.beforeTimeout); // Set up our runner's needs first. suite.beforeAll("prepare suite", function () { return __awaiter(this, void 0, void 0, function* () { // This compiles some native contracts (including the assertion library // contracts) which need to be compiled before initializing the runner yield self.compileNewAbstractInterface.bind(this)(runner); yield runner.initialize.bind(runner)(); runner.disableChecksOnEventDecoding(); //for handling of test events on Solidity <0.7.6 due to empty string problem yield self.deployTestDependencies.bind(this)(abstraction, dependencyPaths, runner); }); }); suite.afterAll("clean up", function () { runner.reEnableChecksOnEventDecoding(); }); suite.beforeEach("before test", function () { return __awaiter(this, void 0, void 0, function* () { yield runner.startTest(this); }); }); // Function that checks transaction logs to see if a test failed. function checkResultForFailure(result) { return __awaiter(this, void 0, void 0, function* () { const logs = result.receipt.rawLogs; for (const log of logs) { const decodings = yield runner.decoder.decodeLog(log, { disableChecks: true }); for (const decoding of decodings) { //check: is this a TestEvent? //note: we don't check the argument names if (decoding.abi.name === "TestEvent" && decoding.arguments.length === 2 && decoding.arguments[0].value.type.typeClass === "bool" && decoding.arguments[0].indexed && decoding.arguments[1].value.type.typeClass === "string" && !decoding.arguments[1].indexed) { //if so: did the test fail? if (!decoding.arguments[0].value.value.asBoolean) { //if so: extract the message let messageDecoding = decoding.arguments[1].value; let message; switch (messageDecoding.value.kind) { case "valid": message = messageDecoding.value.asString; break; case "malformed": //use buffer to convert hex to string //(this causes malformed UTF-8 to become U+FFFD) message = Buffer.from(messageDecoding.value.asHex.slice(2), "hex").toString(); } throw new Error(message); } } } } }); } // Add functions from test file. for (const item of abstraction.abi) { if (item.type !== "function") { continue; } const hookTypes = ["beforeAll", "beforeEach", "afterAll", "afterEach"]; for (const hookType of hookTypes) { if (item.name.startsWith(hookType)) { suite[hookType](item.name, () => __awaiter(this, void 0, void 0, function* () { let deployed = yield abstraction.deployed(); yield checkResultForFailure(yield deployed[item.name]()); })); } } if (item.name.startsWith("test")) { const test = new test_js_1.default(item.name, () => __awaiter(this, void 0, void 0, function* () { let deployed = yield abstraction.deployed(); yield checkResultForFailure(yield deployed[item.name]()); })); test.timeout(runner.testTimeout); suite.addTest(test); } } suite.afterEach("after test", function () { return __awaiter(this, void 0, void 0, function* () { yield runner.endTest(this); }); }); mocha.suite.addSuite(suite); }); }, compileNewAbstractInterface(runner) { return __awaiter(this, void 0, void 0, function* () { debug("compiling"); const config = runner.config; const truffleLibraries = [ "truffle/Assert.sol", "truffle/AssertAddress.sol", "truffle/AssertAddressArray.sol", "truffle/AssertBalance.sol", "truffle/AssertBool.sol", "truffle/AssertBytes32.sol", "truffle/AssertBytes32Array.sol", "truffle/AssertGeneral.sol", "truffle/AssertInt.sol", "truffle/AssertIntArray.sol", "truffle/AssertString.sol", "truffle/AssertUint.sol", "truffle/AssertUintArray.sol", "truffle/DeployedAddresses.sol", "truffle/SafeSend.sol", "truffle/Console.sol" ]; const { compilations } = yield compile_solidity_1.Compile.sourcesWithDependencies({ paths: truffleLibraries, options: runner.config.with({ quiet: true }) }); const contracts = compilations.reduce((a, compilation) => { return a.concat(compilation.contracts); }, []); // Set network values. for (let contract of contracts) { contract.network_id = config.network_id; contract.default_network = config.default_network; } yield config.artifactor.saveAll(contracts.map(compile_common_1.Shims.NewToLegacy.forContract)); debug("compiled"); }); }, deployTestDependencies(abstraction, dependencyPaths, runner) { return __awaiter(this, void 0, void 0, function* () { debug("deploying %s", abstraction.contract_name); const deployer = new deployer_1.default(runner.config.with({ logger: { log() { } } })); debug("starting deployer"); yield deployer.start(); const testLibraries = [ "Assert", "AssertAddress", "AssertAddressArray", "AssertBalance", "AssertBool", "AssertBytes32", "AssertBytes32Array", "AssertGeneral", "AssertInt", "AssertIntArray", "AssertString", "AssertUint", "AssertUintArray", "DeployedAddresses", "Console" ]; const testAbstractions = testLibraries.map(name => runner.config.resolver.require(`truffle/${name}.sol`)); const SafeSend = runner.config.resolver.require("SafeSend"); debug("deploying test libs"); for (const testLib of testAbstractions) { yield deployer.deploy(testLib); yield deployer.link(testLib, abstraction); } debug("linking dependencies"); for (const dependencyPath of dependencyPaths) { const dependency = runner.config.resolver.require(dependencyPath); if (dependency.isDeployed()) { yield deployer.link(dependency, abstraction); } } debug("deploying contract"); yield deployer.deploy(abstraction); const deployed = yield abstraction.deployed(); let balance; if (deployed.initialBalance) { balance = yield deployed.initialBalance.call(); } else { balance = 0; } if (balance !== 0) { yield deployer.deploy(SafeSend); const safeSend = yield SafeSend.deployed(); yield safeSend.deliver(deployed.address, { value: balance }); } debug("deployed %s", abstraction.contract_name); }); } }; //# sourceMappingURL=SolidityTest.js.map /***/ }), /***/ 83725: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Test = void 0; const colors_1 = __importDefault(__webpack_require__(83196)); const chai_1 = __importDefault(__webpack_require__(14960)); const path = __webpack_require__(71017); const interface_adapter_1 = __webpack_require__(36339); const config_1 = __importDefault(__webpack_require__(20553)); const workflow_compile_1 = __importDefault(__webpack_require__(37017)); const resolver_1 = __webpack_require__(48511); const TestRunner_1 = __webpack_require__(34036); const SolidityTest_1 = __webpack_require__(64956); const rangeUtils_1 = __importDefault(__webpack_require__(32739)); const expect = __importStar(__webpack_require__(14096)); const migrate_1 = __importDefault(__webpack_require__(22478)); const profiler_1 = __webpack_require__(22860); const original_require_1 = __importDefault(__webpack_require__(44516)); const Codec = __importStar(__webpack_require__(20102)); const debug_1 = __importDefault(__webpack_require__(15158)); const debug = (0, debug_1.default)("lib:test"); const debugger_1 = __importDefault(__webpack_require__(92851)); let Mocha; // Late init with "mocha" or "mocha-parallel-tests" chai_1.default.use((__webpack_require__(1465)["default"])); exports.Test = { run: function (options, createInTestDebugFunction) { return __awaiter(this, void 0, void 0, function* () { expect.options(options, [ "contracts_directory", "contracts_build_directory", "migrations_directory", "test_files", "network", "network_id", "provider" ]); // if test is used standalone, this function won't be setup like in core if (createInTestDebugFunction === undefined) { createInTestDebugFunction = () => { return () => { config.logger.log(`${colors_1.default.bold("Warning:")} Use of in-test debugging is only available when running ` + `truffle test --debug.`); }; }; } const config = config_1.default.default().merge(options); config.test_files = config.test_files.map((testFile) => { return path.resolve(testFile); }); const interfaceAdapter = (0, interface_adapter_1.createInterfaceAdapter)({ provider: config.provider, networkType: config.networks[config.network].type }); // `accounts` will be populated before each contract() invocation // and passed to it so tests don't have to call it themselves. const web3 = new interface_adapter_1.Web3Shim({ provider: config.provider, networkType: config.networks[config.network].type ? config.networks[config.network].type : "web3js" }); // Override console.warn() because web3 outputs gross errors to it. // e.g., https://github.com/ethereum/web3.js/blob/master/lib/web3/allevents.js#L61 // Output looks like this during tests: https://gist.github.com/tcoulter/1988349d1ec65ce6b958 const warn = config.logger.warn; config.logger.warn = function (message) { if (message === "cannot find event for log") { return; } else { if (warn) warn.apply(console, arguments); } }; const mocha = this.createMocha(config); // set up a promise on this instance to resolve to // Mocha's "runner" returned by `mocha.run(...)`. // // do this upfront so that the promise is available // immediately, even though mocha.run happens at the very // end of this setup. let setMochaRunner; this.mochaRunner = new Promise(resolve => { setMochaRunner = resolve; }); const jsTests = config.test_files.filter((file) => { return path.extname(file) !== ".sol"; }); const solTests = config.test_files.filter((file) => { return path.extname(file) === ".sol"; }); // Add Javascript tests because there's nothing we need to do with them. // Solidity tests will be handled later. jsTests.forEach((file) => { // There's an idiosyncracy in Mocha where the same file can't be run twice // unless we delete the `require` cache. // https://github.com/mochajs/mocha/issues/995 delete original_require_1.default.cache[file]; mocha.addFile(file); }); const accounts = yield this.getAccounts(interfaceAdapter); const testResolver = new resolver_1.Resolver(config); const { compilations } = yield this.compileContractsWithTestFilesIfNeeded(solTests, config, testResolver); const testContracts = solTests.map((testFilePath) => { return testResolver.require(testFilePath); }); const runner = new TestRunner_1.TestRunner(config); if (config.migrateNone || config["migrate-none"]) { if (config.events) { config.events.emit("test:migration:skipped"); } } else { yield this.performInitialDeploy(config, testResolver); } const sourcePaths = [] .concat(...compilations.map((compilation) => compilation.sourceIndexes) //we don't need the indices here, just the paths ) .filter(path => path); //make sure we don't pass in any undefined yield this.defineSolidityTests(mocha, testContracts, sourcePaths, runner); const debuggerCompilations = Codec.Compilations.Utils.shimCompilations(compilations); //for stack traces, we'll need to set up a light-mode debugger... let bugger; if (config.stacktrace) { debug("stacktraces on!"); bugger = yield debugger_1.default.forProject({ compilations: debuggerCompilations, provider: config.provider, lightMode: true }); } yield this.setJSTestGlobals({ config, web3, interfaceAdapter, accounts, testResolver, runner, compilations: debuggerCompilations, bugger, createInTestDebugFunction }); // Finally, run mocha. process.on("unhandledRejection", reason => { throw reason; }); return new Promise(resolve => { const mochaRunner = mocha.run((failures) => { config.logger.warn = warn; resolve(failures); }); // finish setting up the mocha runner so that the // previously-made promise resolves. setMochaRunner(mochaRunner); }); }); }, createMocha: function (config) { // Allow people to specify config.mocha in their config. const mochaConfig = config.mocha || {}; // Propagate --bail option to mocha mochaConfig.bail = config.bail; // If the command line overrides color usage, use that. if (config.color != null) { mochaConfig.color = config.color; } else if (config.colors != null) { // --colors is a mocha alias for --color mochaConfig.color = config.colors; } // Default to true if configuration isn't set anywhere. if (mochaConfig.color == null) { mochaConfig.color = true; } Mocha = mochaConfig.package || __webpack_require__(3270); delete mochaConfig.package; const mocha = new Mocha(mochaConfig); return mocha; }, getAccounts: function (interfaceAdapter) { return interfaceAdapter.getAccounts(); }, compileContractsWithTestFilesIfNeeded: function (solidityTestFiles, config, testResolver) { return __awaiter(this, void 0, void 0, function* () { const updated = (yield profiler_1.Profiler.updated(config.with({ resolver: testResolver }))) || []; const compiler = config.compileNone || config["--compile-none"] ? "none" : config.compiler; let compileConfig = config.with({ all: config.compileAll === true, compiler, files: updated.concat(solidityTestFiles), resolver: testResolver, quiet: config.runnerOutputOnly || config.quiet, quietWrite: true }); if (config.compileAllDebug) { let versionString = ((compileConfig.compilers || {}).solc || {}).version; versionString = rangeUtils_1.default.resolveToRange(versionString); if (rangeUtils_1.default.rangeContainsAtLeast(versionString, "0.6.3")) { compileConfig = compileConfig.merge({ compilers: { solc: { settings: { debug: { revertStrings: "debug" } } } } }); } else { config.logger.log(`\n${colors_1.default.bold("Warning:")} Extra revert string info requires Solidity v0.6.3 or higher. For more\n information, see release notes <https://github.com/ethereum/solidity/releases/tag/v0.6.3>`); } } // Compile project contracts and test contracts const { contracts, compilations } = yield workflow_compile_1.default.compileAndSave(compileConfig); return { contracts, compilations }; }); }, performInitialDeploy: function (config, resolver) { const migrateConfig = config.with({ reset: true, resolver: resolver, quiet: true }); return migrate_1.default.run(migrateConfig); }, defineSolidityTests: (mocha, contracts, dependencyPaths, runner) => __awaiter(void 0, void 0, void 0, function* () { for (const contract of contracts) { yield SolidityTest_1.SolidityTest.define(contract, dependencyPaths, runner, mocha); debug("defined solidity tests for %s", contract.contractName); } }), setJSTestGlobals: function ({ config, web3, interfaceAdapter, accounts, testResolver, runner, compilations, bugger, //for stacktracing createInTestDebugFunction }) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { // @ts-ignore global.interfaceAdapter = interfaceAdapter; // @ts-ignore global.web3 = web3; const resolvedChai = (_b = (_a = config.chai) === null || _a === void 0 ? void 0 : _a.package) !== null && _b !== void 0 ? _b : chai_1.default; // @ts-ignore global.assert = resolvedChai.assert; // @ts-ignore global.expect = resolvedChai.expect; // @ts-ignore global.artifacts = { require: (importPath) => { let contract = testResolver.require(importPath); //HACK: both of the following should go by means //of the provisioner, but I'm not sure how to make //that work at the moment contract.reloadJson = function () { const reloaded = testResolver.require(importPath); this._json = reloaded._json; }; if (bugger) { contract.debugger = bugger; } return contract; } }; // @ts-ignore global.config = config.normalize(config); // @ts-ignore global[config.debugGlobal] = createInTestDebugFunction({ compilations, mochaRunner: this.mochaRunner, config }); const template = function (tests) { this.timeout(runner.testTimeout); // @ts-ignore before("prepare suite", function () { return __awaiter(this, void 0, void 0, function* () { this.timeout(runner.beforeTimeout); yield runner.initialize(); }); }); // @ts-ignore beforeEach("before test", function () { return __awaiter(this, void 0, void 0, function* () { yield runner.startTest(); }); }); // @ts-ignore afterEach("after test", function () { return __awaiter(this, void 0, void 0, function* () { yield runner.endTest(this); }); }); tests(accounts); }; // @ts-ignore global.contract = function (name, tests) { Mocha.describe("Contract: " + name, function () { template.bind(this, tests)(); }); }; // @ts-ignore global.contract.only = function (name, tests) { Mocha.describe.only("Contract: " + name, function () { template.bind(this, tests)(); }); }; // @ts-ignore global.contract.skip = function (name, tests) { Mocha.describe.skip("Contract: " + name, function () { template.bind(this, tests)(); }); }; }); } }; //# sourceMappingURL=Test.js.map /***/ }), /***/ 34036: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.TestRunner = void 0; const interface_adapter_1 = __webpack_require__(36339); const web3_utils_1 = __importDefault(__webpack_require__(18269)); const config_1 = __importDefault(__webpack_require__(20553)); const migrate_1 = __importDefault(__webpack_require__(22478)); const resolver_1 = __webpack_require__(48511); const expect = __importStar(__webpack_require__(14096)); const util_1 = __importDefault(__webpack_require__(73837)); const fs_1 = __importDefault(__webpack_require__(57147)); const path_1 = __importDefault(__webpack_require__(71017)); const debug_1 = __importDefault(__webpack_require__(15158)); const debug = (0, debug_1.default)("lib:testing:testrunner"); const Decoder = __importStar(__webpack_require__(18852)); const Codec = __importStar(__webpack_require__(20102)); const os_1 = __importDefault(__webpack_require__(22037)); class TestRunner { constructor(options) { expect.options(options, [ "resolver", "provider", "contracts_build_directory" ]); this.config = config_1.default.default().merge(options); this.logger = options.logger || console; this.provider = options.provider; this.canSnapshot = false; this.firstSnapshot = true; this.initialSnapshot = null; this.interfaceAdapter = (0, interface_adapter_1.createInterfaceAdapter)({ provider: options.provider, networkType: options.networks[options.network].type }); this.decoder = null; // For each test this.currentTestStartBlock = null; this.beforeTimeout = (options.mocha && options.mocha.before_timeout) || 120000; this.testTimeout = (options.mocha && options.mocha.timeout) || 300000; } disableChecksOnEventDecoding() { this.disableChecks = true; //used by Solidity testing due to empty string problem on Solidity <0.7.6 } reEnableChecksOnEventDecoding() { this.disableChecks = false; } initialize() { return __awaiter(this, void 0, void 0, function* () { debug("initializing"); this.config.resolver = new resolver_1.Resolver(this.config); if (this.firstSnapshot) { debug("taking first snapshot"); try { const initialSnapshot = yield this.snapshot(); this.canSnapshot = true; this.initialSnapshot = initialSnapshot; } catch (error) { debug("first snapshot failed"); debug("Error: %O", error); } this.firstSnapshot = false; } else { yield this.resetState(); } //set up decoder let files = fs_1.default .readdirSync(this.config.contracts_build_directory) .filter(file => path_1.default.extname(file) === ".json"); let data = files.map(file => fs_1.default.readFileSync(path_1.default.join(this.config.contracts_build_directory, file), "utf8")); let artifacts = data.map(text => JSON.parse(text)); this.decoder = yield Decoder.forProject({ provider: this.provider, projectInfo: { artifacts } }); }); } deploy() { return __awaiter(this, void 0, void 0, function* () { yield migrate_1.default.run(this.config.with({ reset: true, quiet: true })); }); } resetState() { return __awaiter(this, void 0, void 0, function* () { if (this.canSnapshot) { debug("reverting..."); yield this.revert(this.initialSnapshot); this.initialSnapshot = yield this.snapshot(); } else { debug("redeploying..."); yield this.deploy(); } }); } startTest() { return __awaiter(this, void 0, void 0, function* () { const blockNumber = web3_utils_1.default.toBN(yield this.interfaceAdapter.getBlockNumber()); const one = web3_utils_1.default.toBN(1); // Add one in base 10 this.currentTestStartBlock = blockNumber.add(one); }); } endTest(mocha) { return __awaiter(this, void 0, void 0, function* () { // Skip logging if test passes and `show-events` option is not true if (mocha.currentTest.state !== "failed" && !this.config["show-events"]) { return; } function indent(input, indentation, initialPrefix = "") { const unindented = input.split(/\r?\n/); return unindented .map((line, index) => index === 0 ? initialPrefix + " ".repeat(indentation - initialPrefix.length) + line : " ".repeat(indentation) + line) .join(os_1.default.EOL); } function printEvent(decoding, indentation = 0, initialPrefix = "") { debug("raw event: %O", decoding); const inspected = util_1.default.inspect(new Codec.Export.LogDecodingInspector(decoding), { depth: null, colors: true, maxArrayLength: null, breakLength: 80 - indentation //should this include prefix lengths as well? }); return indent(inspected, indentation, initialPrefix); } if (this.decoder === null) { throw new Error("Decoder has not yet been initialized."); } if (this.currentTestStartBlock === null) { throw new Error("`currentTestStartBlock` has not been initialized. You must " + "call `startTest` before calling `endTest`."); } const logs = yield this.decoder.events({ //NOTE: block numbers shouldn't be over 2^53 so this //should be fine, but should change this once decoder //accepts more general types for blocks fromBlock: this.currentTestStartBlock.toNumber(), extras: "necessary", disableChecks: this.disableChecks //for Solidity testing }); const userDefinedEventLogs = logs.filter(log => { return log.decodings.every(decoding => decoding.abi.name !== "TestEvent"); }); if (userDefinedEventLogs.length === 0) { this.logger.log(" > No events were emitted"); return; } this.logger.log("\n Events emitted during test:"); this.logger.log(" ---------------------------"); this.logger.log(""); for (const log of userDefinedEventLogs) { switch (log.decodings.length) { case 0: this.logger.log(` Warning: Could not decode event!`); this.logger.log(""); break; case 1: this.logger.log(printEvent(log.decodings[0], 4)); this.logger.log(""); break; default: this.logger.log(` Ambiguous event, possible interpretations:`); for (const decoding of log.decodings) { this.logger.log(printEvent(decoding, 6, " * ")); } this.logger.log(""); break; } } this.logger.log("\n ---------------------------"); }); } snapshot() { return __awaiter(this, void 0, void 0, function* () { return (yield this.rpc("evm_snapshot")).result; }); } revert(snapshot_id) { return __awaiter(this, void 0, void 0, function* () { yield this.rpc("evm_revert", [snapshot_id]); }); } rpc(method, arg) { return __awaiter(this, void 0, void 0, function* () { let request = { jsonrpc: "2.0", method: method, id: Date.now(), params: arg }; let result = yield util_1.default.promisify(this.provider.send)(request); if (result.error != null) { throw new Error("RPC Error: " + (result.error.message || result.error)); } return result; }); } } exports.TestRunner = TestRunner; //# sourceMappingURL=TestRunner.js.map /***/ }), /***/ 1465: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); const web3_utils_1 = __importDefault(__webpack_require__(18269)); function default_1(chai, _utils) { const assert = chai.assert; chai.Assertion.addProperty("address", function () { this.assert(this._obj.length === 42, "expected #{this} to be a 42 character address (0x...)", "expected #{this} to not be a 42 character address (0x...)"); // Convert address to a number. Make sure it's not zero. // Controversial: Technically there is that edge case where // all zeroes could be a valid address. But: This catches all // those cases where Ethereum returns 0x0000... if something fails. const number = web3_utils_1.default.toBN(this._obj); this.assert(!number.isZero(), "expected address #{this} to not be zero", "you shouldn't ever see this."); }); assert.isAddress = function (val, _exp, msg) { return new chai.Assertion(val, msg).to.be.address; }; } exports["default"] = default_1; //# sourceMappingURL=assertions.js.map /***/ }), /***/ 26158: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; var __webpack_unused_export__; __webpack_unused_export__ = ({ value: true }); __webpack_unused_export__ = __webpack_unused_export__ = exports.Test = void 0; var Test_1 = __webpack_require__(83725); Object.defineProperty(exports, "Test", ({ enumerable: true, get: function () { return Test_1.Test; } })); var SolidityTest_1 = __webpack_require__(64956); __webpack_unused_export__ = ({ enumerable: true, get: function () { return SolidityTest_1.SolidityTest; } }); var TestRunner_1 = __webpack_require__(34036); __webpack_unused_export__ = ({ enumerable: true, get: function () { return TestRunner_1.TestRunner; } }); //# sourceMappingURL=index.js.map /***/ }), /***/ 81969: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const debug = __webpack_require__(15158)("workflow-compile"); const fse = __webpack_require__(55674); const externalCompile = __webpack_require__(96412); const solcCompile = __webpack_require__(4273); const vyperCompile = __webpack_require__(74269); const { Shims } = __webpack_require__(29833); const expect = __webpack_require__(14096); const Config = __webpack_require__(20553); const Artifactor = __webpack_require__(29463); const Resolver = (__webpack_require__(48511)["default"]); const SUPPORTED_COMPILERS = { solc: solcCompile, vyper: vyperCompile, external: externalCompile }; function prepareConfig(options) { expect.options(options, ["contracts_build_directory"]); expect.one(options, ["contracts_directory", "files"]); // Use a config object to ensure we get the default sources. const config = Config.default().merge(options); config.compilersInfo = {}; if (!config.resolver) config.resolver = new Resolver(config); if (!config.artifactor) { config.artifactor = new Artifactor(config.contracts_build_directory); } return config; } const WorkflowCompile = { collectCompilations: async compilations => { let result = { outputs: {}, contracts: {} }; for (let compilation of await Promise.all(compilations)) { let { compiler, output, contracts } = compilation; result.outputs[compiler] = output; for (let [name, abstraction] of Object.entries(contracts)) { result.contracts[name] = abstraction; } } return result; },