From 99b3b6e835caa31aa8d15a2716032319d4647cac Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sat, 12 Oct 2019 11:30:58 -0700 Subject: [PATCH 01/21] Update buidler / reorg dependencies --- buidler.config.js | 18 - package.json | 14 +- test/util/util.js | 2 +- yarn.lock | 1200 ++++++++++++++++++++++++++------------------- 4 files changed, 716 insertions(+), 518 deletions(-) delete mode 100644 buidler.config.js diff --git a/buidler.config.js b/buidler.config.js deleted file mode 100644 index 4ce54044..00000000 --- a/buidler.config.js +++ /dev/null @@ -1,18 +0,0 @@ - -// Mute compiler warnings - this will need to be addressed properly in -// the Buidler plugin by overloading TASK_COMPILE_COMPILE. -const originalLog = console.log; -console.warn = () => {}; -console.log = val => val === '\n' ? null : originalLog(val); - -module.exports = { - solc: { - version: "0.5.8" - }, - paths: { - artifacts: "./test/artifacts", - cache: "./test/cache", - test: "./test/units", - sources: "./test/sources/contracts", - } -} diff --git a/package.json b/package.json index 0a1df45f..bed3e2b5 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,9 @@ "@truffle/provider": "^0.1.17", "chalk": "^2.4.2", "death": "^1.1.0", - "fs-extra": "^8.1.0", "detect-port": "^1.3.0", - "ganache-core-sc": "2.7.0-sc.0", + "fs-extra": "^8.1.0", + "ganache-cli": "6.7.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", @@ -39,15 +39,17 @@ "node-emoji": "^1.10.0", "pify": "^4.0.1", "shelljs": "^0.8.3", - "solidity-parser-antlr": "^0.4.7", + "solidity-parser-antlr": "0.4.7", "web3": "1.2.1", "web3-utils": "^1.0.0" }, "devDependencies": { - "@nomiclabs/buidler": "^1.0.0-beta.8", - "@nomiclabs/buidler-truffle5": "^1.0.0-beta.8", - "@nomiclabs/buidler-web3": "^1.0.0-beta.8", + "@nomiclabs/buidler": "^1.0.1", + "@nomiclabs/buidler-truffle5": "^1.0.1", + "@nomiclabs/buidler-web3": "^1.0.1", + "@truffle/contract": "^4.0.36", "decache": "^4.5.1", + "ganache-core-sc": "^2.7.0-sc.0", "mocha": "5.2.0", "nyc": "^14.1.1", "solc": "^0.5.10", diff --git a/test/util/util.js b/test/util/util.js index 987f3374..85874055 100644 --- a/test/util/util.js +++ b/test/util/util.js @@ -5,7 +5,7 @@ const fs = require('fs'); const path = require('path'); const solc = require('solc'); -const TruffleContract = require('truffle-contract'); +const TruffleContract = require('@truffle/contract'); const Instrumenter = require('./../../lib/instrumenter'); const DataCollector = require('./../../lib/collector') diff --git a/yarn.lock b/yarn.lock index 5cc76b8f..5c3e4251 100644 --- a/yarn.lock +++ b/yarn.lock @@ -111,43 +111,113 @@ "@nodelib/fs.scandir" "2.1.2" fastq "^1.6.0" -"@nomiclabs/buidler-truffle5@^1.0.0-beta.8": - version "1.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-truffle5/-/buidler-truffle5-1.0.0-beta.8.tgz#d810b2c7d6de7cc58dddff2af227595be7b6e250" - integrity sha512-3v4SFcqWCH/aDRxgNTxhESLoCuHrC8CGBZIeeRwYOV6P2jdZBFkaCziW8QbpNd4hpOa3qAxHYzbE823T6A/p5A== +"@nomiclabs/buidler-truffle5@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-truffle5/-/buidler-truffle5-1.0.1.tgz#6545f52c6441dc8942f66a2f14ef9fdacc899088" + integrity sha512-4c36uf62mQz7hrBkKLvLv2+Z7u3VWMoJ7MStm69RMCtUA6iG5kd7Sd+cL3jCHr+eIAMSBGllPmvmAFDp7etFeQ== dependencies: + "@nomiclabs/truffle-contract" "^4.0.0" + "@types/chai" "^4.2.0" chai "^4.2.0" - truffle-contract "^4.0.14" + ethereumjs-util "^6.1.0" + fs-extra "^7.0.1" -"@nomiclabs/buidler-web3@^1.0.0-beta.8": - version "1.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-web3/-/buidler-web3-1.0.0-beta.8.tgz#75df7a2d5de6ec03d4c73cb1c7369be1e1021f46" - integrity sha512-ConceCb/qNV26HjFyWXxv0+kCmkPTpR10C6CS2aZpq6GuKybY4YO6Mks1YzhYdZWii3s/+laJzylDLpjXcwjcg== +"@nomiclabs/buidler-web3@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler-web3/-/buidler-web3-1.0.1.tgz#8e7f42b62a52a9ed9e205b2ff941a686d8705513" + integrity sha512-dgMIabIqReVUzp2reN7pWUS4n0wdIZBsJ4pQFjbjpP91bpVtVAMSaGSU71gqUiXWbyqFY3TOT9Hr9Q8VsqFxEA== -"@nomiclabs/buidler@^1.0.0-beta.8": - version "1.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/buidler/-/buidler-1.0.0-beta.8.tgz#31aaa351e5f3a15e9821738256417b98a7657665" - integrity sha512-qG348aP+kl4xJn1PG4pHgAeDlNOszvffRDS6H2yUJI7XiIgw8o1qkYEd4zFnLEJI+4PPrPtv2zhUg8tXpiaWWw== - dependencies: - ansi-colors "^3.2.4" +"@nomiclabs/buidler@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@nomiclabs/buidler/-/buidler-1.0.1.tgz#4ac100fa96cf4326a551bf7099922b4c61956a50" + integrity sha512-MpjKvp7iYbTCT8gf4/RTYl5LK98owGYkibjUsWZ+B8COtlNQgpt7Eoxrh77lls06oGP8GmseWtVFF+qt9oZczw== + dependencies: + "@nomiclabs/eth-sig-util" "^2.4.4" + "@nomiclabs/ethereumjs-vm" "^4.1.0" + "@types/bn.js" "^4.11.5" + "@types/lru-cache" "^5.1.0" + abort-controller "^3.0.0" + bip32 "^2.0.3" + bip39 "^3.0.2" + chalk "^2.4.2" + ci-info "^2.0.0" + debug "^4.1.1" deepmerge "^2.1.0" download "^7.1.0" enquirer "^2.3.0" - ethereumjs-tx "^1.3.7" + ethereumjs-abi "^0.6.8" + ethereumjs-account "^3.0.0" + ethereumjs-block "^2.2.0" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" ethereumjs-util "^6.1.0" find-up "^2.1.0" + fp-ts "1.19.3" fs-extra "^7.0.1" glob "^7.1.3" - io-ts "^1.8.6" + io-ts "1.10.4" + is-installed-globally "^0.2.0" lodash "^4.17.11" + merkle-patricia-tree "^3.0.0" mocha "^5.2.0" - semver "^5.6.0" - solc "0.5.8" + node-fetch "^2.6.0" + qs "^6.7.0" + semver "^6.3.0" + solc "0.5.11" solidity-parser-antlr "^0.4.2" - source-map-support "^0.5.12" + source-map-support "^0.5.13" ts-essentials "^2.0.7" tsort "0.0.1" - web3x "^2.0.0" + uuid "^3.3.2" + +"@nomiclabs/eth-sig-util@^2.4.4": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@nomiclabs/eth-sig-util/-/eth-sig-util-2.4.4.tgz#e3518a90027a7952af24204a81713c21b500d546" + integrity sha512-t6vqztYHLq9t0CTiULheO+zrNqp1c10EjFgfKNxQGSV+A8hoztJDgU8FRKpczWN6MgQv2qFFgGMRfymadjY4pA== + dependencies: + buffer "^5.2.1" + elliptic "^6.4.0" + ethereumjs-abi "0.6.5" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.0" + tweetnacl-util "^0.15.0" + +"@nomiclabs/ethereumjs-vm@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.1.0.tgz#2767e5e779c9c1db4ce50adb789d87a683622710" + integrity sha512-2eordoieZBmNEMkspyOpn3X4jqUtIzKarahGlPUd3WRVPvOSfbf68wNgKN+IbcQ9xND6nvb64fpW3kgckXdclQ== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + core-js-pure "^3.0.1" + ethereumjs-account "^3.0.0" + ethereumjs-block "~2.2.0" + ethereumjs-blockchain "^4.0.1" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" + ethereumjs-util "^6.1.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + util.promisify "^1.0.0" + +"@nomiclabs/truffle-contract@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/truffle-contract/-/truffle-contract-4.0.0.tgz#14a1f6c880eaf6b0ff2b8a208419972c6e7b9b4a" + integrity sha512-CTehoNcdZO+PAvOcMlVu3XEdVkxugJLdVui46vrmBF+AJuuiLwMbA+unM0AJtVpwhqcNt5Zb4KyMixqlH7VEEQ== + dependencies: + "@truffle/blockchain-utils" "^0.0.12" + "@truffle/contract-schema" "^3.0.16" + "@truffle/error" "^0.0.7" + "@truffle/interface-adapter" "^0.2.6" + bignumber.js "^7.2.1" + ethers "^4.0.0-beta.1" + web3 "1.2.1" + web3-core-promievent "1.2.1" + web3-eth-abi "1.2.1" + web3-utils "1.2.1" "@sindresorhus/is@^0.14.0": version "0.14.0" @@ -166,6 +236,41 @@ dependencies: defer-to-connect "^1.0.1" +"@truffle/blockchain-utils@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.0.12.tgz#ad75c7eb7ef65ee954850470745873de59392309" + integrity sha512-Khoc0zxksDL3xEHg4j0qpD7+4xyRdRS1Sa5ghwwBCa23I6ofQUmntEoQasZsXo7g6PDkErrJzxOWxTs8gpHQnA== + +"@truffle/blockchain-utils@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.0.13.tgz#2b6302586248fe2068ba160be53855c3c923a4e2" + integrity sha512-58PNluLrJ967BjoBymWmfa+j9tfDa2GpAjEOiKkQav94aVbrBecDwmd3jOTl3gAhJA21AB3UZxri50mKVHopKw== + +"@truffle/contract-schema@^3.0.16": + version "3.0.16" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.0.16.tgz#0de8670b2b0dacba57b43b65911c5376dd00bbdf" + integrity sha512-E88YTZNVvnSprvKS8qMx7e5zm3VAgkCAciQrX1VC+h14EbCJxHyg/9iBVm26ySKgghRzV3Ia8Y6ZJQt6o2iSJw== + dependencies: + ajv "^6.10.0" + crypto-js "^3.1.9-1" + debug "^4.1.0" + +"@truffle/contract@^4.0.36": + version "4.0.36" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.0.36.tgz#9c5d22034f034866f7566eb1ff6d46af0404090d" + integrity sha512-Bhgpd45ZB+o01fKS35xJbvz+ipBWBtE6fzSEEEF6nQvW+OR1jZJ2eKoVSfPU1h3wV5jSzBbQuLbWCtNA+RrNqg== + dependencies: + "@truffle/blockchain-utils" "^0.0.13" + "@truffle/contract-schema" "^3.0.16" + "@truffle/error" "^0.0.7" + "@truffle/interface-adapter" "^0.2.7" + bignumber.js "^7.2.1" + ethers "^4.0.0-beta.1" + web3 "1.2.1" + web3-core-promievent "1.2.1" + web3-eth-abi "1.2.1" + web3-utils "1.2.1" + "@truffle/error@^0.0.7": version "0.0.7" resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.0.7.tgz#e9db39885575647ef08bf624b0c13fe46d41a209" @@ -181,6 +286,16 @@ lodash "^4.17.13" web3 "1.2.1" +"@truffle/interface-adapter@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.2.7.tgz#43331d29539e09432a70cfb9fb614b8afaa7b290" + integrity sha512-GJF0V7VAX+8MQOt/kWGXaQu44QpoKUu4wJpqHxmBMaeVxU9LWB7i7Opa1cR/7rjRnLam2+mCxB5cjoQ9pHD4eQ== + dependencies: + bn.js "^4.11.8" + ethers "^4.0.32" + lodash "^4.17.13" + web3 "1.2.1" + "@truffle/provider@^0.1.17": version "0.1.17" resolved "https://registry.yarnpkg.com/@truffle/provider/-/provider-0.1.17.tgz#9b72a76a7ce18a054eabb3ebd21a55a33dc7d7b6" @@ -190,13 +305,18 @@ "@truffle/interface-adapter" "^0.2.6" web3 "1.2.1" -"@types/bn.js@^4.11.2": +"@types/bn.js@^4.11.5": version "4.11.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" integrity sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng== dependencies: "@types/node" "*" +"@types/chai@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.3.tgz#419477a3d5202bad19e14c787940a61dc9ea6407" + integrity sha512-VRw2xEGbll3ZiTQ4J02/hUjNqZoue1bMhoo2dgM2LXjDdyaq4q80HgBDHwpI0/VKlo4Eg+BavyQMv/NYgTetzA== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -211,6 +331,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/lru-cache@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" + integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -221,19 +346,21 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== -"@types/node@^10.12.0", "@types/node@^10.3.2": +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + +"@types/node@^10.3.2": version "10.14.13" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== -"@types/ws@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" - integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== - dependencies: - "@types/events" "*" - "@types/node" "*" - JSONStream@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -252,6 +379,13 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + abstract-leveldown@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" @@ -346,7 +480,7 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" -ansi-colors@^3.2.1, ansi-colors@^3.2.4: +ansi-colors@^3.2.1: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== @@ -1033,9 +1167,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base-x@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.6.tgz#de047ec95f5f7b99ae63d830a2a894c96538b2cd" - integrity sha512-4PaF8u2+AlViJxRVjurkLTxpp7CaFRD/jo5rPT9ONnKxyhQ8f59yzamEvq7EkriG56yn5On4ONyaG75HLqr46w== + version "3.0.7" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.7.tgz#1c5a7fafe8f66b4114063e8da102799d4e7c408f" + integrity sha512-zAKJGuQPihXW22fkrfOclUUZXM2g92z5GzlSMHxhO6r6Qj+Nm0ccaGNBzDZojzwOMkpjAv4J0fOv1U4go+a4iw== dependencies: safe-buffer "^5.0.1" @@ -1056,13 +1190,26 @@ bignumber.js@^7.2.1: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== -bindings@^1.2.1, bindings@^1.5.0: +bindings@^1.2.1, bindings@^1.3.0, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" +bip32@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.4.tgz#b662bd28710d4676fb351ba8a13be45cb4d85d01" + integrity sha512-ioPytarPDIrWckWMuK4RNUtvwhvWEc2fvuhnO0WEwu732k5OLjUXv4rXi2c/KJHw9ZMNQMkYRJrBw81RujShGQ== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.0" + typeforce "^1.11.5" + wif "^2.0.6" + bip39@2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" @@ -1074,16 +1221,15 @@ bip39@2.5.0: safe-buffer "^5.0.1" unorm "^1.3.3" -bip39@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" - integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== +bip39@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" + integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== dependencies: + "@types/node" "11.11.6" create-hash "^1.1.0" pbkdf2 "^3.0.9" randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" bip66@^1.1.5: version "1.1.5" @@ -1112,11 +1258,16 @@ bluebird@^2.9.34: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= -bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: +bluebird@^3.5.0: version "3.5.5" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== +bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: + version "3.7.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.0.tgz#56a6a886e03f6ae577cffedeb524f8f2450293cf" + integrity sha512-aBQ1FxIa7kSWCcmKHlcHFlT2jt6J/l4FzC7KcPELkOJOsPOb/bccdhmIrKDfXhwFrmc7vDoDrrepFvGqjyXGJg== + bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" @@ -1182,7 +1333,7 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0: +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -1262,7 +1413,7 @@ bs58@^4.0.0: dependencies: base-x "^3.0.2" -bs58check@^2.1.2: +bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== @@ -1342,10 +1493,10 @@ bytewise@~1.1.0: bytewise-core "^1.2.2" typewise "^1.0.3" -cacache@^12.0.0: - version "12.0.2" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c" - integrity sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg== +cacache@^12.0.0, cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== dependencies: bluebird "^3.5.5" chownr "^1.1.1" @@ -1423,9 +1574,9 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30000844: - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== + version "1.0.30000999" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz#427253a69ad7bea4aa8d8345687b8eec51ca0e43" + integrity sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg== caseless@~0.12.0: version "0.12.0" @@ -1491,6 +1642,11 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== +chownr@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1598,7 +1754,17 @@ commander@2.15.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== -commander@^2.20.0, commander@^2.8.1, commander@~2.20.0: +commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -1696,6 +1862,11 @@ copy-concurrently@^1.0.0: rimraf "^2.5.4" run-queue "^1.0.0" +core-js-pure@^3.0.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.2.1.tgz#879a23699cff46175bfd2d09158b5c50645a3c45" + integrity sha512-+qpvnYrsi/JDeQTArB7NnNc2VoMYLE1YSkziCDHgjexC2KH7OFiGhLUd3urxfyWmNjSwSW7NYXPWHMhuIJx9Ow== + core-js@^2.4.0, core-js@^2.5.0: version "2.6.9" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" @@ -1744,7 +1915,7 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -1781,6 +1952,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + crypto-browserify@3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1808,10 +1990,10 @@ crypto-random-string@^1.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= d@1: version "1.0.1" @@ -1992,7 +2174,7 @@ deferred-leveldown@~4.0.0: abstract-leveldown "~5.0.0" inherits "^2.0.3" -define-properties@^1.1.2: +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -2131,9 +2313,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.47: - version "1.3.223" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.223.tgz#3472d5260096cfc9be8b7350252a4c577f68f80a" - integrity sha512-xXFNJ+akZMtRZQYBLlGoc11lDfwj6FdWHwle/0U3vWtVaWh/MBbU25vtRCBB4lpHLmQ8Y9a6Tsb+0UONFbNXmQ== + version "1.3.281" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.281.tgz#2dbeb9f0bdffddb1662f9ca00d26c49d31dc0f7e" + integrity sha512-oxXKngPjTWRmXFy4vV9FeAkPl7wU4xMejfOY+HXjGrj4T0z9l96loWWVDLJEtbT/aPKOWKrSz6xoYxd+YJ/gJA== elliptic@6.3.3: version "6.3.3" @@ -2194,9 +2376,9 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: once "^1.4.0" enquirer@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.1.tgz#f1bf52ea38470525f41412d723a62ba6868559c6" - integrity sha512-7slmHsJY+mvnIrzD0Z0FfTFLmVJuIzRNCW72X9s35BshOoC+MI4jLJ8aPyAC/BelAirXBZB+Mu1wSqP0wpW4Kg== + version "2.3.2" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.2.tgz#1c30284907cadff5ed2404bd8396036dd3da070e" + integrity sha512-PLhTMPUXlnaIv9D3Cq3/Zr1xb7soeDDgunobyCmYLUG19n24dvC8i+ZZgm2DekGpDnx7JvFSHV7lxfM58PMtbA== dependencies: ansi-colors "^3.2.1" @@ -2231,6 +2413,22 @@ es-abstract@^1.5.0: is-regex "^1.0.4" object-keys "^1.0.12" +es-abstract@^1.5.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.15.0.tgz#8884928ec7e40a79e3c9bc812d37d10c8b24cc57" + integrity sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.0" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" + es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" @@ -2352,15 +2550,14 @@ eth-ens-namehash@2.0.8: js-sha3 "^0.5.7" eth-json-rpc-infura@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.0.tgz#62c3f516b51351038c32a548704467cec113ca8f" - integrity sha512-FLcpdxPRVBCUc7yoE+wHGvyYg2lATedP+/q7PsKvaSzQpJbgTG4ZjLnyrLanxDr6M1k/dSNa6V5QnILwjUKJcw== + version "3.2.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" + integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== dependencies: cross-fetch "^2.1.1" eth-json-rpc-middleware "^1.5.0" json-rpc-engine "^3.4.0" json-rpc-error "^2.0.0" - tape "^4.8.0" eth-json-rpc-middleware@^1.5.0: version "1.6.0" @@ -2483,14 +2680,22 @@ ethereumjs-abi@0.6.7: bn.js "^4.11.8" ethereumjs-util "^6.0.0" +ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": - version "0.6.7" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#d700d091f79c06f4e27872f4a1d7b153986cc3dd" + version "0.6.8" + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#1cfbb13862f90f0b391d8a699544d5fe4dfb8c7b" dependencies: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -ethereumjs-account@3.0.0: +ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== @@ -2508,7 +2713,7 @@ ethereumjs-account@^2.0.3: rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-block@2.2.0, ethereumjs-block@~2.2.0: +ethereumjs-block@2.2.0, ethereumjs-block@^2.2.0, ethereumjs-block@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.0.tgz#8c6c3ab4a5eff0a16d9785fbeedbe643f4dbcbef" integrity sha512-Ye+uG/L2wrp364Zihdlr/GfC3ft+zG8PdHcRtsBFNNH1CkOhxOwdB8friBU85n89uRZ9eIMAywCq0F4CwT1wAw== @@ -2546,12 +2751,28 @@ ethereumjs-blockchain@^3.4.0: safe-buffer "^5.1.2" semaphore "^1.1.0" -ethereumjs-common@^1.1.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.3.1.tgz#a5cffac41beb7ad393283b2e5aa71fadf8a9cc73" - integrity sha512-kexqNgM2q29RKoZPPjehPREeqbr/vhYfT9Ho8FVeH3f7USjBuYp1iZ1qjqklk8FSMvEKPpMJFYSOunikw30Prw== +ethereumjs-blockchain@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.1.tgz#db113dfed4fcc5197d223391f10adbc5a1b3536b" + integrity sha512-twf2yeyzeBXzCgclLyF9wZEyCKbCweM2KZdZkTsnlqGgaffgnSgY44+z+9BHUIVoWY+gxMj+XsTlTgVcbha8rg== + dependencies: + async "^2.6.1" + ethashjs "~0.0.7" + ethereumjs-block "~2.2.0" + ethereumjs-common "^1.1.0" + ethereumjs-util "~6.1.0" + flow-stoplight "^1.0.0" + level-mem "^3.0.1" + lru-cache "^5.1.1" + rlp "^2.2.2" + semaphore "^1.1.0" -ethereumjs-tx@1.3.7, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3, ethereumjs-tx@^1.3.7: +ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.1, ethereumjs-common@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.3.2.tgz#5a20831e52199a31ff4b68ef361e34c05c976ed0" + integrity sha512-GkltYRIqBLzaZLmF/K3E+g9lZ4O4FL+TtpisAlD3N+UVlR+mrtoG+TvxavqVa6PwOY4nKIEMe5pl6MrTio3Lww== + +ethereumjs-tx@1.3.7, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: version "1.3.7" resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== @@ -2559,7 +2780,15 @@ ethereumjs-tx@1.3.7, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^ ethereum-common "^0.0.18" ethereumjs-util "^5.0.0" -ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0: +ethereumjs-tx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.1.tgz#7d204e2b319156c9bc6cec67e9529424a26e8ccc" + integrity sha512-QtVriNqowCFA19X9BCRPMgdVNJ0/gMBS91TQb1DfrhsbR748g4STwxZptFAwfqehMyrF8rDwB23w87PQwru0wA== + dependencies: + ethereumjs-common "^1.3.1" + ethereumjs-util "^6.0.0" + +ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@~6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== @@ -2583,7 +2812,7 @@ ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: rlp "^2.0.0" secp256k1 "^3.0.1" -ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5: +ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" integrity sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA== @@ -2659,10 +2888,10 @@ ethereumjs-wallet@0.6.3: utf8 "^3.0.0" uuid "^3.3.2" -ethers@4.0.0-beta.1: - version "4.0.0-beta.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.1.tgz#0648268b83e0e91a961b1af971c662cdf8cbab6d" - integrity sha512-SoYhktEbLxf+fiux5SfCEwdzWENMvgIbMZD90I62s4GZD9nEjgEWy8ZboI3hck193Vs0bDoTohDISx84f2H2tw== +ethers@4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" + integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -2675,10 +2904,10 @@ ethers@4.0.0-beta.1: uuid "2.0.1" xmlhttprequest "1.8.0" -ethers@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" - integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== +ethers@^4.0.0-beta.1: + version "4.0.37" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.37.tgz#dfa70d59498663878c5e4a977d14356660ca5b90" + integrity sha512-B7bDdyQ45A5lPr6k2HOkEKMtYOuqlfy+nNf8glnRvWidkDQnToKw1bv7UyrwlbsIgY2mE03UxTVtouXcT6Vvcw== dependencies: "@types/node" "^10.3.2" aes-js "3.0.0" @@ -2686,12 +2915,12 @@ ethers@4.0.0-beta.3: elliptic "6.3.3" hash.js "1.1.3" js-sha3 "0.5.7" - scrypt-js "2.0.3" + scrypt-js "2.0.4" setimmediate "1.0.4" uuid "2.0.1" xmlhttprequest "1.8.0" -ethers@^4.0.0-beta.1, ethers@^4.0.32: +ethers@^4.0.32: version "4.0.33" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" integrity sha512-lAHkSPzBe0Vj+JrhmkEHLtUEKEheVktIjGDyE9gbzF4zf1vibjYgB57LraDHu4/ItqWVkztgsm8GWqcDMN+6vQ== @@ -2723,6 +2952,11 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter3@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" @@ -2759,6 +2993,19 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + express@^4.14.0: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -3032,6 +3279,11 @@ forwarded@~0.1.2: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + fp-ts@^1.0.0: version "1.19.5" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" @@ -3153,7 +3405,16 @@ functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -ganache-core-sc@2.7.0-sc.0: +ganache-cli@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.7.0.tgz#b59845578221bdf686cf124d007c5ee62e85a62f" + integrity sha512-9CZsClo9hl5MxGL7hkk14mie89Q94P0idh92jcV7LmppTYTCG7SHatuwcfqN7emFHArMt3fneN4QbH2do2N6Ow== + dependencies: + ethereumjs-util "6.1.0" + source-map-support "0.5.12" + yargs "13.2.4" + +ganache-core-sc@^2.7.0-sc.0: version "2.7.0-sc.0" resolved "https://registry.yarnpkg.com/ganache-core-sc/-/ganache-core-sc-2.7.0-sc.0.tgz#a802eb2b7f1f9fbe833d19752347f3dceefe55d3" integrity sha512-mlOpZs5Jdk4mIy55m7vVbknTDRViFWbSV0vnESelHH2g/yS0BVbxIH3QVjI9KjH1rMNuC56Obny/KjKOtnP5Og== @@ -3231,7 +3492,7 @@ get-stream@^2.2.0: object-assign "^4.0.1" pinkie-promise "^2.0.0" -get-stream@^4.1.0: +get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -3302,7 +3563,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@~7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0: +global-dirs@^0.1.0, global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= @@ -3377,7 +3638,7 @@ got@7.1.0, got@^7.1.0: url-parse-lax "^1.0.0" url-to-options "^1.0.1" -got@9.6.0, got@^9.3.0, got@^9.6.0: +got@9.6.0, got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== @@ -3574,11 +3835,16 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: +hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +hosted-git-info@^2.7.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" + integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== + http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" @@ -3673,9 +3939,9 @@ iferr@^0.1.5: integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== dependencies: minimatch "^3.0.4" @@ -3699,7 +3965,7 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -infer-owner@^1.0.3: +infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== @@ -3752,7 +4018,12 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= -io-ts@^1.8.6: +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +io-ts@1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== @@ -3845,6 +4116,14 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-installed-globally@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.2.0.tgz#8cde07ade508458b51f14bcda315ffaf4898de30" + integrity sha512-g3TzWCnR/eO4Q3abCwgFjOFw7uVOfxG4m8hMr/39Jcf2YvE5mHrFKqpyuraWV4zwx9XhjnVO4nY0ZI4llzl0Pg== + dependencies: + global-dirs "^0.1.1" + is-path-inside "^2.1.0" + is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -3877,6 +4156,13 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -3889,11 +4175,16 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: +is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= +is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -3931,11 +4222,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -4031,6 +4317,11 @@ js-sha3@0.5.7, js-sha3@^0.5.7: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + js-sha3@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.6.1.tgz#5b89f77a7477679877f58c4a075240934b1f95c0" @@ -4143,9 +4434,9 @@ json5@^0.5.1: integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" + integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== dependencies: minimist "^1.2.0" @@ -4232,7 +4523,7 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" -kleur@^3.0.2: +kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== @@ -4251,6 +4542,13 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + level-codec@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.1.tgz#042f4aa85e56d4328ace368c950811ba802b7247" @@ -4357,6 +4655,15 @@ level-ws@0.0.0: readable-stream "~1.0.15" xtend "~2.1.1" +level-ws@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" + integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.8" + xtend "^4.0.1" + levelup@3.1.1, levelup@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" @@ -4445,7 +4752,7 @@ lodash@4.17.14: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.2.0: +lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.0: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -4546,6 +4853,13 @@ make-fetch-happen@^5.0.0: socks-proxy-agent "^4.0.0" ssri "^6.0.0" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -4567,6 +4881,15 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + memdown@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" @@ -4627,6 +4950,19 @@ merkle-patricia-tree@2.3.2, merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2 rlp "^2.0.0" semaphore ">=1.0.1" +merkle-patricia-tree@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" + integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== + dependencies: + async "^2.6.1" + ethereumjs-util "^5.2.0" + level-mem "^3.0.1" + level-ws "^1.0.0" + readable-stream "^3.0.6" + rlp "^2.0.0" + semaphore ">=1.0.1" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -4648,11 +4984,16 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.40.0, mime-db@^1.28.0: +mime-db@1.40.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== +mime-db@^1.28.0: + version "1.42.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" + integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== + mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.24" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" @@ -4670,6 +5011,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -4722,6 +5068,14 @@ minipass@^2.2.1, minipass@^2.3.5: safe-buffer "^5.1.2" yallist "^3.0.0" +minipass@^2.8.6: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + minizlib@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" @@ -4827,7 +5181,7 @@ nan@2.13.2: resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== -nan@^2.0.8, nan@^2.14.0, nan@^2.2.1, nan@^2.3.3: +nan@^2.0.8, nan@^2.13.2, nan@^2.14.0, nan@^2.2.1, nan@^2.3.3: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -4862,6 +5216,11 @@ next-tick@^1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-alias@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/node-alias/-/node-alias-1.0.4.tgz#1f1b916b56b9ea241c0135f97ced6940f556f292" @@ -4898,6 +5257,11 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= +node-fetch@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -4906,11 +5270,6 @@ node-fetch@~1.7.1: encoding "^0.1.11" is-stream "^1.0.1" -node-http-xhr@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/node-http-xhr/-/node-http-xhr-1.3.4.tgz#0dbf827c2858f40c57a79375fc4be07c8ff46f55" - integrity sha512-0bA08/2RKWxw6pMkOVd3KP+0F5+ifQLMMTDxrCgxlgkoU1N8DhCbCSAYEqpgaVYM2smvbVVewiXjW+8AyoLfxQ== - nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -4948,27 +5307,27 @@ npm-bundled@^1.0.1: integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== npm-check-updates@^3.1.11: - version "3.1.20" - resolved "https://registry.yarnpkg.com/npm-check-updates/-/npm-check-updates-3.1.20.tgz#9dd719bc04af9c273b33b44a7d5368d5e85ae9c2" - integrity sha512-mc9BAoOYSTwP/IvoA+ofdkWSipwRvhgC0qop1PvlMZojgzi7N/dykdxOIWrw0OlZPnEKvXkKFEuPk97LrvXE1A== + version "3.1.24" + resolved "https://registry.yarnpkg.com/npm-check-updates/-/npm-check-updates-3.1.24.tgz#bbb27267c786aa4c052cfd6f5f45b02ae00c021f" + integrity sha512-8CxlXsSPo8RCAHHqycxU9gcDcSkoBI0I2bkh37HJry2VJhqGxeVnEVq8vtFcigzIRrUgbSOyKgSm+jvu3ookMw== dependencies: chalk "^2.4.2" cint "^8.2.1" cli-table "^0.3.1" - commander "^2.20.0" + commander "^3.0.2" fast-diff "^1.2.0" find-up "4.1.0" get-stdin "^7.0.0" json-parse-helpfulerror "^1.0.3" libnpmconfig "^1.2.1" - lodash "^4.17.13" + lodash "^4.17.15" node-alias "^1.0.4" - pacote "^9.5.1" + pacote "^9.5.8" progress "^2.0.3" - prompts "^2.1.0" + prompts "^2.2.1" rc-config-loader "^2.0.4" requireg "^0.2.2" - semver "^6.2.0" + semver "^6.3.0" semver-utils "^1.1.4" spawn-please "^0.3.0" update-notifier "^3.0.1" @@ -4982,36 +5341,36 @@ npm-conf@^1.1.0: pify "^3.0.0" npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" - integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" + integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== dependencies: - hosted-git-info "^2.6.0" + hosted-git-info "^2.7.1" osenv "^0.1.5" - semver "^5.5.0" + semver "^5.6.0" validate-npm-package-name "^3.0.0" npm-packlist@^1.1.12: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + version "1.4.6" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" + integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" -npm-pick-manifest@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" - integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA== +npm-pick-manifest@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" + integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== dependencies: figgy-pudding "^3.5.1" npm-package-arg "^6.0.0" semver "^5.4.1" npm-registry-fetch@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.0.tgz#5ef75845b605855c7964472542c25da172af8677" - integrity sha512-Jllq35Jag8dtv0M17ue74XtdQTyqKzuAYGiX9mAjOhkmNjib3bBUgK6mUY61+AHnXeSRobQkpY3/xIOS/omptw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.2.tgz#2b1434f93ccbe6b6385f8e45f45db93e16921d7a" + integrity sha512-Z0IFtPEozNdeZRPh3aHHxdG+ZRpzcbQaJLthsm3VhNf6DScicTFRHZzK82u8RsJUsUHkX+QH/zcB/5pmd20H4A== dependencies: JSONStream "^1.3.4" bluebird "^3.5.1" @@ -5019,6 +5378,7 @@ npm-registry-fetch@^4.0.0: lru-cache "^5.1.1" make-fetch-happen "^5.0.0" npm-package-arg "^6.1.0" + safe-buffer "^5.2.0" npm-run-path@^2.0.0: version "2.0.2" @@ -5081,12 +5441,12 @@ object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@~1.6.0: +object-inspect@^1.6.0, object-inspect@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== -object-keys@^1.0.12: +object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -5096,6 +5456,14 @@ object-keys@~0.4.0: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + oboe@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" @@ -5163,6 +5531,15 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5191,6 +5568,11 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + p-event@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" @@ -5208,6 +5590,11 @@ p-is-promise@^1.1.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -5215,13 +5602,20 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== dependencies: p-try "^2.0.0" +p-limit@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -5287,16 +5681,18 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pacote@^9.5.1: - version "9.5.4" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.4.tgz#8baa26f3d1326d13dc2fe0fe84040a364ae30aad" - integrity sha512-nWr0ari6E+apbdoN0hToTKZElO5h4y8DGFa2pyNA5GQIdcP0imC96bA0bbPw1gpeguVIiUgHHaAlq/6xfPp8Qw== +pacote@^9.5.8: + version "9.5.8" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.8.tgz#23480efdc4fa74515855c9ecf39cf64078f99786" + integrity sha512-0Tl8Oi/K0Lo4MZmH0/6IsT3gpGf9eEAznLXEQPKgPq7FscnbUOyopnVpwXlnQdIbCUaojWy1Wd7VMyqfVsRrIw== dependencies: bluebird "^3.5.3" - cacache "^12.0.0" + cacache "^12.0.2" + chownr "^1.1.2" figgy-pudding "^3.5.1" get-stream "^4.1.0" glob "^7.1.3" + infer-owner "^1.0.4" lru-cache "^5.1.1" make-fetch-happen "^5.0.0" minimatch "^3.0.4" @@ -5306,7 +5702,7 @@ pacote@^9.5.1: normalize-package-data "^2.4.0" npm-package-arg "^6.1.0" npm-packlist "^1.1.12" - npm-pick-manifest "^2.2.3" + npm-pick-manifest "^3.0.0" npm-registry-fetch "^4.0.0" osenv "^0.1.5" promise-inflight "^1.0.1" @@ -5316,16 +5712,16 @@ pacote@^9.5.1: safe-buffer "^5.1.2" semver "^5.6.0" ssri "^6.0.1" - tar "^4.4.8" + tar "^4.4.10" unique-filename "^1.1.1" which "^1.3.1" parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== dependencies: - cyclist "~0.2.2" + cyclist "^1.0.1" inherits "^2.0.3" readable-stream "^2.1.5" @@ -5377,12 +5773,12 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= @@ -5414,7 +5810,7 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= -pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== @@ -5535,13 +5931,13 @@ promise-to-callback@^1.0.0: is-fn "^1.0.0" set-immediate-shim "^1.0.1" -prompts@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db" - integrity sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg== +prompts@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35" + integrity sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw== dependencies: - kleur "^3.0.2" - sisteransi "^1.0.0" + kleur "^3.0.3" + sisteransi "^1.0.3" proto-list@~1.2.1: version "1.2.4" @@ -5683,6 +6079,11 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.7.0: + version "6.9.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409" + integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -5772,7 +6173,7 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -5795,6 +6196,15 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@^3.0.6: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@~1.0.15: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" @@ -5984,7 +6394,14 @@ reusify@^1.0.0: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@2, rimraf@^2.5.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^2.2.8, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -5999,7 +6416,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rlp@^2.0.0, rlp@^2.2.1: +rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.3.tgz#7f94aef86cec412df87d5ea1d8cb116a47d45f0e" integrity sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ== @@ -6029,7 +6446,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -6135,7 +6552,7 @@ semver-utils@^1.1.4: resolved "https://registry.yarnpkg.com/semver-utils/-/semver-utils-1.1.4.tgz#cf0405e669a57488913909fc1c3f29bf2a4871e2" integrity sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA== -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== @@ -6145,7 +6562,12 @@ semver@6.2.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== -semver@^6.0.0, semver@^6.2.0: +semver@^5.0.3, semver@^5.3.0, semver@^5.4.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -6275,10 +6697,10 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" -sisteransi@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.2.tgz#ec57d64b6f25c4f26c0e2c7dd23f2d7f12f7e418" - integrity sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w== +sisteransi@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" + integrity sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg== slash@^1.0.0: version "1.0.0" @@ -6311,19 +6733,19 @@ socks@~2.3.2: ip "^1.1.5" smart-buffer "4.0.2" -solc@0.5.8: - version "0.5.8" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.8.tgz#a0aa2714082fc406926f5cb384376d7408080611" - integrity sha512-RQ2SlwPBOBSV7ktNQJkvbiQks3t+3V9dsqD014EdstxnJzSxBuOvbt3P5QXpNPYW1DsEmF7dhOaT3JL7yEae/A== +solc@0.5.11: + version "0.5.11" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.11.tgz#5905261191d01befd78ef52610a006820022ee8f" + integrity sha512-F8avCCVDYnJzvIm/ITsU11GFNdFI4HaNsME+zw9lK5a3ojD3LZN2Op2cIfWg7w1HeRYRiMOU1dM77saX6jUIKw== dependencies: command-exists "^1.2.8" fs-extra "^0.30.0" - keccak "^1.0.2" + js-sha3 "0.8.0" memorystream "^0.3.1" require-from-string "^2.0.0" semver "^5.5.0" tmp "0.0.33" - yargs "^11.0.0" + yargs "^13.2.0" solc@^0.5.10: version "0.5.10" @@ -6339,13 +6761,18 @@ solc@^0.5.10: tmp "0.0.33" yargs "^11.0.0" -solidity-parser-antlr@^0.4.2, solidity-parser-antlr@^0.4.7: +solidity-parser-antlr@0.4.7: version "0.4.7" resolved "https://registry.yarnpkg.com/solidity-parser-antlr/-/solidity-parser-antlr-0.4.7.tgz#8e18867c95a956958ed008371e43f9e571dee6af" integrity sha512-iVjNhgqkXw+o+0E+xoLcji+3KuXLe8Rm8omUuVGhsV14+ZsTwQ70nhBRXg8O3t9xwdS0iST1q9NJ5IqHnqpWkA== dependencies: npm-check-updates "^3.1.11" +solidity-parser-antlr@^0.4.2: + version "0.4.11" + resolved "https://registry.yarnpkg.com/solidity-parser-antlr/-/solidity-parser-antlr-0.4.11.tgz#af43e1f13b3b88309a875455f5d6e565b05ee5f1" + integrity sha512-4jtxasNGmyC0midtjH/lTFPZYvTTUMy6agYcF+HoMnzW8+cqo3piFrINb4ZCzpPW+7tTVFCGa5ubP34zOzeuMg== + sort-keys-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" @@ -6367,7 +6794,7 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" -source-map-support@0.5.12, source-map-support@^0.5.12: +source-map-support@0.5.12: version "0.5.12" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== @@ -6382,6 +6809,14 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -6535,6 +6970,29 @@ string.prototype.trim@^1.1.2, string.prototype.trim@~1.1.2: es-abstract "^1.5.0" function-bind "^1.0.2" +string.prototype.trimleft@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -6656,7 +7114,7 @@ swarm-js@0.1.37: tar.gz "^1.0.5" xhr-request-promise "^0.1.2" -swarm-js@0.1.39, swarm-js@^0.1.39: +swarm-js@0.1.39: version "0.1.39" resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== @@ -6674,7 +7132,7 @@ swarm-js@0.1.39, swarm-js@^0.1.39: tar "^4.0.2" xhr-request-promise "^0.1.2" -tape@^4.6.3, tape@^4.8.0: +tape@^4.6.3: version "4.11.0" resolved "https://registry.yarnpkg.com/tape/-/tape-4.11.0.tgz#63d41accd95e45a23a874473051c57fdbc58edc1" integrity sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA== @@ -6726,7 +7184,7 @@ tar@^2.1.1: fstream "^1.0.12" inherits "2" -tar@^4.0.2, tar@^4.4.8: +tar@^4.0.2: version "4.4.10" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== @@ -6739,6 +7197,19 @@ tar@^4.0.2, tar@^4.4.8: safe-buffer "^5.1.2" yallist "^3.0.3" +tar@^4.4.10: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -6788,6 +7259,17 @@ timed-out@^4.0.0, timed-out@^4.0.1: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= +tiny-secp256k1@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.3.tgz#e93b1e1bf62e9bd1ad3ab24af27ff6127ce0e077" + integrity sha512-ZpobrhOtHP98VYEN51IYQH1YcrbFpnxFhI6ceWa3OEbJn7eHvSd8YFjGPxbedGCy7PNYU1v/+BRsdvyr5uRd4g== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + tmp@0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6854,11 +7336,6 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -truffle-blockchain-utils@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.10.tgz#18b772673635a95a893f7083f7be6bd62227462b" - integrity sha512-gVvagLCvYD0QXfnkxy6I48P6O+d7TEY0smc2VFuwldl1/clLVWE+KfBO/jFMaAz+nupTQeKvPhNTeyh3JAsCeA== - truffle-config@^1.1.18: version "1.1.18" resolved "https://registry.yarnpkg.com/truffle-config/-/truffle-config-1.1.18.tgz#3bef981cc54f1e87371154e38cdec02881810b00" @@ -6871,45 +7348,11 @@ truffle-config@^1.1.18: truffle-error "^0.0.5" truffle-provider "^0.1.14" -truffle-contract-schema@^3.0.11: - version "3.0.11" - resolved "https://registry.yarnpkg.com/truffle-contract-schema/-/truffle-contract-schema-3.0.11.tgz#202f6982b51bcad032b7ff2a8d5837853fb69301" - integrity sha512-YcgSOlrufi6VtnXg8LU5Ma7JHzHpnZQxzB1PSWnb+JOTc1nL02XRoCWTgEO7PkJnFgf6yrwOpW0ajSwHk3zQ7Q== - dependencies: - ajv "^6.10.0" - crypto-js "^3.1.9-1" - debug "^4.1.0" - -truffle-contract@^4.0.14: - version "4.0.25" - resolved "https://registry.yarnpkg.com/truffle-contract/-/truffle-contract-4.0.25.tgz#dc58c3ad20a4b1654efc0d55020e3bb8b9adac66" - integrity sha512-ngy+ljTCSs/Arv4/9xUjq6mBdAHvQjFvJGqMcBDoNZSXUdvuW4qmX9gu/cOFEt2hdsBcpt0sx7DrXGlY4O97ww== - dependencies: - bignumber.js "^7.2.1" - ethers "^4.0.0-beta.1" - truffle-blockchain-utils "^0.0.10" - truffle-contract-schema "^3.0.11" - truffle-error "^0.0.5" - truffle-interface-adapter "^0.2.0" - web3 "1.0.0-beta.37" - web3-core-promievent "1.0.0-beta.37" - web3-eth-abi "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - truffle-error@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.5.tgz#6b5740c9f3aac74f47b85d654fff7fe2c1fc5e0e" integrity sha512-JpzPLMPSCE0vaZ3vH5NO5u42GpMj/Y1SRBkQ6b69PSw3xMSH1umApN32cEcg1nnh8q5FNYc5FnKu0m4tiBffyQ== -truffle-interface-adapter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/truffle-interface-adapter/-/truffle-interface-adapter-0.2.0.tgz#8f998dc27c039e5bb93b44c37726f8c32cfd026d" - integrity sha512-NMj2gGr96/Ny5P2CvVzvkMAYXFjZfkdLCLt0kOiYGltoTt7EVP+HVLpYUfvxHjmEYytGdjXjrt/1srCfbPbAsQ== - dependencies: - bn.js "^4.11.8" - ethers "^4.0.32" - web3 "1.0.0-beta.37" - truffle-interface-adapter@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/truffle-interface-adapter/-/truffle-interface-adapter-0.2.3.tgz#475a425dd8eb27fbe54486b0b25e697bb184d0fa" @@ -6943,11 +7386,6 @@ ts-essentials@^2.0.7: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" @@ -7017,6 +7455,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + typewise-core@^1.2, typewise-core@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" @@ -7160,11 +7603,19 @@ utf8@3.0.0, utf8@^3.0.0: resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -7218,15 +7669,6 @@ web3-bzz@1.0.0-beta.35: swarm-js "0.1.37" underscore "1.8.3" -web3-bzz@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.37.tgz#59e3e4f5a9d732731008fe9165c3ec8bf85d502f" - integrity sha512-E+dho49Nsm/QpQvYWOF35YDsQrMvLB19AApENxhlQsu6HpWQt534DQul0t3Y/aAh8rlKD6Kanxt8LhHDG3vejQ== - dependencies: - got "7.1.0" - swarm-js "0.1.37" - underscore "1.8.3" - web3-bzz@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.1.tgz#c3bd1e8f0c02a13cd6d4e3c3e9e1713f144f6f0d" @@ -7245,15 +7687,6 @@ web3-core-helpers@1.0.0-beta.35: web3-eth-iban "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-core-helpers@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.37.tgz#04ec354b7f5c57234c309eea2bda9bf1f2fe68ba" - integrity sha512-efaLOzN28RMnbugnyelgLwPWWaSwElQzcAJ/x3PZu+uPloM/lE5x0YuBKvIh7/PoSMlHqtRWj1B8CpuQOUQ5Ew== - dependencies: - underscore "1.8.3" - web3-eth-iban "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-core-helpers@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz#f5f32d71c60a4a3bd14786118e633ce7ca6d5d0d" @@ -7274,17 +7707,6 @@ web3-core-method@1.0.0-beta.35: web3-core-subscriptions "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-core-method@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.37.tgz#53d148e63f818b23461b26307afdfbdaa9457744" - integrity sha512-pKWFUeqnVmzx3VrZg+CseSdrl/Yrk2ioid/HzolNXZE6zdoITZL0uRjnsbqXGEzgRRd1Oe/pFndpTlRsnxXloA== - dependencies: - underscore "1.8.3" - web3-core-helpers "1.0.0-beta.37" - web3-core-promievent "1.0.0-beta.37" - web3-core-subscriptions "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-core-method@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.1.tgz#9df1bafa2cd8be9d9937e01c6a47fc768d15d90a" @@ -7304,14 +7726,6 @@ web3-core-promievent@1.0.0-beta.35: any-promise "1.3.0" eventemitter3 "1.1.1" -web3-core-promievent@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.37.tgz#4e51c469d0a7ac0a969885a4dbcde8504abe5b02" - integrity sha512-GTF2r1lP8nJBeA5Gxq5yZpJy9l8Fb9CXGZPfF8jHvaRdQHtm2Z+NDhqYmF833lcdkokRSyfPcXlz1mlWeClFpg== - dependencies: - any-promise "1.3.0" - eventemitter3 "1.1.1" - web3-core-promievent@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz#003e8a3eb82fb27b6164a6d5b9cad04acf733838" @@ -7331,17 +7745,6 @@ web3-core-requestmanager@1.0.0-beta.35: web3-providers-ipc "1.0.0-beta.35" web3-providers-ws "1.0.0-beta.35" -web3-core-requestmanager@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.37.tgz#721a75df5920621bff42d9d74f7a64413675d56b" - integrity sha512-66VUqye5BGp1Zz1r8psCxdNH+GtTjaFwroum2Osx+wbC5oRjAiXkkadiitf6wRb+edodjEMPn49u7B6WGNuewQ== - dependencies: - underscore "1.8.3" - web3-core-helpers "1.0.0-beta.37" - web3-providers-http "1.0.0-beta.37" - web3-providers-ipc "1.0.0-beta.37" - web3-providers-ws "1.0.0-beta.37" - web3-core-requestmanager@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz#fa2e2206c3d738db38db7c8fe9c107006f5c6e3d" @@ -7362,15 +7765,6 @@ web3-core-subscriptions@1.0.0-beta.35: underscore "1.8.3" web3-core-helpers "1.0.0-beta.35" -web3-core-subscriptions@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.37.tgz#40de5e2490cc05b15faa8f935c97fd48d670cd9a" - integrity sha512-FdXl8so9kwkRRWziuCSpFsAuAdg9KvpXa1fQlT16uoGcYYfxwFO/nkwyBGQzkZt7emShI2IRugcazyPCZDwkOA== - dependencies: - eventemitter3 "1.1.1" - underscore "1.8.3" - web3-core-helpers "1.0.0-beta.37" - web3-core-subscriptions@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz#8c2368a839d4eec1c01a4b5650bbeb82d0e4a099" @@ -7390,16 +7784,6 @@ web3-core@1.0.0-beta.35: web3-core-requestmanager "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-core@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.37.tgz#66c2c7000772c9db36d737ada31607ace09b7e90" - integrity sha512-cIwEqCj7OJyefQNauI0HOgW4sSaOQ98V99H2/HEIlnCZylsDzfw7gtQUdwnRFiIyIxjbWy3iWsjwDPoXNPZBYg== - dependencies: - web3-core-helpers "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-core-requestmanager "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-core@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.1.tgz#7278b58fb6495065e73a77efbbce781a7fddf1a9" @@ -7420,15 +7804,6 @@ web3-eth-abi@1.0.0-beta.35: web3-core-helpers "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-eth-abi@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.37.tgz#55592fa9cd2427d9f0441d78f3b8d0c1359a2a24" - integrity sha512-g9DKZGM2OqwKp/tX3W/yihcj7mQCtJ6CXyZXEIZfuDyRBED/iSEIFfieDOd+yo16sokLMig6FG7ADhhu+19hdA== - dependencies: - ethers "4.0.0-beta.1" - underscore "1.8.3" - web3-utils "1.0.0-beta.37" - web3-eth-abi@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz#9b915b1c9ebf82f70cca631147035d5419064689" @@ -7454,22 +7829,6 @@ web3-eth-accounts@1.0.0-beta.35: web3-core-method "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-eth-accounts@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.37.tgz#0a5a9f14a6c3bd285e001c15eb3bb38ffa4b5204" - integrity sha512-uvbHL62/zwo4GDmwKdqH9c/EgYd8QVnAfpVw8D3epSISpgbONNY7Hr4MRMSd/CqAP12l2Ls9JVQGLhhC83bW6g== - dependencies: - any-promise "1.3.0" - crypto-browserify "3.12.0" - eth-lib "0.2.7" - scrypt.js "0.2.0" - underscore "1.8.3" - uuid "2.0.1" - web3-core "1.0.0-beta.37" - web3-core-helpers "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-eth-accounts@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz#2741a8ef337a7219d57959ac8bd118b9d68d63cf" @@ -7501,20 +7860,6 @@ web3-eth-contract@1.0.0-beta.35: web3-eth-abi "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-eth-contract@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.37.tgz#87f93c95ed16f320ba54943b7886890de6766013" - integrity sha512-h1B3A8Z/C7BlnTCHkrWbXZQTViDxfR12lKMeTkT8Sqj5phFmxrBlPE4ORy4lf1Dk5b23mZYE0r/IRACx4ThCrQ== - dependencies: - underscore "1.8.3" - web3-core "1.0.0-beta.37" - web3-core-helpers "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-core-promievent "1.0.0-beta.37" - web3-core-subscriptions "1.0.0-beta.37" - web3-eth-abi "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-eth-contract@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz#3542424f3d341386fd9ff65e78060b85ac0ea8c4" @@ -7529,20 +7874,6 @@ web3-eth-contract@1.2.1: web3-eth-abi "1.2.1" web3-utils "1.2.1" -web3-eth-ens@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.37.tgz#714ecb01eb447ee3eb39b2b20a10ae96edb1f01f" - integrity sha512-dR3UkrVzdRrJhfP57xBPx0CMiVnCcYFvh+u2XMkGydrhHgupSUkjqGr89xry/j1T0BkuN9mikpbyhdCVMXqMbg== - dependencies: - eth-ens-namehash "2.0.8" - underscore "1.8.3" - web3-core "1.0.0-beta.37" - web3-core-helpers "1.0.0-beta.37" - web3-core-promievent "1.0.0-beta.37" - web3-eth-abi "1.0.0-beta.37" - web3-eth-contract "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-eth-ens@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz#a0e52eee68c42a8b9865ceb04e5fb022c2d971d5" @@ -7565,14 +7896,6 @@ web3-eth-iban@1.0.0-beta.35: bn.js "4.11.6" web3-utils "1.0.0-beta.35" -web3-eth-iban@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.37.tgz#313a3f18ae2ab00ba98678ea1156b09ef32a3655" - integrity sha512-WQRniGJFxH/XCbd7miO6+jnUG+6bvuzfeufPIiOtCbeIC1ypp1kSqER8YVBDrTyinU1xnf1U5v0KBZ2yiWBJxQ== - dependencies: - bn.js "4.11.6" - web3-utils "1.0.0-beta.37" - web3-eth-iban@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz#2c3801718946bea24e9296993a975c80b5acf880" @@ -7592,17 +7915,6 @@ web3-eth-personal@1.0.0-beta.35: web3-net "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-eth-personal@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.37.tgz#187472f51861e2b6d45da43411801bc91a859f9a" - integrity sha512-B4dZpGbD+nGnn48i6nJBqrQ+HB7oDmd+Q3wGRKOsHSK5HRWO/KwYeA7wgwamMAElkut50lIsT9EJl4Apfk3G5Q== - dependencies: - web3-core "1.0.0-beta.37" - web3-core-helpers "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-net "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-eth-personal@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz#244e9911b7b482dc17c02f23a061a627c6e47faf" @@ -7632,25 +7944,6 @@ web3-eth@1.0.0-beta.35: web3-net "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-eth@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.37.tgz#0e8ffcd857a5f85ae4b5f052ad831ca5c56f4f74" - integrity sha512-Eb3aGtkz3G9q+Z9DKgSQNbn/u8RtcZQQ0R4sW9hy5KK47GoT6vab5c6DiD3QWzI0BzitHzR5Ji+3VHf/hPUGgw== - dependencies: - underscore "1.8.3" - web3-core "1.0.0-beta.37" - web3-core-helpers "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-core-subscriptions "1.0.0-beta.37" - web3-eth-abi "1.0.0-beta.37" - web3-eth-accounts "1.0.0-beta.37" - web3-eth-contract "1.0.0-beta.37" - web3-eth-ens "1.0.0-beta.37" - web3-eth-iban "1.0.0-beta.37" - web3-eth-personal "1.0.0-beta.37" - web3-net "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-eth@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.1.tgz#b9989e2557c73a9e8ffdc107c6dafbe72c79c1b0" @@ -7679,15 +7972,6 @@ web3-net@1.0.0-beta.35: web3-core-method "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3-net@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.37.tgz#b494136043f3c6ba84fe4a47d4c028c2a63c9a8e" - integrity sha512-xG/uBtMdDa1UMXw9KjDUgf3fXA/fDEJUYUS0TDn+U9PMgngA+UVECHNNvQTrVVDxEky38V3sahwIDiopNsQdsw== - dependencies: - web3-core "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3-net@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.1.tgz#edd249503315dd5ab4fa00220f6509d95bb7ab10" @@ -7731,14 +8015,6 @@ web3-providers-http@1.0.0-beta.35: web3-core-helpers "1.0.0-beta.35" xhr2-cookies "1.1.0" -web3-providers-http@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.37.tgz#c06efd60e16e329e25bd268d2eefc68d82d13651" - integrity sha512-FM/1YDB1jtZuTo78habFj7S9tNHoqt0UipdyoQV29b8LkGKZV9Vs3is8L24hzuj1j/tbwkcAH+ewIseHwu0DTg== - dependencies: - web3-core-helpers "1.0.0-beta.37" - xhr2-cookies "1.1.0" - web3-providers-http@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.1.tgz#c93ea003a42e7b894556f7e19dd3540f947f5013" @@ -7756,15 +8032,6 @@ web3-providers-ipc@1.0.0-beta.35: underscore "1.8.3" web3-core-helpers "1.0.0-beta.35" -web3-providers-ipc@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.37.tgz#55d247e7197257ca0c3e4f4b0fe1561311b9d5b9" - integrity sha512-NdRPRxYMIU0C3u18NI8u4bwbhI9pCg5nRgDGYcmSAx5uOBxiYcQy+hb0WkJRRhBoyIXJmy+s26FoH8904+UnPg== - dependencies: - oboe "2.1.3" - underscore "1.8.3" - web3-core-helpers "1.0.0-beta.37" - web3-providers-ipc@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz#017bfc687a8fc5398df2241eb98f135e3edd672c" @@ -7783,15 +8050,6 @@ web3-providers-ws@1.0.0-beta.35: web3-core-helpers "1.0.0-beta.35" websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" -web3-providers-ws@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.37.tgz#77c15aebc00b75d760d22d063ac2e415bdbef72f" - integrity sha512-8p6ZLv+1JYa5Vs8oBn33Nn3VGFBbF+wVfO+b78RJS1Qf1uIOzjFVDk3XwYDD7rlz9G5BKpxhaQw+6EGQ7L02aw== - dependencies: - underscore "1.8.3" - web3-core-helpers "1.0.0-beta.37" - websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" - web3-providers-ws@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz#2d941eaf3d5a8caa3214eff8dc16d96252b842cb" @@ -7811,16 +8069,6 @@ web3-shh@1.0.0-beta.35: web3-core-subscriptions "1.0.0-beta.35" web3-net "1.0.0-beta.35" -web3-shh@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.37.tgz#3246ce5229601b525020828a56ee283307057105" - integrity sha512-h5STG/xqZNQWtCLYOu7NiMqwqPea8SfkKQUPUFxXKIPVCFVKpHuQEwW1qcPQRJMLhlQIv17xuoUe1A+RzDNbrw== - dependencies: - web3-core "1.0.0-beta.37" - web3-core-method "1.0.0-beta.37" - web3-core-subscriptions "1.0.0-beta.37" - web3-net "1.0.0-beta.37" - web3-shh@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.1.tgz#4460e3c1e07faf73ddec24ccd00da46f89152b0c" @@ -7844,19 +8092,6 @@ web3-utils@1.0.0-beta.35: underscore "1.8.3" utf8 "2.1.1" -web3-utils@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.37.tgz#ab868a90fe5e649337e38bdaf72133fcbf4d414d" - integrity sha512-kA1fyhO8nKgU21wi30oJQ/ssvu+9srMdjOTKbHYbQe4ATPcr5YNwwrxG3Bcpbu1bEwRUVKHCkqi+wTvcAWBdlQ== - dependencies: - bn.js "4.11.6" - eth-lib "0.1.27" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randomhex "0.1.5" - underscore "1.8.3" - utf8 "2.1.1" - web3-utils@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.1.tgz#21466e38291551de0ab34558de21512ac4274534" @@ -7896,19 +8131,6 @@ web3@1.0.0-beta.35: web3-shh "1.0.0-beta.35" web3-utils "1.0.0-beta.35" -web3@1.0.0-beta.37: - version "1.0.0-beta.37" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.37.tgz#b42c30e67195f816cd19d048fda872f70eca7083" - integrity sha512-8XLgUspdzicC/xHG82TLrcF/Fxzj2XYNJ1KTYnepOI77bj5rvpsxxwHYBWQ6/JOjk0HkZqoBfnXWgcIHCDhZhQ== - dependencies: - web3-bzz "1.0.0-beta.37" - web3-core "1.0.0-beta.37" - web3-eth "1.0.0-beta.37" - web3-eth-personal "1.0.0-beta.37" - web3-net "1.0.0-beta.37" - web3-shh "1.0.0-beta.37" - web3-utils "1.0.0-beta.37" - web3@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.1.tgz#5d8158bcca47838ab8c2b784a2dee4c3ceb4179b" @@ -7922,31 +8144,6 @@ web3@1.2.1: web3-shh "1.2.1" web3-utils "1.2.1" -web3x@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/web3x/-/web3x-2.0.4.tgz#0d5d0f1f08b394dca9a082ddb8e1715b11b78066" - integrity sha512-fyRgoSo3XtUWXApLxXb3ntUOoQ8aaRna3K7kr5iFPNLrhwzEbYihXeQTK9s0HV6Gf+NahQZpgOd61P4K4nORFA== - dependencies: - "@types/bn.js" "^4.11.2" - "@types/node" "^10.12.0" - "@types/ws" "^6.0.1" - bip39 "^2.5.0" - bn.js "^4.11.8" - browserify-aes "^1.2.0" - elliptic "^6.4.0" - got "^9.3.0" - hdkey "^1.1.0" - idna-uts46-hx "^2.3.1" - isomorphic-ws "^4.0.1" - mkdirp "^0.5.1" - node-http-xhr "^1.3.4" - pbkdf2 "^3.0.17" - randombytes "^2.0.6" - swarm-js "^0.1.39" - tslib "^1.9.3" - utf8 "^3.0.0" - ws "^6.1.0" - websocket@1.0.29, "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis": version "1.0.29" resolved "https://codeload.github.com/web3-js/WebSocket-Node/tar.gz/b134a75541b5db59668df81c03e926cd5f325077" @@ -7990,6 +8187,13 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= + dependencies: + bs58check "<3.0.0" + wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -8047,13 +8251,6 @@ ws@^5.1.1: dependencies: async-limiter "~1.0.0" -ws@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - dependencies: - async-limiter "~1.0.0" - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -8138,7 +8335,7 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== -yargs-parser@^13.0.0, yargs-parser@^13.1.1: +yargs-parser@^13.0.0, yargs-parser@^13.1.0, yargs-parser@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== @@ -8153,6 +8350,23 @@ yargs-parser@^9.0.2: dependencies: camelcase "^4.1.0" +yargs@13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + yargs@^11.0.0: version "11.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" @@ -8171,7 +8385,7 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" -yargs@^13.2.2: +yargs@^13.2.0, yargs@^13.2.2: version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== From 0bc67b8a344d661db05ad158e0381b1a61231413 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 13 Oct 2019 16:52:01 -0700 Subject: [PATCH 02/21] Update test fixtures and plugin utils for Buidler (#422) --- dist/plugin-assets/plugin.utils.js | 209 +----------------- dist/plugin-assets/truffle.utils.js | 206 +++++++++++++++++ dist/truffle.plugin.js | 16 +- lib/validator.js | 5 - .../assets/SimpleError.sol | 0 .../{truffle => generic}/assets/asset.js | 0 .../contracts/Migrations.sol | 0 .../migrations/1_initial.js | 0 .../{truffle => generic}/test/.marker | 0 .../projects/bad-solcoverjs/buidler.config.js | 1 + .../projects/import-paths/buidler.config.js | 1 + .../projects/libraries/buidler.config.js | 1 + .../projects/libraries/test/libraries.js | 20 +- .../multiple-migrations/buidler.config.js | 1 + .../projects/no-sources/buidler.config.js | 1 + .../projects/skipping/buidler.config.js | 1 + .../projects/test-files/buidler.config.js | 1 + .../projects/test-files/test/globby_b.js | 2 +- .../projects/test-files/test/globby_c.js | 2 +- .../projects/test-files/test/specific_a.js | 2 +- test/sources/js/block-gas-limit.js | 4 +- test/sources/js/empty.js | 11 +- test/sources/js/inheritance.js | 16 +- test/sources/js/only-call.js | 20 +- test/sources/js/pureview.js | 6 +- test/sources/js/simple.js | 2 +- test/sources/js/sol-parse-fail.js | 17 -- test/sources/js/testrpc-options.js | 13 +- test/sources/js/totallyPure.js | 19 +- test/sources/js/truffle-crash.js | 4 +- test/sources/js/truffle-test-fail.js | 15 +- test/sources/js/wallet.js | 2 +- test/sources/solidity/contracts/app/Proxy.sol | 2 +- test/units/truffle/errors.js | 2 +- test/units/truffle/flags.js | 2 +- test/units/truffle/standard.js | 6 +- ...{integration.truffle.js => integration.js} | 84 +++++-- 37 files changed, 367 insertions(+), 327 deletions(-) create mode 100644 dist/plugin-assets/truffle.utils.js rename test/integration/{truffle => generic}/assets/SimpleError.sol (100%) rename test/integration/{truffle => generic}/assets/asset.js (100%) rename test/integration/{truffle => generic}/contracts/Migrations.sol (100%) rename test/integration/{truffle => generic}/migrations/1_initial.js (100%) rename test/integration/{truffle => generic}/test/.marker (100%) create mode 100644 test/integration/projects/bad-solcoverjs/buidler.config.js create mode 100644 test/integration/projects/import-paths/buidler.config.js create mode 100644 test/integration/projects/libraries/buidler.config.js create mode 100644 test/integration/projects/multiple-migrations/buidler.config.js create mode 100644 test/integration/projects/no-sources/buidler.config.js create mode 100644 test/integration/projects/skipping/buidler.config.js create mode 100644 test/integration/projects/test-files/buidler.config.js delete mode 100644 test/sources/js/sol-parse-fail.js rename test/util/{integration.truffle.js => integration.js} (71%) diff --git a/dist/plugin-assets/plugin.utils.js b/dist/plugin-assets/plugin.utils.js index 948013a3..cabbf0c7 100644 --- a/dist/plugin-assets/plugin.utils.js +++ b/dist/plugin-assets/plugin.utils.js @@ -10,11 +10,7 @@ const PluginUI = require('./truffle.ui'); const path = require('path'); const fs = require('fs-extra'); -const dir = require('node-dir'); -const globby = require('globby'); const shell = require('shelljs'); -const globalModules = require('global-modules'); -const TruffleProvider = require('@truffle/provider'); // === // UI @@ -83,7 +79,7 @@ function toRelativePath(pathToFile, pathToParent){ * @return {Object} temp paths */ function getTempLocations(config){ - const cwd = config.working_directory; + const cwd = config.workingDir; const contractsDirName = '.coverage_contracts'; const artifactsDirName = config.temp || '.coverage_artifacts'; @@ -100,9 +96,9 @@ function getTempLocations(config){ function checkContext(config, tempContractsDir, tempArtifactsDir){ const ui = new PluginUI(config.logger.log); - if (!shell.test('-e', config.contracts_directory)){ + if (!shell.test('-e', config.contractsDir)){ - const msg = ui.generate('sources-fail', [config.contracts_directory]) + const msg = ui.generate('sources-fail', [config.contractsDir]) throw new Error(msg); } @@ -135,7 +131,7 @@ function assembleFiles(config, skipFiles=[]){ shell.mkdir(tempContractsDir); shell.mkdir(tempArtifactsDir); - targets = shell.ls(`${config.contracts_directory}/**/*.sol`); + targets = shell.ls(`${config.contractsDir}/**/*.sol`); skipFiles = assembleSkipped(config, targets, skipFiles); @@ -145,7 +141,7 @@ function assembleFiles(config, skipFiles=[]){ function assembleTargets(config, targets=[], skipFiles=[]){ const skipped = []; const filtered = []; - const cd = config.contracts_directory; + const cd = config.contractsDir; for (let target of targets){ if (skipFiles.includes(target)){ @@ -176,11 +172,8 @@ function assembleTargets(config, targets=[], skipFiles=[]){ * Parses the skipFiles option (which also accepts folders) */ function assembleSkipped(config, targets, skipFiles=[]){ - const cd = config.contracts_directory; - // Make paths absolute - skipFiles = skipFiles.map(contract => `${cd}/${contract}`); - skipFiles.push(`${cd}/Migrations.sol`); + skipFiles = skipFiles.map(contract => `${config.contractsDir}/${contract}`); // Enumerate files in skipped folders const skipFolders = skipFiles.filter(item => path.extname(item) !== '.sol') @@ -195,183 +188,6 @@ function assembleSkipped(config, targets, skipFiles=[]){ return skipFiles; } -// ======== -// Truffle -// ======== - -/** - * Returns a list of test files to pass to mocha. - * @param {Object} config truffleConfig - * @return {String[]} list of files to pass to mocha - */ -function getTestFilePaths(config){ - let target; - let ui = new PluginUI(config.logger.log); - - - // Handle --file cli option (subset of tests) - (typeof config.file === 'string') - ? target = globby.sync([config.file]) - : target = dir.files(config.test_directory, { sync: true }) || []; - - // Filter native solidity tests and warn that they're skipped - const solregex = /.*\.(sol)$/; - const hasSols = target.filter(f => f.match(solregex) != null); - - if (hasSols.length > 0) ui.report('sol-tests', [hasSols.length]); - - // Return list of test files - const testregex = /.*\.(js|ts|es|es6|jsx)$/; - return target.filter(f => f.match(testregex) != null); -} - - -/** - * Configures the network. Runs before the server is launched. - * User can request a network from truffle-config with "--network ". - * There are overlapiing options in solcoverjs (like port and providerOptions.network_id). - * Where there are mismatches user is warned & the truffle network settings are preferred. - * - * Also generates a default config & sets the default gas high / gas price low. - * - * @param {TruffleConfig} config - * @param {SolidityCoverage} api - */ -function setNetwork(config, api){ - const ui = new PluginUI(config.logger.log); - - // --network - if (config.network){ - const network = config.networks[config.network]; - - // Check network: - if (!network){ - throw new Error(ui.generate('no-network', [config.network])); - } - - // Check network id - if (!isNaN(parseInt(network.network_id))){ - - // Warn: non-matching provider options id and network id - if (api.providerOptions.network_id && - api.providerOptions.network_id !== parseInt(network.network_id)){ - - ui.report('id-clash', [ parseInt(network.network_id) ]); - } - - // Prefer network defined id. - api.providerOptions.network_id = parseInt(network.network_id); - - } else { - network.network_id = "*"; - } - - // Check port: use solcoverjs || default if undefined - if (!network.port) { - ui.report('no-port', [api.port]); - network.port = api.port; - } - - // Warn: port conflicts - if (api.port !== api.defaultPort && api.port !== network.port){ - ui.report('port-clash', [ network.port ]) - } - - // Prefer network port if defined; - api.port = network.port; - - network.gas = api.gasLimit; - network.gasPrice = api.gasPrice; - - setOuterConfigKeys(config, api, network.network_id); - return; - } - - // Default Network Configuration - config.network = 'soliditycoverage'; - setOuterConfigKeys(config, api, "*"); - - config.networks[config.network] = { - network_id: "*", - port: api.port, - host: api.host, - gas: api.gasLimit, - gasPrice: api.gasPrice - } -} - -/** - * Sets the default `from` account field in the truffle network that will be used. - * This needs to be done after accounts are fetched from the launched client. - * @param {TruffleConfig} config - * @param {Array} accounts - */ -function setNetworkFrom(config, accounts){ - if (!config.networks[config.network].from){ - config.networks[config.network].from = accounts[0]; - } -} - -// Truffle complains that these outer keys *are not* set when running plugin fn directly. -// But throws saying they *cannot* be manually set when running as truffle command. -function setOuterConfigKeys(config, api, id){ - try { - config.network_id = id; - config.port = api.port; - config.host = api.host; - config.provider = TruffleProvider.create(config); - } catch (err){} -} - -/** - * Tries to load truffle module library and reports source. User can force use of - * a non-local version using cli flags (see option). It's necessary to maintain - * a fail-safe lib because feature was only introduced in 5.0.30. Load order is: - * - * 1. local node_modules - * 2. global node_modules - * 3. fail-safe (truffle lib v 5.0.31 at ./plugin-assets/truffle.library) - * - * @param {Object} truffleConfig config - * @return {Module} - */ -function loadTruffleLibrary(config){ - const ui = new PluginUI(config.logger.log); - - // Local - try { - if (config.useGlobalTruffle || config.usePluginTruffle) throw null; - - const lib = require("truffle"); - ui.report('lib-local'); - return lib; - - } catch(err) {}; - - // Global - try { - if (config.usePluginTruffle) throw null; - - const globalTruffle = path.join(globalModules, 'truffle'); - const lib = require(globalTruffle); - ui.report('lib-global'); - return lib; - - } catch(err) {}; - - // Plugin Copy @ v 5.0.31 - try { - if (config.forceLibFailure) throw null; // For err unit testing - - ui.report('lib-warn'); - return require("./truffle.library") - - } catch(err) { - throw new Error(ui.generate('lib-fail', [err])); - }; - -} - function loadSolcoverJS(config){ let solcoverjs; let coverageConfig; @@ -380,8 +196,8 @@ function loadSolcoverJS(config){ // Handle --solcoverjs flag (config.solcoverjs) - ? solcoverjs = path.join(config.working_directory, config.solcoverjs) - : solcoverjs = path.join(config.working_directory, '.solcover.js'); + ? solcoverjs = path.join(config.workingDir, config.solcoverjs) + : solcoverjs = path.join(config.workingDir, '.solcover.js'); // Catch solcoverjs syntax errors if (shell.test('-e', solcoverjs)){ @@ -400,8 +216,8 @@ function loadSolcoverJS(config){ // Truffle writes to coverage config coverageConfig.log = config.logger.log; - coverageConfig.cwd = config.working_directory; - coverageConfig.originalContractsDir = config.contracts_directory; + coverageConfig.cwd = config.workingDir; + coverageConfig.originalContractsDir = config.contractsDir; // Solidity-Coverage writes to Truffle config config.mocha = config.mocha || {}; @@ -446,15 +262,10 @@ module.exports = { checkContext: checkContext, finish: finish, getTempLocations: getTempLocations, - getTestFilePaths: getTestFilePaths, loadSource: loadSource, loadSolcoverJS: loadSolcoverJS, - loadTruffleLibrary: loadTruffleLibrary, reportSkipped: reportSkipped, save: save, - setNetwork: setNetwork, - setNetworkFrom: setNetworkFrom, - setOuterConfigKeys: setOuterConfigKeys, checkContext: checkContext, toRelativePath: toRelativePath } diff --git a/dist/plugin-assets/truffle.utils.js b/dist/plugin-assets/truffle.utils.js new file mode 100644 index 00000000..3f430bdd --- /dev/null +++ b/dist/plugin-assets/truffle.utils.js @@ -0,0 +1,206 @@ +const PluginUI = require('./truffle.ui'); + +const globalModules = require('global-modules'); +const TruffleProvider = require('@truffle/provider'); +const dir = require('node-dir'); +const globby = require('globby'); +const path = require('path'); + +// ============================= +// Truffle Specific Plugin Utils +// ============================== + +/** + * Returns a list of test files to pass to mocha. + * @param {Object} config truffleConfig + * @return {String[]} list of files to pass to mocha + */ +function getTestFilePaths(config){ + let target; + let ui = new PluginUI(config.logger.log); + + + // Handle --file cli option (subset of tests) + (typeof config.file === 'string') + ? target = globby.sync([config.file]) + : target = dir.files(config.testDir, { sync: true }) || []; + + // Filter native solidity tests and warn that they're skipped + const solregex = /.*\.(sol)$/; + const hasSols = target.filter(f => f.match(solregex) != null); + + if (hasSols.length > 0) ui.report('sol-tests', [hasSols.length]); + + // Return list of test files + const testregex = /.*\.(js|ts|es|es6|jsx)$/; + return target.filter(f => f.match(testregex) != null); +} + + +/** + * Configures the network. Runs before the server is launched. + * User can request a network from truffle-config with "--network ". + * There are overlapiing options in solcoverjs (like port and providerOptions.network_id). + * Where there are mismatches user is warned & the truffle network settings are preferred. + * + * Also generates a default config & sets the default gas high / gas price low. + * + * @param {TruffleConfig} config + * @param {SolidityCoverage} api + */ +function setNetwork(config, api){ + const ui = new PluginUI(config.logger.log); + + // --network + if (config.network){ + const network = config.networks[config.network]; + + // Check network: + if (!network){ + throw new Error(ui.generate('no-network', [config.network])); + } + + // Check network id + if (!isNaN(parseInt(network.network_id))){ + + // Warn: non-matching provider options id and network id + if (api.providerOptions.network_id && + api.providerOptions.network_id !== parseInt(network.network_id)){ + + ui.report('id-clash', [ parseInt(network.network_id) ]); + } + + // Prefer network defined id. + api.providerOptions.network_id = parseInt(network.network_id); + + } else { + network.network_id = "*"; + } + + // Check port: use solcoverjs || default if undefined + if (!network.port) { + ui.report('no-port', [api.port]); + network.port = api.port; + } + + // Warn: port conflicts + if (api.port !== api.defaultPort && api.port !== network.port){ + ui.report('port-clash', [ network.port ]) + } + + // Prefer network port if defined; + api.port = network.port; + + network.gas = api.gasLimit; + network.gasPrice = api.gasPrice; + + setOuterConfigKeys(config, api, network.network_id); + return; + } + + // Default Network Configuration + config.network = 'soliditycoverage'; + setOuterConfigKeys(config, api, "*"); + + config.networks[config.network] = { + network_id: "*", + port: api.port, + host: api.host, + gas: api.gasLimit, + gasPrice: api.gasPrice + } +} + +/** + * Sets the default `from` account field in the truffle network that will be used. + * This needs to be done after accounts are fetched from the launched client. + * @param {TruffleConfig} config + * @param {Array} accounts + */ +function setNetworkFrom(config, accounts){ + if (!config.networks[config.network].from){ + config.networks[config.network].from = accounts[0]; + } +} + +// Truffle complains that these outer keys *are not* set when running plugin fn directly. +// But throws saying they *cannot* be manually set when running as truffle command. +function setOuterConfigKeys(config, api, id){ + try { + config.network_id = id; + config.port = api.port; + config.host = api.host; + config.provider = TruffleProvider.create(config); + } catch (err){} +} + +/** + * Tries to load truffle module library and reports source. User can force use of + * a non-local version using cli flags (see option). It's necessary to maintain + * a fail-safe lib because feature was only introduced in 5.0.30. Load order is: + * + * 1. local node_modules + * 2. global node_modules + * 3. fail-safe (truffle lib v 5.0.31 at ./plugin-assets/truffle.library) + * + * @param {Object} truffleConfig config + * @return {Module} + */ +function loadLibrary(config){ + const ui = new PluginUI(config.logger.log); + + // Local + try { + if (config.useGlobalTruffle || config.usePluginTruffle) throw null; + + const lib = require("truffle"); + ui.report('lib-local'); + return lib; + + } catch(err) {}; + + // Global + try { + if (config.usePluginTruffle) throw null; + + const globalTruffle = path.join(globalModules, 'truffle'); + const lib = require(globalTruffle); + ui.report('lib-global'); + return lib; + + } catch(err) {}; + + // Plugin Copy @ v 5.0.31 + try { + if (config.forceLibFailure) throw null; // For err unit testing + + ui.report('lib-warn'); + return require("./truffle.library") + + } catch(err) { + throw new Error(ui.generate('lib-fail', [err])); + }; + +} + +/** + * Maps truffle specific keys for the paths to things like sources to the generic + * keys required by the plugin utils + * @return {Object} truffle-config.js + */ +function normalizeConfig(config){ + config.workingDir = config.working_directory; + config.contractsDir = config.contracts_directory; + config.testDir = config.test_directory; + config.artifactsDir = config.build_directory; + + return config; +} + +module.exports = { + getTestFilePaths: getTestFilePaths, + setNetwork: setNetwork, + setNetworkFrom: setNetworkFrom, + loadLibrary: loadLibrary, + normalizeConfig: normalizeConfig, +} diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index aaef2e8a..62c4ad33 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -1,5 +1,6 @@ const API = require('./../lib/api'); const utils = require('./plugin-assets/plugin.utils'); +const truffleUtils = require('./plugin-assets/truffle.utils'); const PluginUI = require('./plugin-assets/truffle.ui'); const pkg = require('./../package.json'); @@ -23,14 +24,16 @@ async function plugin(config){ try { death(utils.finish.bind(null, config, api)); // Catch interrupt signals + config = truffleUtils.normalizeConfig(config); + ui = new PluginUI(config.logger.log); if(config.help) return ui.report('help'); // Exit if --help - truffle = utils.loadTruffleLibrary(config); + truffle = truffleUtils.loadLibrary(config); api = new API(utils.loadSolcoverJS(config)); - utils.setNetwork(config, api); + truffleUtils.setNetwork(config, api); // Server launch const address = await api.ganache(truffle.ganache); @@ -40,7 +43,7 @@ async function plugin(config){ const nodeInfo = await web3.eth.getNodeInfo(); const ganacheVersion = nodeInfo.split('/')[1]; - utils.setNetworkFrom(config, accounts); + truffleUtils.setNetworkFrom(config, accounts); // Version Info ui.report('versions', [ @@ -62,10 +65,13 @@ async function plugin(config){ await api.onServerReady(config); // Instrument + const skipFiles = api.skipFiles || []; + skipFiles.push('Migrations.sol'); + let { targets, skipped - } = utils.assembleFiles(config, api.skipFiles); + } = utils.assembleFiles(config, skipFiles); targets = api.instrument(targets); utils.reportSkipped(config, skipped); @@ -88,7 +94,7 @@ async function plugin(config){ ); config.all = true; - config.test_files = utils.getTestFilePaths(config); + config.test_files = truffleUtils.getTestFilePaths(config); config.compilers.solc.settings.optimizer.enabled = false; // Compile Instrumented Contracts diff --git a/lib/validator.js b/lib/validator.js index b5d84415..cdc5b624 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -2,11 +2,6 @@ const Validator = require('jsonschema').Validator; const AppUI = require('./ui').AppUI; const util = require('util') - -function isFunction(input){ - -} - Validator.prototype.customFormats.isFunction = function(input) { return typeof input === "function" }; diff --git a/test/integration/truffle/assets/SimpleError.sol b/test/integration/generic/assets/SimpleError.sol similarity index 100% rename from test/integration/truffle/assets/SimpleError.sol rename to test/integration/generic/assets/SimpleError.sol diff --git a/test/integration/truffle/assets/asset.js b/test/integration/generic/assets/asset.js similarity index 100% rename from test/integration/truffle/assets/asset.js rename to test/integration/generic/assets/asset.js diff --git a/test/integration/truffle/contracts/Migrations.sol b/test/integration/generic/contracts/Migrations.sol similarity index 100% rename from test/integration/truffle/contracts/Migrations.sol rename to test/integration/generic/contracts/Migrations.sol diff --git a/test/integration/truffle/migrations/1_initial.js b/test/integration/generic/migrations/1_initial.js similarity index 100% rename from test/integration/truffle/migrations/1_initial.js rename to test/integration/generic/migrations/1_initial.js diff --git a/test/integration/truffle/test/.marker b/test/integration/generic/test/.marker similarity index 100% rename from test/integration/truffle/test/.marker rename to test/integration/generic/test/.marker diff --git a/test/integration/projects/bad-solcoverjs/buidler.config.js b/test/integration/projects/bad-solcoverjs/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/bad-solcoverjs/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/import-paths/buidler.config.js b/test/integration/projects/import-paths/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/import-paths/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/libraries/buidler.config.js b/test/integration/projects/libraries/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/libraries/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/libraries/test/libraries.js b/test/integration/projects/libraries/test/libraries.js index e41ff19b..971d5d73 100644 --- a/test/integration/projects/libraries/test/libraries.js +++ b/test/integration/projects/libraries/test/libraries.js @@ -2,60 +2,60 @@ const UsesPure = artifacts.require('UsesPure'); contract('UsesPure', accounts => { it('calls imported, inherited pure/view functions within its own function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.usesThem(); }); it('calls a library method', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.usesLibrary(); assert.equal(value.toNumber(), 1); }); it('calls an imported, inherited pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isPure(4, 5); assert.equal(value.toNumber(), 20); }); it('calls an imported, inherited view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isView(); assert.equal(value.toNumber(), 5); }); it('overrides an imported, inherited abstract pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.bePure(4, 5); assert.equal(value.toNumber(), 9); }); it('overrides an imported, inherited abstract view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.beView(); assert.equal(value.toNumber(), 99); }); it('calls a pure method implemented in an inherited class', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedPure(4, 5); assert.equal(value.toNumber(), 9); }); it('calls a view method implemented in an inherited class', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedView(); assert.equal(value.toNumber(), 5); }); it('calls a view method whose modifiers span lines', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.multiline(5, 7) assert.equal(value.toNumber(), 99); }); it('calls a method who signature is defined by an interface', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.cry(); }); diff --git a/test/integration/projects/multiple-migrations/buidler.config.js b/test/integration/projects/multiple-migrations/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/multiple-migrations/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/no-sources/buidler.config.js b/test/integration/projects/no-sources/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/no-sources/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/skipping/buidler.config.js b/test/integration/projects/skipping/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/skipping/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/test-files/buidler.config.js b/test/integration/projects/test-files/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/test-files/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/test-files/test/globby_b.js b/test/integration/projects/test-files/test/globby_b.js index 14b4cc27..42d8cb84 100644 --- a/test/integration/projects/test-files/test/globby_b.js +++ b/test/integration/projects/test-files/test/globby_b.js @@ -3,7 +3,7 @@ const ContractB = artifacts.require("ContractB"); contract("contractB", function(accounts) { let instance; - before(async () => instance = await ContractB.deployed()) + before(async () => instance = await ContractB.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/integration/projects/test-files/test/globby_c.js b/test/integration/projects/test-files/test/globby_c.js index 124f47aa..9b3d950d 100644 --- a/test/integration/projects/test-files/test/globby_c.js +++ b/test/integration/projects/test-files/test/globby_c.js @@ -3,7 +3,7 @@ const ContractC = artifacts.require("ContractC"); contract("contractc", function(accounts) { let instance; - before(async () => instance = await ContractC.deployed()) + before(async () => instance = await ContractC.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/integration/projects/test-files/test/specific_a.js b/test/integration/projects/test-files/test/specific_a.js index 0559b95e..7cab74b8 100644 --- a/test/integration/projects/test-files/test/specific_a.js +++ b/test/integration/projects/test-files/test/specific_a.js @@ -3,7 +3,7 @@ const ContractA = artifacts.require("ContractA"); contract("contracta", function(accounts) { let instance; - before(async () => instance = await ContractA.deployed()) + before(async () => instance = await ContractA.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/sources/js/block-gas-limit.js b/test/sources/js/block-gas-limit.js index 8256c0f6..43568333 100644 --- a/test/sources/js/block-gas-limit.js +++ b/test/sources/js/block-gas-limit.js @@ -1,7 +1,7 @@ -const Expensive = artifacts.require('./Expensive.sol'); +const Expensive = artifacts.require('Expensive'); contract('Expensive', () => { - it('should deploy', async () => { + it('should deploy', async function() { const instance = await Expensive.new() const hash = instance.transactionHash; const receipt = await web3.eth.getTransactionReceipt(hash); diff --git a/test/sources/js/empty.js b/test/sources/js/empty.js index def0cd05..33835e1d 100644 --- a/test/sources/js/empty.js +++ b/test/sources/js/empty.js @@ -1,8 +1,7 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract */ +const Empty = artifacts.require('Empty'); -const Empty = artifacts.require('./Empty.sol'); - -contract('Empty', () => { - it('should deploy', () => Empty.deployed()); +contract('Empty', function() { + it('should deploy', async function (){ + await Empty.new() + }); }); diff --git a/test/sources/js/inheritance.js b/test/sources/js/inheritance.js index d2546246..04a6af7f 100644 --- a/test/sources/js/inheritance.js +++ b/test/sources/js/inheritance.js @@ -1,11 +1,11 @@ -const Owned = artifacts.require('./Owned.sol'); -const Proxy = artifacts.require('./Proxy.sol'); +const Owned = artifacts.require('Owned'); +const Proxy = artifacts.require('Proxy'); contract('Proxy', accounts => { - it('Should compile and run when one contract inherits from another', () => Owned.deployed() - .then(() => Proxy.deployed()) - .then(instance => instance.isOwner.call({ - from: accounts[0], - })) - .then(val => assert.equal(val, true))); + it('when one contract inherits from another', async function(){ + const owned = await Owned.new(); + const proxy = await Proxy.new(); + const val = await proxy.isOwner({from: accounts[0]}); + assert.equal(val, true); + }) }); diff --git a/test/sources/js/only-call.js b/test/sources/js/only-call.js index da72716b..931f9b7c 100644 --- a/test/sources/js/only-call.js +++ b/test/sources/js/only-call.js @@ -1,17 +1,9 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - -const OnlyCall = artifacts.require('./OnlyCall.sol'); +const OnlyCall = artifacts.require('OnlyCall'); contract('OnlyCall', accounts => { - it('should return val + 2', done => { - OnlyCall.deployed().then(instance => { - instance.addTwo.call(5, { - from: accounts[0], - }).then(val => { - assert.equal(val, 7); - done(); - }); - }); - }); + it('should return val + 2', async function(){ + const onlycall = await OnlyCall.new(); + const val = await onlycall.addTwo(5); + assert.equal(val.toNumber(), 7); + }) }); diff --git a/test/sources/js/pureview.js b/test/sources/js/pureview.js index d2aee69a..1cb78b5b 100644 --- a/test/sources/js/pureview.js +++ b/test/sources/js/pureview.js @@ -1,17 +1,17 @@ /* eslint-env node, mocha */ /* global artifacts, contract, assert */ -const PureView = artifacts.require('./PureView.sol'); +const PureView = artifacts.require('PureView'); contract('PureView', accounts => { it('calls a pure function', async function(){ - const instance = await PureView.deployed(); + const instance = await PureView.new(); const value = await instance.isPure(4,5); }); it('calls a view function', async function(){ - const instance = await PureView.deployed(); + const instance = await PureView.new(); const value = await instance.isView(); }) }); \ No newline at end of file diff --git a/test/sources/js/simple.js b/test/sources/js/simple.js index 12281931..6edc385e 100644 --- a/test/sources/js/simple.js +++ b/test/sources/js/simple.js @@ -2,7 +2,7 @@ const Simple = artifacts.require('Simple'); contract('Simple', () => { it('should set x to 5', async function(){ - const simple = await Simple.deployed() + const simple = await Simple.new() await simple.test(5); const val = await simple.getX.call(); assert.equal(val.toNumber(), 5); diff --git a/test/sources/js/sol-parse-fail.js b/test/sources/js/sol-parse-fail.js deleted file mode 100644 index ff17dbaa..00000000 --- a/test/sources/js/sol-parse-fail.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - -const Simple = artifacts.require('./Simple.sol'); - -// This test is constructed correctly but the SimpleError.sol has a syntax error -contract('SimpleError', () => { - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val, 5)); - }); -}); diff --git a/test/sources/js/testrpc-options.js b/test/sources/js/testrpc-options.js index b2112303..452df67e 100644 --- a/test/sources/js/testrpc-options.js +++ b/test/sources/js/testrpc-options.js @@ -1,4 +1,4 @@ -const Simple = artifacts.require('./Simple.sol'); +const Simple = artifacts.require('Simple'); contract('Simple', accounts => { @@ -7,15 +7,4 @@ contract('Simple', accounts => { balance = web3.utils.fromWei(balance); assert(parseInt(balance) >= 776) }); - - // Generate some coverage so the script doesn't exit(1) because there are no events - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val.toNumber(), 5)); - }); }); diff --git a/test/sources/js/totallyPure.js b/test/sources/js/totallyPure.js index 7688a3f9..6b257107 100644 --- a/test/sources/js/totallyPure.js +++ b/test/sources/js/totallyPure.js @@ -2,55 +2,54 @@ const UsesPure = artifacts.require('UsesPure'); contract('UsesPure', accounts => { it('calls imported, inherited pure/view functions within its own function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.usesThem(); }); it('calls an imported, inherited pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isPure(4, 5); assert.equal(value.toNumber(), 20); }); it('calls an imported, inherited view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isView(); assert.equal(value.toNumber(), 5); }); it('overrides an imported, inherited abstract pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.bePure(4, 5); assert.equal(value.toNumber(), 9); }); it('overrides an imported, inherited abstract view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.beView(); assert.equal(value.toNumber(), 99); }); it('calls a pure method implemented in an inherited class', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedPure(4, 5); assert.equal(value.toNumber(), 9); }); it('calls a view method implemented in an inherited class', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedView(); assert.equal(value.toNumber(), 5); }); it('calls a view method whose modifiers span lines', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.multiline(5, 7) assert.equal(value.toNumber(), 99); }); it('calls a method who signature is defined by an interface', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.cry(); }); - }); \ No newline at end of file diff --git a/test/sources/js/truffle-crash.js b/test/sources/js/truffle-crash.js index 33633aa9..92b3adc6 100644 --- a/test/sources/js/truffle-crash.js +++ b/test/sources/js/truffle-crash.js @@ -1,11 +1,11 @@ /* eslint-env node, mocha */ /* global artifacts, contract */ -var Simple = artifacts.require('./Simple.sol'); +var Simple = artifacts.require('Simple'); // This test should break truffle because it has a syntax error. contract('Simple', () => { it('should crash', function(){ - return Simple.deployed().then.why. + return Simple.new().then.why. }) }) \ No newline at end of file diff --git a/test/sources/js/truffle-test-fail.js b/test/sources/js/truffle-test-fail.js index e9457d01..cb08d550 100644 --- a/test/sources/js/truffle-test-fail.js +++ b/test/sources/js/truffle-test-fail.js @@ -1,16 +1,13 @@ /* eslint-env node, mocha */ /* global artifacts, contract, assert */ -const Simple = artifacts.require('./Simple.sol'); +const Simple = artifacts.require('Simple'); contract('Simple', () => { - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val.toNumber(), 4)); // <-- Wrong result: test fails + it('should set x to 5', async function() { + let simple = await Simple.new(); + await simple.test(5); + const val = await simple.getX(); + assert.equal(val.toNumber(), 4) // <-- Wrong result: test fails }); }); diff --git a/test/sources/js/wallet.js b/test/sources/js/wallet.js index 827a4001..144f3b71 100644 --- a/test/sources/js/wallet.js +++ b/test/sources/js/wallet.js @@ -1,4 +1,4 @@ -const Wallet = artifacts.require('./Wallet.sol'); +const Wallet = artifacts.require('Wallet'); contract('Wallet', accounts => { it('should should allow transfers and sends', async () => { diff --git a/test/sources/solidity/contracts/app/Proxy.sol b/test/sources/solidity/contracts/app/Proxy.sol index f6557ed3..b3109a5c 100644 --- a/test/sources/solidity/contracts/app/Proxy.sol +++ b/test/sources/solidity/contracts/app/Proxy.sol @@ -3,7 +3,7 @@ pragma solidity ^0.5.0; import "./Owned.sol"; contract Proxy is Owned { - function isOwner() public returns (bool) { + function isOwner() public view returns (bool) { if (msg.sender == owner) { return true; } else { diff --git a/test/units/truffle/errors.js b/test/units/truffle/errors.js index b39a00fa..dbbf6cc3 100644 --- a/test/units/truffle/errors.js +++ b/test/units/truffle/errors.js @@ -6,7 +6,7 @@ const shell = require('shelljs'); const ganache = require('ganache-core-sc'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======= diff --git a/test/units/truffle/flags.js b/test/units/truffle/flags.js index 18d3c79e..92757d5c 100644 --- a/test/units/truffle/flags.js +++ b/test/units/truffle/flags.js @@ -4,7 +4,7 @@ const path = require('path') const shell = require('shelljs'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======================= diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 4a19e238..4b767bc2 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -4,7 +4,7 @@ const path = require('path') const shell = require('shelljs'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======================= @@ -46,7 +46,9 @@ describe('Truffle Plugin: standard use cases', function() { ); }); - it('with many unbracketed statements (time check)', async function() { + // Instrumentation speed is fine - but this takes solc almost a minute to compile + // so annoying. Unskip whenever modifying the instrumentation files though..... + it.skip('with many unbracketed statements (time check)', async function() { truffleConfig.compilers.solc.version = "0.4.24"; mock.install('Oraclize', 'oraclize.js', solcoverConfig, truffleConfig, true); diff --git a/test/util/integration.truffle.js b/test/util/integration.js similarity index 71% rename from test/util/integration.truffle.js rename to test/util/integration.js index 98b823b9..8a50dcc6 100644 --- a/test/util/integration.truffle.js +++ b/test/util/integration.js @@ -11,11 +11,12 @@ const decache = require('decache'); const temp = './sc_temp'; const truffleConfigName = 'truffle-config.js'; +const buidlerConfigName = 'buidler.config.js'; const configPath = `${temp}/.solcover.js`; const testPath = './test/sources/js/'; const sourcesPath = './test/sources/solidity/contracts/app/'; const migrationPath = `${temp}/migrations/2_deploy.js`; -const templatePath = './test/integration/truffle/*'; +const templatePath = './test/integration/generic/*'; const projectPath = './test/integration/projects/' @@ -25,6 +26,7 @@ const projectPath = './test/integration/projects/' function decacheConfigs(){ decache(`${process.cwd()}/${temp}/.solcover.js`); decache(`${process.cwd()}/${temp}/${truffleConfigName}`); + decache(`${process.cwd()}/${temp}/${buidlerConfigName}`); } function clean() { @@ -48,7 +50,7 @@ function getOutput(truffleConfig){ } // ========================== -// Configuration +// Truffle Configuration // ========================== function getDefaultTruffleConfig(){ const logger = process.env.SILENT ? { log: () => {} } : console; @@ -82,14 +84,61 @@ function getDefaultTruffleConfig(){ return (new TruffleConfig()).with(vals); } +function getTruffleConfigJS(config){ + if (config) { + return `module.exports = ${JSON.stringify(config, null, ' ')}`; + } else { + return `module.exports = ${JSON.stringify(getDefaultTruffleConfig(), null, ' ')}`; + } +} + +// ========================== +// Buidler Configuration +// ========================== +function getDefaultBuidlerConfig() { + const logger = process.env.SILENT ? { log: () => {} } : console; + const reporter = process.env.SILENT ? 'dot' : 'spec'; + + const mockwd = path.join(process.cwd(), temp); + const vals = { + root: mockwd, + artifacts: path.join(mockwd, 'artifacts'), + cache: path.join(mockwd, 'cache'), + sources: path.join(mockwd, 'contracts'), + tests: path.join(mockwd, 'test'), + logger: logger, + mocha: { + reporter: reporter + }, + networks: { + development: { + url: "http://127.0.0.1:8545", + } + }, + solc: { + version: "0.5.3", + optimizer: {} + } + } + + return vals; +} + +function getBuidlerConfigJS(config){ + if (config) { + return `module.exports = ${JSON.stringify(config, null, ' ')}` + } else { + return `module.exports = ${JSON.stringify(getDefaultBuidlerConfig(), null, ' ')}` + } +} + +// ========================== +// .solcover.js Configuration +// ========================== function getSolcoverJS(config){ return `module.exports = ${JSON.stringify(config, null, ' ')}` } -function getTruffleConfigJS(config){ - if (config) return `module.exports = ${JSON.stringify(config, null, ' ')}` - return `module.exports = ${JSON.stringify(getDefaultTruffleConfig(), null, ' ')}` -} // ========================== // Migration Generators @@ -117,7 +166,7 @@ function deployDouble(contractNames){ // Project Installers // ========================== /** - * Installs mock truffle project at ./temp with a single contract + * Installs mock truffle/buidler project at ./temp with a single contract * and test specified by the params. * @param {String} contract located in /test/sources/cli/ * @param {[type]} test located in /test/cli/ @@ -125,15 +174,16 @@ function deployDouble(contractNames){ function install( contract, test, - config, - _truffleConfig, + solcoverConfig, + devPlatformConfig, noMigrations ) { let configjs; - if(config) configjs = getSolcoverJS(config); + if(solcoverConfig) solcoverJS = getSolcoverJS(solcoverConfig); - const trufflejs = getTruffleConfigJS(_truffleConfig); + const trufflejs = getTruffleConfigJS(devPlatformConfig); + const buidlerjs = getBuidlerConfigJS(devPlatformConfig); const migration = deploySingle(contract); // Scaffold @@ -151,15 +201,14 @@ function install( // Configs fs.writeFileSync(`${temp}/${truffleConfigName}`, trufflejs); - if(config) fs.writeFileSync(configPath, configjs); + fs.writeFileSync(`${temp}/${buidlerConfigName}`, buidlerjs); + if(solcoverConfig) fs.writeFileSync(configPath, solcoverJS); decacheConfigs(); - }; /** - * Installs mock truffle project with two contracts (for inheritance, libraries, etc) - * + * Installs mock truffle/buidler project with two contracts (for inheritance, libraries, etc) */ function installDouble(contracts, test, config) { const configjs = getSolcoverJS(config); @@ -182,11 +231,15 @@ function installDouble(contracts, test, config) { // Configs fs.writeFileSync(`${temp}/${truffleConfigName}`, getTruffleConfigJS()); + fs.writeFileSync(`${temp}/${buidlerConfigName}`, getBuidlerConfigJS()); fs.writeFileSync(configPath, configjs); decacheConfigs(); }; +/** + * Installs full truffle/buidler project + */ function installFullProject(name, config) { shell.mkdir(temp); shell.cp('-Rf', `${projectPath}${name}/{.,}*`, temp); @@ -219,6 +272,7 @@ module.exports = { testLogger: testLogger, loggerOutput: loggerOutput, getDefaultTruffleConfig: getDefaultTruffleConfig, + getDefaultBuidlerConfig: getDefaultBuidlerConfig, install: install, installDouble: installDouble, installFullProject: installFullProject, From 592470608c311563cffd5258532e1e4c99f8b529 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 17 Oct 2019 16:20:26 -0700 Subject: [PATCH 03/21] Buidler plugin draft (#426) * Plugin draft * Passing: standard test suite --- dist/buidler.plugin.js | 139 ++++++++++ dist/plugin-assets/buidler.ui.js | 83 ++++++ dist/plugin-assets/buidler.utils.js | 108 ++++++++ dist/plugin-assets/plugin.utils.js | 3 +- lib/api.js | 10 +- lib/validator.js | 2 - .../projects/bad-solcoverjs/buidler.config.js | 9 +- .../projects/import-paths/buidler.config.js | 9 +- .../node_modules/package/package.json | 1 + .../projects/libraries/buidler.config.js | 8 +- .../multiple-migrations/buidler.config.js | 2 +- .../projects/multiple-suites/.solcover.js | 4 + .../multiple-suites/buidler.config.js | 8 + .../multiple-suites/contracts/ContractA.sol | 17 ++ .../multiple-suites/contracts/ContractB.sol | 17 ++ .../multiple-suites/contracts/ContractC.sol | 17 ++ .../multiple-suites/contracts/Migrations.sol | 23 ++ .../multiple-suites/test/contracta.js | 15 + .../multiple-suites/test/contractb.js | 15 + .../multiple-suites/test/contractc.js | 20 ++ .../multiple-suites/truffle-config.js | 7 + .../projects/no-sources/buidler.config.js | 8 +- .../projects/skipping/buidler.config.js | 9 +- .../projects/test-files/.solcover.js | 1 + .../projects/test-files/buidler.config.js | 8 +- test/sources/js/truffle-test-fail.js | 7 + test/units/buidler/standard.js | 258 ++++++++++++++++++ test/units/validator.js | 1 - test/util/integration.js | 60 ++-- test/util/verifiers.js | 12 +- 30 files changed, 843 insertions(+), 38 deletions(-) create mode 100644 dist/plugin-assets/buidler.ui.js create mode 100644 dist/plugin-assets/buidler.utils.js create mode 100644 test/integration/projects/import-paths/node_modules/package/package.json create mode 100644 test/integration/projects/multiple-suites/.solcover.js create mode 100644 test/integration/projects/multiple-suites/buidler.config.js create mode 100644 test/integration/projects/multiple-suites/contracts/ContractA.sol create mode 100644 test/integration/projects/multiple-suites/contracts/ContractB.sol create mode 100644 test/integration/projects/multiple-suites/contracts/ContractC.sol create mode 100644 test/integration/projects/multiple-suites/contracts/Migrations.sol create mode 100644 test/integration/projects/multiple-suites/test/contracta.js create mode 100644 test/integration/projects/multiple-suites/test/contractb.js create mode 100644 test/integration/projects/multiple-suites/test/contractc.js create mode 100644 test/integration/projects/multiple-suites/truffle-config.js create mode 100644 test/units/buidler/standard.js diff --git a/dist/buidler.plugin.js b/dist/buidler.plugin.js index e69de29b..dba89c48 100644 --- a/dist/buidler.plugin.js +++ b/dist/buidler.plugin.js @@ -0,0 +1,139 @@ +const API = require('./../lib/api'); +const utils = require('./plugin-assets/plugin.utils'); +const buidlerUtils = require('./plugin-assets/buidler.utils'); +const PluginUI = require('./plugin-assets/buidler.ui'); + +const pkg = require('./../package.json'); +const death = require('death'); +const path = require('path'); +const Web3 = require('web3'); +const ganache = require('ganache-cli'); + +const { task, types } = require("@nomiclabs/buidler/config"); +const { ensurePluginLoadedWithUsePlugin } = require("@nomiclabs/buidler/plugins"); + +const { + TASK_TEST, + TASK_COMPILE, +} = require("@nomiclabs/buidler/builtin-tasks/task-names"); + +function plugin() { + + // UI for the task flags... + const ui = new PluginUI(); + + task("coverage", "Generates a code coverage report for tests") + + .addOptionalParam("file", ui.flags.file, null, types.string) + .addOptionalParam("solcoverjs", ui.flags.solcoverjs, null, types.string) + .addOptionalParam('temp', ui.flags.temp, null, types.string) + + .setAction(async function(taskArguments, env){ + let error; + let ui; + let api; + let config; + + try { + death(buidlerUtils.finish.bind(null, config, api)); // Catch interrupt signals + + config = buidlerUtils.normalizeConfig(env.config); + ui = new PluginUI(config.logger.log); + api = new API(utils.loadSolcoverJS(config)); + + // ============== + // Server launch + // ============== + + const network = buidlerUtils.setupNetwork(env, api); + + const address = await api.ganache(ganache); + const web3 = new Web3(address); + const accounts = await web3.eth.getAccounts(); + const nodeInfo = await web3.eth.getNodeInfo(); + const ganacheVersion = nodeInfo.split('/')[1]; + + // Set default account + network.from = accounts[0]; + + // Version Info + ui.report('versions', [ + ganacheVersion, + pkg.version + ]); + + // Network Info + ui.report('network', [ + api.defaultNetworkName, + api.port + ]); + + // Run post-launch server hook; + await api.onServerReady(config); + + // ================ + // Instrumentation + // ================ + + const skipFiles = api.skipFiles || []; + + let { + targets, + skipped + } = utils.assembleFiles(config, skipFiles); + + targets = api.instrument(targets); + utils.reportSkipped(config, skipped); + + // ============== + // Compilation + // ============== + + const { + tempArtifactsDir, + tempContractsDir + } = utils.getTempLocations(config); + + utils.save(targets, config.paths.sources, tempContractsDir); + utils.save(skipped, config.paths.sources, tempContractsDir); + + config.paths.sources = tempContractsDir; + config.paths.artifacts = tempArtifactsDir; + config.paths.cache = buidlerUtils.tempCacheDir(config); + config.solc.optimizer.enabled = false; + + await env.run(TASK_COMPILE); + + await api.onCompileComplete(config); + + // ====== + // Tests + // ====== + const testFiles = buidlerUtils.getTestFilePaths(config); + + try { + await env.run(TASK_TEST, {testFiles: testFiles}) + } catch (e) { + error = e; + } + await api.onTestsComplete(config); + + // ======== + // Istanbul + // ======== + await api.report(); + await api.onIstanbulComplete(config); + + } catch(e) { + error = e; + } + + await utils.finish(config, api); + + if (error !== undefined ) throw error; + if (process.exitCode > 0) throw new Error(ui.generate('tests-fail', [process.exitCode])); + }) +} + +module.exports = plugin; + diff --git a/dist/plugin-assets/buidler.ui.js b/dist/plugin-assets/buidler.ui.js new file mode 100644 index 00000000..78c39a38 --- /dev/null +++ b/dist/plugin-assets/buidler.ui.js @@ -0,0 +1,83 @@ +const UI = require('./../../lib/ui').UI; + +/** + * Truffle Plugin logging + */ +class PluginUI extends UI { + constructor(log){ + super(log); + + this.flags = { + file: `Path (or glob) defining a subset of tests to run`, + + solcoverjs: `Relative path from working directory to config. ` + + `Useful for monorepo packages that share settings.`, + + temp: `Path to a disposable folder to store compilation artifacts in. ` + + `Useful when your test setup scripts include hard-coded paths to ` + + `a build directory.`, + + } + } + + /** + * Writes a formatted message via log + * @param {String} kind message selector + * @param {String[]} args info to inject into template + */ + report(kind, args=[]){ + const c = this.chalk; + const ct = c.bold.green('>'); + const ds = c.bold.yellow('>'); + const w = ":warning:"; + + const kinds = { + + 'instr-skip': `\n${c.bold('Coverage skipped for:')}` + + `\n${c.bold('=====================')}\n`, + + 'instr-skipped': `${ds} ${c.grey(args[0])}`, + + 'versions': `${ct} ${c.bold('ganache-core')}: ${args[0]}\n` + + `${ct} ${c.bold('solidity-coverage')}: v${args[1]}`, + + 'network': `\n${c.bold('Network Info')}` + + `\n${c.bold('============')}\n` + + `${ct} ${c.bold('port')}: ${args[1]}\n` + + `${ct} ${c.bold('network')}: ${args[0]}\n`, + } + + this._write(kinds[kind]); + } + + /** + * Returns a formatted message. Useful for error message. + * @param {String} kind message selector + * @param {String[]} args info to inject into template + * @return {String} message + */ + generate(kind, args=[]){ + const c = this.chalk; + const x = ":x:"; + + const kinds = { + + 'sources-fail': `${c.red('Cannot locate expected contract sources folder: ')} ${args[0]}`, + + 'solcoverjs-fail': `${c.red('Could not load .solcover.js config file. ')}` + + `${c.red('This can happen if it has a syntax error or ')}` + + `${c.red('the path you specified for it is wrong.')}`, + + 'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`, + + 'no-network': `${c.red('Network: ')} ${args[0]} ` + + `${c.red(' is not defined in your truffle-config networks. ')}`, + + } + + + return this._format(kinds[kind]) + } +} + +module.exports = PluginUI; \ No newline at end of file diff --git a/dist/plugin-assets/buidler.utils.js b/dist/plugin-assets/buidler.utils.js new file mode 100644 index 00000000..23fff0c8 --- /dev/null +++ b/dist/plugin-assets/buidler.utils.js @@ -0,0 +1,108 @@ +const shell = require('shelljs'); +const globby = require('globby'); +const pluginUtils = require("./plugin.utils"); +const path = require('path'); +const util = require('util'); +const { createProvider } = require("@nomiclabs/buidler/internal/core/providers/construction"); + + +// ============================= +// Buidler Specific Plugin Utils +// ============================= + +/** + * Returns a list of test files to pass to TASK_TEST. + * @param {BuidlerConfig} config + * @return {String[]} list of files to pass to mocha + */ +function getTestFilePaths(config){ + let target; + + // Handle --file cli option (subset of tests) + (typeof config.file === 'string') + ? target = globby.sync([config.file]) + : target = []; + + // Return list of test files + const testregex = /.*\.(js|ts|es|es6|jsx)$/; + return target.filter(f => f.match(testregex) != null); +} + +/** + * Normalizes buidler paths / logging for use by the plugin utilities and + * attaches them to the config + * @param {BuidlerConfig} config + * @return {BuidlerConfig} updated config + */ +function normalizeConfig(config){ + config.workingDir = config.paths.root; + config.contractsDir = config.paths.sources; + config.testDir = config.paths.tests; + config.artifactsDir = config.paths.artifacts; + config.logger = config.logger ? config.logger : {log: null}; + + return config; +} + +function setupNetwork(env, api){ + const networkConfig = { + url: `http://${api.host}:${api.port}`, + gas: api.gasLimit, + gasPrice: api.gasPrice + } + + const provider = createProvider(api.defaultNetworkName, networkConfig); + + env.config.networks[api.defaultNetworkName] = networkConfig; + env.config.defaultNetwork = api.defaultNetworkName; + + env.network = { + name: api.defaultNetworkName, + config: networkConfig, + provider: provider, + } + + env.ethereum = provider; + + // Return a reference so we can set the from account + return env.network; +} + +/** + * Generates a path to a temporary compilation cache directory + * @param {BuidlerConfig} config + * @return {String} .../.coverage_cache + */ +function tempCacheDir(config){ + return path.join(config.paths.root, '.coverage_cache'); +} + +/** + * Silently removes temporary folders and calls api.finish to shut server down + * @param {BuidlerConfig} config + * @param {SolidityCoverage} api + * @return {Promise} + */ +async function finish(config, api){ + const { + tempContractsDir, + tempArtifactsDir + } = pluginUtils.getTempLocations(config); + + shell.config.silent = true; + shell.rm('-Rf', tempContractsDir); + shell.rm('-Rf', tempArtifactsDir); + shell.rm('-Rf', path.join(config.paths.root, '.coverage_cache')); + shell.config.silent = false; + + if (api) await api.finish(); +} + +module.exports = { + normalizeConfig: normalizeConfig, + finish: finish, + tempCacheDir: tempCacheDir, + getTestFilePaths: getTestFilePaths, + setupNetwork: setupNetwork +} + diff --git a/dist/plugin-assets/plugin.utils.js b/dist/plugin-assets/plugin.utils.js index cabbf0c7..d4162eee 100644 --- a/dist/plugin-assets/plugin.utils.js +++ b/dist/plugin-assets/plugin.utils.js @@ -11,6 +11,7 @@ const PluginUI = require('./truffle.ui'); const path = require('path'); const fs = require('fs-extra'); const shell = require('shelljs'); +const util = require('util') // === // UI @@ -193,7 +194,6 @@ function loadSolcoverJS(config){ let coverageConfig; let ui = new PluginUI(config.logger.log); - // Handle --solcoverjs flag (config.solcoverjs) ? solcoverjs = path.join(config.workingDir, config.solcoverjs) @@ -251,6 +251,7 @@ async function finish(config, api){ shell.config.silent = true; shell.rm('-Rf', tempContractsDir); shell.rm('-Rf', tempArtifactsDir); + shell.config.silent = false; if (api) await api.finish(); } diff --git a/lib/api.js b/lib/api.js index 14aa5803..4ed9d4c3 100644 --- a/lib/api.js +++ b/lib/api.js @@ -30,7 +30,6 @@ class API { this.testsErrored = false; this.cwd = config.cwd || process.cwd(); - this.originalContractsDir = config.originalContractsDir this.defaultHook = () => {}; this.onServerReady = config.onServerReady || this.defaultHook; @@ -41,12 +40,12 @@ class API { this.server = null; this.provider = null; this.defaultPort = 8555; + this.defaultNetworkName = 'soliditycoverage'; this.client = config.client; this.port = config.port || this.defaultPort; this.host = config.host || "127.0.0.1"; this.providerOptions = config.providerOptions || {}; - this.skipFiles = config.skipFiles || []; this.log = config.log || console.log; @@ -167,10 +166,7 @@ class API { return new Promise((resolve, reject) => { try { - this.coverage.generate( - this.instrumenter.instrumentationData, - this.originalContractsDir - ); + this.coverage.generate(this.instrumenter.instrumentationData); const mapping = this.makeKeysRelative(this.coverage.data, this.cwd); this.saveCoverage(mapping); @@ -230,7 +226,7 @@ class API { } // NB: EADDRINUSE errors are uncatch-able? - pify(this.server.listen)(this.port); + await pify(this.server.listen)(this.port); } assertHasBlockchain(provider){ diff --git a/lib/validator.js b/lib/validator.js index cdc5b624..1b224034 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -15,8 +15,6 @@ const configSchema = { cwd: {type: "string"}, host: {type: "string"}, - - originalContractsDir: {type: "string"}, port: {type: "number"}, providerOptions: {type: "object"}, silent: {type: "boolean"}, diff --git a/test/integration/projects/bad-solcoverjs/buidler.config.js b/test/integration/projects/bad-solcoverjs/buidler.config.js index 0e563633..084a9f23 100644 --- a/test/integration/projects/bad-solcoverjs/buidler.config.js +++ b/test/integration/projects/bad-solcoverjs/buidler.config.js @@ -1 +1,8 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/import-paths/buidler.config.js b/test/integration/projects/import-paths/buidler.config.js index 0e563633..f170d4cc 100644 --- a/test/integration/projects/import-paths/buidler.config.js +++ b/test/integration/projects/import-paths/buidler.config.js @@ -1 +1,8 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; diff --git a/test/integration/projects/import-paths/node_modules/package/package.json b/test/integration/projects/import-paths/node_modules/package/package.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/integration/projects/import-paths/node_modules/package/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/integration/projects/libraries/buidler.config.js b/test/integration/projects/libraries/buidler.config.js index 0e563633..46ea0f59 100644 --- a/test/integration/projects/libraries/buidler.config.js +++ b/test/integration/projects/libraries/buidler.config.js @@ -1 +1,7 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/multiple-migrations/buidler.config.js b/test/integration/projects/multiple-migrations/buidler.config.js index 0e563633..2ed08bf0 100644 --- a/test/integration/projects/multiple-migrations/buidler.config.js +++ b/test/integration/projects/multiple-migrations/buidler.config.js @@ -1 +1 @@ -modules.exports={}; +module.exports={}; diff --git a/test/integration/projects/multiple-suites/.solcover.js b/test/integration/projects/multiple-suites/.solcover.js new file mode 100644 index 00000000..71b990cc --- /dev/null +++ b/test/integration/projects/multiple-suites/.solcover.js @@ -0,0 +1,4 @@ +module.exports = { + "silent": false, + "istanbulReporter": [ "json-summary", "text"] +} diff --git a/test/integration/projects/multiple-suites/buidler.config.js b/test/integration/projects/multiple-suites/buidler.config.js new file mode 100644 index 00000000..084a9f23 --- /dev/null +++ b/test/integration/projects/multiple-suites/buidler.config.js @@ -0,0 +1,8 @@ +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/multiple-suites/contracts/ContractA.sol b/test/integration/projects/multiple-suites/contracts/ContractA.sol new file mode 100644 index 00000000..9d8d1344 --- /dev/null +++ b/test/integration/projects/multiple-suites/contracts/ContractA.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractA { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/multiple-suites/contracts/ContractB.sol b/test/integration/projects/multiple-suites/contracts/ContractB.sol new file mode 100644 index 00000000..daa42f7d --- /dev/null +++ b/test/integration/projects/multiple-suites/contracts/ContractB.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractB { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/multiple-suites/contracts/ContractC.sol b/test/integration/projects/multiple-suites/contracts/ContractC.sol new file mode 100644 index 00000000..454c86cd --- /dev/null +++ b/test/integration/projects/multiple-suites/contracts/ContractC.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractC { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/multiple-suites/contracts/Migrations.sol b/test/integration/projects/multiple-suites/contracts/Migrations.sol new file mode 100644 index 00000000..c378ffb0 --- /dev/null +++ b/test/integration/projects/multiple-suites/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity >=0.4.21 <0.6.0; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + constructor() public { + owner = msg.sender; + } + + modifier restricted() { + if (msg.sender == owner) _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/test/integration/projects/multiple-suites/test/contracta.js b/test/integration/projects/multiple-suites/test/contracta.js new file mode 100644 index 00000000..cc778027 --- /dev/null +++ b/test/integration/projects/multiple-suites/test/contracta.js @@ -0,0 +1,15 @@ +const ContractA = artifacts.require("ContractA"); + +contract("contracta", function(accounts) { + let instance; + + before(async () => instance = await ContractA.new()) + + it('sends [ @skipForCoverage ]', async function(){ + await instance.sendFn(); + }); + + it('calls [ @skipForCoverage ]', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/multiple-suites/test/contractb.js b/test/integration/projects/multiple-suites/test/contractb.js new file mode 100644 index 00000000..71ebfb7a --- /dev/null +++ b/test/integration/projects/multiple-suites/test/contractb.js @@ -0,0 +1,15 @@ +const ContractB = artifacts.require("ContractB"); + +contract("contractB [ @skipForCoverage ]", function(accounts) { + let instance; + + before(async () => instance = await ContractB.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/multiple-suites/test/contractc.js b/test/integration/projects/multiple-suites/test/contractc.js new file mode 100644 index 00000000..9b3d950d --- /dev/null +++ b/test/integration/projects/multiple-suites/test/contractc.js @@ -0,0 +1,20 @@ +const ContractC = artifacts.require("ContractC"); + +contract("contractc", function(accounts) { + let instance; + + before(async () => instance = await ContractC.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) + + it('sends', async function(){ + await instance.sendFn(); + }); + +}); diff --git a/test/integration/projects/multiple-suites/truffle-config.js b/test/integration/projects/multiple-suites/truffle-config.js new file mode 100644 index 00000000..b398b071 --- /dev/null +++ b/test/integration/projects/multiple-suites/truffle-config.js @@ -0,0 +1,7 @@ +module.exports = { + networks: {}, + mocha: {}, + compilers: { + solc: {} + } +} diff --git a/test/integration/projects/no-sources/buidler.config.js b/test/integration/projects/no-sources/buidler.config.js index 0e563633..46ea0f59 100644 --- a/test/integration/projects/no-sources/buidler.config.js +++ b/test/integration/projects/no-sources/buidler.config.js @@ -1 +1,7 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/skipping/buidler.config.js b/test/integration/projects/skipping/buidler.config.js index 0e563633..084a9f23 100644 --- a/test/integration/projects/skipping/buidler.config.js +++ b/test/integration/projects/skipping/buidler.config.js @@ -1 +1,8 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/test-files/.solcover.js b/test/integration/projects/test-files/.solcover.js index f73c861e..42903c81 100644 --- a/test/integration/projects/test-files/.solcover.js +++ b/test/integration/projects/test-files/.solcover.js @@ -2,6 +2,7 @@ const fn = (msg, config) => config.logger.log(msg); module.exports = { + skipFiles: ['Migrations.sol'], silent: process.env.SILENT ? true : false, istanbulReporter: ['json-summary', 'text'], onServerReady: fn.bind(null, 'running onServerReady'), diff --git a/test/integration/projects/test-files/buidler.config.js b/test/integration/projects/test-files/buidler.config.js index 0e563633..817a3eb3 100644 --- a/test/integration/projects/test-files/buidler.config.js +++ b/test/integration/projects/test-files/buidler.config.js @@ -1 +1,7 @@ -modules.exports={}; +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", +}; diff --git a/test/sources/js/truffle-test-fail.js b/test/sources/js/truffle-test-fail.js index cb08d550..5e8b79c0 100644 --- a/test/sources/js/truffle-test-fail.js +++ b/test/sources/js/truffle-test-fail.js @@ -10,4 +10,11 @@ contract('Simple', () => { const val = await simple.getX(); assert.equal(val.toNumber(), 4) // <-- Wrong result: test fails }); + + it('should set x to 2', async function() { + let simple = await Simple.new(); + await simple.test(5); + const val = await simple.getX(); + assert.equal(val.toNumber(), 2) // <-- Wrong result: test fails + }); }); diff --git a/test/units/buidler/standard.js b/test/units/buidler/standard.js new file mode 100644 index 00000000..527cca19 --- /dev/null +++ b/test/units/buidler/standard.js @@ -0,0 +1,258 @@ +const assert = require('assert'); +const fs = require('fs'); +const path = require('path') +const shell = require('shelljs'); + +const verify = require('../../util/verifiers') +const mock = require('../../util/integration'); +const plugin = require('../../../dist/buidler.plugin'); + +// ======================= +// Standard Use-case Tests +// ======================= + +describe('Buidler Plugin: standard use cases', function() { + let buidlerConfig; + let solcoverConfig; + + beforeEach(() => { + mock.clean(); + + mock.loggerOutput.val = ''; + solcoverConfig = { skipFiles: ['Migrations.sol']}; + buidlerConfig = mock.getDefaultBuidlerConfig(); + verify.cleanInitialState(); + }) + + afterEach(() => { + mock.buidlerTearDownEnv(); + mock.clean(); + }); + + it('simple contract', async function(){ + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const path = Object.keys(output)[0]; + + assert( + output[path].fnMap['1'].name === 'test', + 'coverage.json missing "test"' + ); + + assert( + output[path].fnMap['2'].name === 'getX', + 'coverage.json missing "getX"' + ); + }); + + it('with relative path solidity imports', async function() { + mock.installFullProject('import-paths'); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + }); + + it('uses inheritance', async function() { + mock.installDouble( + ['Proxy', 'Owned'], + 'inheritance.js', + solcoverConfig + ); + + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const ownedPath = Object.keys(output)[0]; + const proxyPath = Object.keys(output)[1]; + + assert( + output[ownedPath].fnMap['1'].name === 'constructor', + '"constructor" not covered' + ); + + assert( + output[proxyPath].fnMap['1'].name === 'isOwner', + '"isOwner" not covered' + ); + }); + + it('only uses ".call"', async function(){ + mock.install('OnlyCall', 'only-call.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const path = Object.keys(output)[0]; + assert( + output[path].fnMap['1'].name === 'addTwo', + 'cov should map "addTwo"' + ); + }); + + it('sends / transfers to instrumented fallback', async function(){ + mock.install('Wallet', 'wallet.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const path = Object.keys(output)[0]; + assert( + output[path].fnMap['1'].name === 'transferPayment', + 'cov should map "transferPayment"' + ); + }); + + // Truffle test asserts deployment cost is greater than 20,000,000 gas + it('deployment cost > block gasLimit', async function() { + mock.install('Expensive', 'block-gas-limit.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + }); + + // Simple.sol with a failing assertion in a truffle test + it('unit tests failing', async function() { + mock.install('Simple', 'truffle-test-fail.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert(err.message.includes('failed under coverage')); + } + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const path = Object.keys(output)[0]; + + assert(output[path].fnMap['1'].name === 'test', 'cov missing "test"'); + assert(output[path].fnMap['2'].name === 'getX', 'cov missing "getX"'); + }); + + // This project has [ @skipForCoverage ] tags in the test descriptions + // at selected 'contract' and 'it' blocks. + it('config: mocha options', async function() { + solcoverConfig.mocha = { + grep: '@skipForCoverage', + invert: true, + }; + + solcoverConfig.silent = process.env.SILENT ? true : false, + solcoverConfig.istanbulReporter = ['json-summary', 'text'] + + mock.installFullProject('multiple-suites', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + const expected = [ + { + file: mock.pathToContract(buidlerConfig, 'ContractA.sol'), + pct: 0 + }, + { + file: mock.pathToContract(buidlerConfig, 'ContractB.sol'), + pct: 0, + }, + { + file: mock.pathToContract(buidlerConfig, 'ContractC.sol'), + pct: 100, + }, + ]; + + verify.lineCoverage(expected); + }); + + // Truffle test asserts balance is 777 ether + it('config: providerOptions', async function() { + solcoverConfig.providerOptions = { default_balance_ether: 777 } + + mock.install('Simple', 'testrpc-options.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + }); + + it('config: skipped file', async function() { + solcoverConfig.skipFiles = ['Migrations.sol', 'Owned.sol']; + + mock.installDouble( + ['Proxy', 'Owned'], + 'inheritance.js', + solcoverConfig + ); + + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + verify.coverageGenerated(buidlerConfig); + + const output = mock.getOutput(buidlerConfig); + const firstKey = Object.keys(output)[0]; + + assert( + Object.keys(output).length === 1, + 'Wrong # of contracts covered' + ); + + assert( + firstKey.substr(firstKey.length - 9) === 'Proxy.sol', + 'Wrong contract covered' + ); + }); + + it('config: skipped folder', async function() { + mock.installFullProject('skipping'); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + const expected = [{ + file: mock.pathToContract(buidlerConfig, 'ContractA.sol'), + pct: 100 + }]; + + const missing = [{ + file: mock.pathToContract(buidlerConfig, 'skipped-folder/ContractB.sol'), + }]; + + verify.lineCoverage(expected); + verify.coverageMissing(missing); + }); + + it('config: "onServerReady", "onTestsComplete", ...', async function() { + mock.installFullProject('test-files'); + + mock.buidlerSetupEnv(this); + + await this.env.run("coverage"); + + assert( + mock.loggerOutput.val.includes('running onServerReady') && + mock.loggerOutput.val.includes('running onTestsComplete') && + mock.loggerOutput.val.includes('running onCompileComplete') && + mock.loggerOutput.val.includes('running onIstanbulComplete'), + + `Should run "on" hooks : ${mock.loggerOutput.val}` + ); + }); +}) \ No newline at end of file diff --git a/test/units/validator.js b/test/units/validator.js index 14335fc1..cc9aee41 100644 --- a/test/units/validator.js +++ b/test/units/validator.js @@ -22,7 +22,6 @@ describe('config validation', () => { const options = [ "cwd", "host", - "originalContractsDir", ] options.forEach(name => { diff --git a/test/util/integration.js b/test/util/integration.js index 8a50dcc6..a5313d8d 100644 --- a/test/util/integration.js +++ b/test/util/integration.js @@ -1,14 +1,16 @@ /* - Utilities for generating a mock truffle project to test plugin. + Utilities for generating & managing mock projects to test plugins. */ const path = require('path'); const fs = require('fs'); const shell = require('shelljs'); -const TruffleConfig = require('truffle-config'); const decache = require('decache'); +const TruffleConfig = require('truffle-config'); +const { resetBuidlerContext } = require("@nomiclabs/buidler/plugins-testing") + const temp = './sc_temp'; const truffleConfigName = 'truffle-config.js'; const buidlerConfigName = 'buidler.config.js'; @@ -19,6 +21,7 @@ const migrationPath = `${temp}/migrations/2_deploy.js`; const templatePath = './test/integration/generic/*'; const projectPath = './test/integration/projects/' +let previousCWD; // ========================== // Misc Utils @@ -44,11 +47,29 @@ function pathToContract(config, file) { return path.join('contracts', file); } -function getOutput(truffleConfig){ - const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); +function getOutput(config){ + const workingDir = config.working_directory || config.paths.root; + const jsonPath = path.join(workingDir, "coverage.json"); return JSON.parse(fs.readFileSync(jsonPath, 'utf8')); } +// Buidler env set up +function buidlerSetupEnv(mocha) { + const mockwd = path.join(process.cwd(), temp); + previousCWD = process.cwd(); + process.chdir(mockwd); + mocha.env = require("@nomiclabs/buidler"); + mocha.env.config.logger = testLogger + mocha.logger = testLogger +}; + +// Buidler env tear down +function buidlerTearDownEnv() { + resetBuidlerContext(); + process.chdir(previousCWD); +}; + + // ========================== // Truffle Configuration // ========================== @@ -101,34 +122,39 @@ function getDefaultBuidlerConfig() { const mockwd = path.join(process.cwd(), temp); const vals = { - root: mockwd, - artifacts: path.join(mockwd, 'artifacts'), - cache: path.join(mockwd, 'cache'), - sources: path.join(mockwd, 'contracts'), - tests: path.join(mockwd, 'test'), + paths : { + root: mockwd, + artifacts: path.join(mockwd, 'artifacts'), + cache: path.join(mockwd, 'cache'), + sources: path.join(mockwd, 'contracts'), + tests: path.join(mockwd, 'test'), + }, logger: logger, mocha: { reporter: reporter }, + defaultNetwork: "buidlerevm", networks: { development: { url: "http://127.0.0.1:8545", } }, - solc: { - version: "0.5.3", - optimizer: {} - } } return vals; } function getBuidlerConfigJS(config){ + const prefix =` + const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); + loadPluginFile(__dirname + "/../dist/buidler.plugin"); + usePlugin("@nomiclabs/buidler-truffle5"); + ` + if (config) { - return `module.exports = ${JSON.stringify(config, null, ' ')}` + return `${prefix}module.exports = ${JSON.stringify(config, null, ' ')}`; } else { - return `module.exports = ${JSON.stringify(getDefaultBuidlerConfig(), null, ' ')}` + return `${prefix}module.exports = ${JSON.stringify(getDefaultBuidlerConfig(), null, ' ')}`; } } @@ -278,6 +304,8 @@ module.exports = { installFullProject: installFullProject, clean: clean, pathToContract: pathToContract, - getOutput: getOutput + getOutput: getOutput, + buidlerSetupEnv: buidlerSetupEnv, + buidlerTearDownEnv: buidlerTearDownEnv } diff --git a/test/util/verifiers.js b/test/util/verifiers.js index 3d3afa59..38bbb5cb 100644 --- a/test/util/verifiers.js +++ b/test/util/verifiers.js @@ -28,14 +28,18 @@ function cleanInitialState(){ assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); } -function coverageGenerated(truffleConfig){ - const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); +function coverageGenerated(config){ + const workingDir = config.working_directory || config.paths.root; + const jsonPath = path.join(workingDir, "coverage.json"); + assert(pathExists('./coverage') === true, 'should gen coverage folder'); assert(pathExists(jsonPath) === true, 'should gen coverage.json'); } -function coverageNotGenerated(truffleConfig){ - const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); +function coverageNotGenerated(config){ + const workingDir = config.working_directory || config.paths.root; + const jsonPath = path.join(workingDir, "coverage.json"); + assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder'); assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json'); } From 9d98f3fd2a83f77e08a4ac0024b415b825c1335e Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sat, 19 Oct 2019 23:05:07 -0700 Subject: [PATCH 04/21] Add error test suites for Buidler plugin (#428) --- test/units/buidler/errors.js | 180 +++++++++++++++++++++++++++++++++++ test/units/truffle/errors.js | 1 - 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 test/units/buidler/errors.js diff --git a/test/units/buidler/errors.js b/test/units/buidler/errors.js new file mode 100644 index 00000000..c39c990e --- /dev/null +++ b/test/units/buidler/errors.js @@ -0,0 +1,180 @@ +const assert = require('assert'); +const fs = require('fs'); +const path = require('path') +const pify = require('pify') +const shell = require('shelljs'); +const ganache = require('ganache-core-sc'); + +const verify = require('../../util/verifiers') +const mock = require('../../util/integration'); +const plugin = require('../../../dist/buidler.plugin'); + +// ======= +// Errors +// ======= + +describe('Buidler Plugin: error cases', function() { + let buidlerConfig; + let solcoverConfig; + + beforeEach(() => { + mock.clean(); + + mock.loggerOutput.val = ''; + solcoverConfig = { skipFiles: ['Migrations.sol']}; + buidlerConfig = mock.getDefaultBuidlerConfig(); + verify.cleanInitialState(); + }) + + afterEach(() => { + mock.buidlerTearDownEnv(); + mock.clean(); + }); + + it('project contains no contract sources folder', async function() { + mock.installFullProject('no-sources'); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert( + err.message.includes('Cannot locate expected contract sources folder'), + `Should error when contract sources cannot be found:: ${err.message}` + ); + + assert( + err.message.includes('sc_temp/contracts'), + `Error message should contain path:: ${err.message}` + ); + } + + verify.coverageNotGenerated(buidlerConfig); + }); + + it('.solcover.js has syntax error', async function(){ + mock.installFullProject('bad-solcoverjs'); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert( + err.message.includes('Could not load .solcover.js config file.'), + `Should notify when solcoverjs has syntax error:: ${err.message}` + ); + } + + verify.coverageNotGenerated(buidlerConfig); + }) + + it('.solcover.js has incorrectly formatted option', async function(){ + solcoverConfig.port = "Antwerpen"; + + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch (err) { + assert( + err.message.includes('config option'), + `Should error on incorrect config options: ${err.message}` + ); + } + }); + + it('tries to launch with a port already in use', async function(){ + const server = ganache.server(); + + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await pify(server.listen)(8555); + + try { + await this.env.run("coverage"); + assert.fail(); + } catch(err){ + assert( + err.message.includes('is already in use') && + err.message.includes('lsof'), + `Should error on port-in-use with advice: ${err.message}` + ) + } + + await pify(server.close)(); + }); + + it('uses an invalid istanbul reporter', async function() { + solcoverConfig = { + silent: process.env.SILENT ? true : false, + istanbulReporter: ['does-not-exist'] + }; + + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail(); + } catch(err){ + assert( + err.message.includes('does-not-exist') && + err.message.includes('coverage reports could not be generated'), + `Should error on invalid reporter: ${err.message}` + ) + } + + }); + + // Truffle test contains syntax error + it('truffle crashes', async function() { + mock.install('Simple', 'truffle-crash.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert(err.toString().includes('SyntaxError')); + } + }); + + // Solidity syntax errors + it('compilation failure', async function(){ + mock.install('SimpleError', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert(err.message.includes('Compilation failed')); + } + + verify.coverageNotGenerated(buidlerConfig); + }); + + it('instrumentation failure', async function(){ + mock.install('Unparseable', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + try { + await this.env.run("coverage"); + assert.fail() + } catch(err){ + assert( + err.message.includes('Unparseable.sol.'), + `Should throw instrumentation errors with file name: ${err.toString()}` + ); + + assert(err.stack !== undefined, 'Should have error trace') + } + + verify.coverageNotGenerated(buidlerConfig); + }); +}) diff --git a/test/units/truffle/errors.js b/test/units/truffle/errors.js index dbbf6cc3..0521ec34 100644 --- a/test/units/truffle/errors.js +++ b/test/units/truffle/errors.js @@ -120,7 +120,6 @@ describe('Truffle Plugin: error cases', function() { } }); - // This case *does* throw an error, but it's uncatch-able; it('tries to launch with a port already in use', async function(){ const server = ganache.server(); From ce2e6c3dfb9ae043ae28f23d7f69a0c0a2c91c42 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 21 Nov 2019 22:51:50 -0800 Subject: [PATCH 05/21] Add tests for buidler cli options (#435) --- README.md | 9 +- dist/buidler.plugin.js | 22 +++-- dist/plugin-assets/buidler.ui.js | 6 +- dist/plugin-assets/buidler.utils.js | 46 ++++----- dist/plugin-assets/plugin.utils.js | 26 ++--- dist/truffle.plugin.js | 1 + package.json | 2 +- test/units/buidler/errors.js | 2 +- test/units/buidler/flags.js | 146 ++++++++++++++++++++++++++++ test/units/truffle/flags.js | 15 +-- test/units/truffle/standard.js | 2 +- test/util/integration.js | 18 +++- 12 files changed, 223 insertions(+), 72 deletions(-) create mode 100644 test/units/buidler/flags.js diff --git a/README.md b/README.md index 6024ad5f..67bb69ba 100644 --- a/README.md +++ b/README.md @@ -36,17 +36,16 @@ truffle run coverage [command-options] + Coverage launches its own in-process ganache server. + You can set [ganache options][1] using the `providerOptions` key in your `.solcover.js` [config][15]. + Coverage [distorts gas consumption][13]. Tests that check exact gas consumption should be [skipped][24]. -+ :warning: Contracts are compiled **without optimization**. Please report unexpected compilation faults to [issue 417][25] ++ :warning: Contracts are compiled **without optimization**. Please report unexpected compilation faults to [issue 417][25] ## Command Options | Option | Example | Description | |--------------|------------------------------------|--------------------------------| -| file | `--file="test/registry/*.js"` | Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)| +| file (Truffle) | `--file="test/registry/*.js"` | Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)| +| testFiles (Buidler) | `--testFiles test/file.js` | JS test file(s) to run.| | solcoverjs | `--solcoverjs ./../.solcover.js` | Relative path from working directory to config. Useful for monorepo packages that share settings. (Path must be "./" prefixed) | -| network | `--network development` | Use network settings defined in the Truffle config | +| network | `--network development` | Use network settings defined in the Truffle or Buidler config | | temp[*][14] | `--temp build` | :warning: **Caution** :warning: Path to a *disposable* folder to store compilation artifacts in. Useful when your test setup scripts include hard-coded paths to a build directory. [More...][14] | -| version | | Version info | -| help | | Usage notes | [* Advanced use][14] diff --git a/dist/buidler.plugin.js b/dist/buidler.plugin.js index dba89c48..8c005daf 100644 --- a/dist/buidler.plugin.js +++ b/dist/buidler.plugin.js @@ -17,6 +17,8 @@ const { TASK_COMPILE, } = require("@nomiclabs/buidler/builtin-tasks/task-names"); +ensurePluginLoadedWithUsePlugin(); + function plugin() { // UI for the task flags... @@ -24,11 +26,11 @@ function plugin() { task("coverage", "Generates a code coverage report for tests") - .addOptionalParam("file", ui.flags.file, null, types.string) + .addOptionalParam("testFiles", ui.flags.file, null, types.string) .addOptionalParam("solcoverjs", ui.flags.solcoverjs, null, types.string) .addOptionalParam('temp', ui.flags.temp, null, types.string) - .setAction(async function(taskArguments, env){ + .setAction(async function(args, env){ let error; let ui; let api; @@ -37,15 +39,19 @@ function plugin() { try { death(buidlerUtils.finish.bind(null, config, api)); // Catch interrupt signals - config = buidlerUtils.normalizeConfig(env.config); + config = buidlerUtils.normalizeConfig(env.config, args); ui = new PluginUI(config.logger.log); api = new API(utils.loadSolcoverJS(config)); // ============== // Server launch // ============== - - const network = buidlerUtils.setupNetwork(env, api); + const network = buidlerUtils.setupNetwork( + env, + api, + args, + ui + ); const address = await api.ganache(ganache); const web3 = new Web3(address); @@ -88,12 +94,14 @@ function plugin() { // ============== // Compilation // ============== + config.temp = args.temp; const { tempArtifactsDir, tempContractsDir } = utils.getTempLocations(config); + utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir) utils.save(targets, config.paths.sources, tempContractsDir); utils.save(skipped, config.paths.sources, tempContractsDir); @@ -109,7 +117,7 @@ function plugin() { // ====== // Tests // ====== - const testFiles = buidlerUtils.getTestFilePaths(config); + const testFiles = args.testFiles ? [args.testFiles] : []; try { await env.run(TASK_TEST, {testFiles: testFiles}) @@ -128,7 +136,7 @@ function plugin() { error = e; } - await utils.finish(config, api); + await buidlerUtils.finish(config, api); if (error !== undefined ) throw error; if (process.exitCode > 0) throw new Error(ui.generate('tests-fail', [process.exitCode])); diff --git a/dist/plugin-assets/buidler.ui.js b/dist/plugin-assets/buidler.ui.js index 78c39a38..35f35ff5 100644 --- a/dist/plugin-assets/buidler.ui.js +++ b/dist/plugin-assets/buidler.ui.js @@ -45,6 +45,10 @@ class PluginUI extends UI { `\n${c.bold('============')}\n` + `${ct} ${c.bold('port')}: ${args[1]}\n` + `${ct} ${c.bold('network')}: ${args[0]}\n`, + + 'port-clash': `${w} ${c.red("The 'port' values in your Buidler url ")}` + + `${c.red("and .solcover.js are different. Using Buidler's: ")} ${c.bold(args[0])}.\n`, + } this._write(kinds[kind]); @@ -70,8 +74,6 @@ class PluginUI extends UI { 'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`, - 'no-network': `${c.red('Network: ')} ${args[0]} ` + - `${c.red(' is not defined in your truffle-config networks. ')}`, } diff --git a/dist/plugin-assets/buidler.utils.js b/dist/plugin-assets/buidler.utils.js index 23fff0c8..9ef5dffa 100644 --- a/dist/plugin-assets/buidler.utils.js +++ b/dist/plugin-assets/buidler.utils.js @@ -10,47 +10,44 @@ const { createProvider } = require("@nomiclabs/buidler/internal/core/providers/c // Buidler Specific Plugin Utils // ============================= -/** - * Returns a list of test files to pass to TASK_TEST. - * @param {BuidlerConfig} config - * @return {String[]} list of files to pass to mocha - */ -function getTestFilePaths(config){ - let target; - - // Handle --file cli option (subset of tests) - (typeof config.file === 'string') - ? target = globby.sync([config.file]) - : target = []; - - // Return list of test files - const testregex = /.*\.(js|ts|es|es6|jsx)$/; - return target.filter(f => f.match(testregex) != null); -} - /** * Normalizes buidler paths / logging for use by the plugin utilities and * attaches them to the config * @param {BuidlerConfig} config * @return {BuidlerConfig} updated config */ -function normalizeConfig(config){ +function normalizeConfig(config, args){ config.workingDir = config.paths.root; config.contractsDir = config.paths.sources; config.testDir = config.paths.tests; config.artifactsDir = config.paths.artifacts; config.logger = config.logger ? config.logger : {log: null}; + config.solcoverjs = args.solcoverjs return config; } -function setupNetwork(env, api){ - const networkConfig = { - url: `http://${api.host}:${api.port}`, - gas: api.gasLimit, - gasPrice: api.gasPrice +function setupNetwork(env, api, taskArgs, ui){ + let networkConfig = {}; + + if (taskArgs.network){ + networkConfig = env.config.networks[taskArgs.network]; + + const configPort = networkConfig.url.split(':')[2]; + + // Warn: port conflicts + if (api.port !== api.defaultPort && api.port !== configPort){ + ui.report('port-clash', [ configPort ]) + } + + // Prefer network port + api.port = parseInt(configPort); } + networkConfig.url = `http://${api.host}:${api.port}`; + networkConfig.gas = api.gasLimit; + networkConfig.gasPrice = api.gasPrice; + const provider = createProvider(api.defaultNetworkName, networkConfig); env.config.networks[api.defaultNetworkName] = networkConfig; @@ -102,7 +99,6 @@ module.exports = { normalizeConfig: normalizeConfig, finish: finish, tempCacheDir: tempCacheDir, - getTestFilePaths: getTestFilePaths, setupNetwork: setupNetwork } diff --git a/dist/plugin-assets/plugin.utils.js b/dist/plugin-assets/plugin.utils.js index d4162eee..1dc50a93 100644 --- a/dist/plugin-assets/plugin.utils.js +++ b/dist/plugin-assets/plugin.utils.js @@ -48,6 +48,19 @@ function loadSource(_path){ return fs.readFileSync(_path).toString(); } +/** + * Sets up temporary folders for instrumented contracts and their compilation artifacts + * @param {PlatformConfig} config + * @param {String} tempContractsDir + * @param {String} tempArtifactsDir + */ +function setupTempFolders(config, tempContractsDir, tempArtifactsDir){ + checkContext(config, tempContractsDir, tempArtifactsDir); + + shell.mkdir(tempContractsDir); + shell.mkdir(tempArtifactsDir); +} + /** * Save a set of instrumented files to a temporary directory. * @param {Object[]} targets array of targets generated by `assembleTargets` @@ -122,16 +135,6 @@ function assembleFiles(config, skipFiles=[]){ let skipFolders; let skipped = []; - const { - tempContractsDir, - tempArtifactsDir - } = getTempLocations(config); - - checkContext(config, tempContractsDir, tempArtifactsDir); - - shell.mkdir(tempContractsDir); - shell.mkdir(tempArtifactsDir); - targets = shell.ls(`${config.contractsDir}/**/*.sol`); skipFiles = assembleSkipped(config, targets, skipFiles); @@ -268,5 +271,6 @@ module.exports = { reportSkipped: reportSkipped, save: save, checkContext: checkContext, - toRelativePath: toRelativePath + toRelativePath: toRelativePath, + setupTempFolders: setupTempFolders } diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index 62c4ad33..57445cd0 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -82,6 +82,7 @@ async function plugin(config){ tempContractsDir } = utils.getTempLocations(config); + utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir) utils.save(targets, config.contracts_directory, tempContractsDir); utils.save(skipped, config.contracts_directory, tempContractsDir); diff --git a/package.json b/package.json index bed3e2b5..9f411918 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "scripts": { "nyc": "SILENT=true nyc --exclude '**/sc_temp/**' --exclude '**/test/**'", "test": "npm run nyc -- mocha test/units/* --timeout 100000 --no-warnings --exit", - "test:ci": "SILENT=true nyc --reporter=lcov --exclude '**/sc_temp/**' --exclude '**/test/**/' -- mocha test/units/* --timeout 100000 --no-warnings --exit", + "test:ci": "SILENT=true node --max-old-space-size=3072 ./node_modules/.bin/nyc --reporter=lcov --exclude '**/sc_temp/**' --exclude '**/test/**/' -- mocha test/units/* --timeout 100000 --no-warnings --exit", "test:debug": "mocha test/units/* --timeout 100000 --no-warnings --exit" }, "homepage": "https://github.com/sc-forks/solidity-coverage", diff --git a/test/units/buidler/errors.js b/test/units/buidler/errors.js index c39c990e..9ab3e485 100644 --- a/test/units/buidler/errors.js +++ b/test/units/buidler/errors.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path') const pify = require('pify') const shell = require('shelljs'); -const ganache = require('ganache-core-sc'); +const ganache = require('ganache-cli') const verify = require('../../util/verifiers') const mock = require('../../util/integration'); diff --git a/test/units/buidler/flags.js b/test/units/buidler/flags.js new file mode 100644 index 00000000..435e2970 --- /dev/null +++ b/test/units/buidler/flags.js @@ -0,0 +1,146 @@ +const assert = require('assert'); +const fs = require('fs'); +const path = require('path') +const shell = require('shelljs'); + +const verify = require('../../util/verifiers') +const mock = require('../../util/integration'); +const plugin = require('../../../dist/buidler.plugin'); + +// ======================= +// CLI Options / Flags +// ======================= +async function delay(){ + return new Promise(res => setTimeout(() => res(), 1000)) +} + +describe('Buidler Plugin: command line options', function() { + let buidlerConfig; + let solcoverConfig; + + beforeEach(function(){ + mock.clean(); + + mock.loggerOutput.val = ''; + solcoverConfig = { + skipFiles: ['Migrations.sol'], + silent: process.env.SILENT ? true : false, + istanbulReporter: ['json-summary', 'text'] + }; + buidlerConfig = mock.getDefaultBuidlerConfig(); + verify.cleanInitialState(); + }) + + afterEach(async function (){ + mock.buidlerTearDownEnv(); + mock.clean(); + }); + + + it('--temp', async function(){ + const taskArgs = { + temp: 'special_folder' + } + + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + const expected = [{ + file: mock.pathToContract(buidlerConfig, 'Simple.sol'), + pct: 100 + }]; + + verify.lineCoverage(expected); + }); + + it('--network (declared port mismatches)', async function(){ + const taskArgs = { + network: 'development' // 8545 + } + + solcoverConfig.port = 8222; + + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + assert( + mock.loggerOutput.val.includes("The 'port' values"), + `Should notify about mismatched port values: ${mock.loggerOutput.val}` + ); + + assert( + mock.loggerOutput.val.includes("8545"), + `Should have used default coverage port 8545: ${mock.loggerOutput.val}` + ); + + const expected = [{ + file: mock.pathToContract(buidlerConfig, 'Simple.sol'), + pct: 100 + }]; + + verify.lineCoverage(expected); + }); + + it('--testFiles test/', async function() { + const taskArgs = { + testFiles: path.join( + buidlerConfig.paths.root, + 'test/specific_a.js' + ) + }; + + mock.installFullProject('test-files'); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + const expected = [ + { + file: mock.pathToContract(buidlerConfig, 'ContractA.sol'), + pct: 100 + }, + { + file: mock.pathToContract(buidlerConfig, 'ContractB.sol'), + pct: 0, + }, + { + file: mock.pathToContract(buidlerConfig, 'ContractC.sol'), + pct: 0, + }, + ]; + + verify.lineCoverage(expected); + }); + + it('--config ../.solcover.js', async function() { + // Write solcoverjs to parent dir of sc_temp (where the test project is installed) + fs.writeFileSync( + '.solcover.js', + `module.exports=${JSON.stringify(solcoverConfig)}` + ); + + // This relative path has to be ./ prefixed (it's path.joined to buidler's paths.root) + const taskArgs = { + solcoverjs: './../.solcover.js' + }; + + mock.install('Simple', 'simple.js'); + mock.buidlerSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + // The relative solcoverjs uses the json-summary reporter + const expected = [{ + file: mock.pathToContract(buidlerConfig, 'Simple.sol'), + pct: 100 + }]; + + verify.lineCoverage(expected); + shell.rm('.solcover.js'); + }); +}); + diff --git a/test/units/truffle/flags.js b/test/units/truffle/flags.js index 92757d5c..5cef07c4 100644 --- a/test/units/truffle/flags.js +++ b/test/units/truffle/flags.js @@ -198,20 +198,7 @@ describe('Truffle Plugin: command line options', function() { ); }); - it('--usePluginTruffle', async function(){ - truffleConfig.usePluginTruffle = true; - truffleConfig.logger = mock.testLogger; - - mock.install('Simple', 'simple.js', solcoverConfig); - await plugin(truffleConfig); - - assert( - mock.loggerOutput.val.includes('fallback Truffle library module'), - `Should notify it's using plugin truffle lib copy: ${mock.loggerOutput.val}` - ); - }); - - it('--coverageArtifacts', async function(){ + it('--temp', async function(){ truffleConfig.logger = mock.testLogger; truffleConfig.temp = 'special_location'; diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 4b767bc2..1597a385 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -156,7 +156,7 @@ describe('Truffle Plugin: standard use cases', function() { }); // Truffle test asserts deployment cost is greater than 20,000,000 gas - it('deployment cost > block gasLimit', async function() { + it.skip('deployment cost > block gasLimit', async function() { mock.install('Expensive', 'block-gas-limit.js', solcoverConfig); await plugin(truffleConfig); }); diff --git a/test/util/integration.js b/test/util/integration.js index a5313d8d..8f37e5e6 100644 --- a/test/util/integration.js +++ b/test/util/integration.js @@ -27,9 +27,17 @@ let previousCWD; // Misc Utils // ========================== function decacheConfigs(){ - decache(`${process.cwd()}/${temp}/.solcover.js`); - decache(`${process.cwd()}/${temp}/${truffleConfigName}`); - decache(`${process.cwd()}/${temp}/${buidlerConfigName}`); + const paths = [ + `${process.cwd()}/${temp}/.solcover.js`, + `${process.cwd()}/${temp}/${truffleConfigName}`, + `${process.cwd()}/${temp}/${buidlerConfigName}`, + `${process.cwd()}/${temp}/contracts/Simple.sol`, + `${process.cwd()}/${temp}/test/simple.js` + ]; + + paths.forEach(pth => { + try { decache(pth) } catch (e){} + }); } function clean() { @@ -65,8 +73,8 @@ function buidlerSetupEnv(mocha) { // Buidler env tear down function buidlerTearDownEnv() { - resetBuidlerContext(); - process.chdir(previousCWD); + resetBuidlerContext(); + process.chdir(previousCWD); }; From 367ef81fa519f85394ba8cacce574642e3ce4d73 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 22 Nov 2019 21:39:55 -0800 Subject: [PATCH 06/21] Prepare API for parallelization (#436) --- README.md | 1 + dist/plugin-assets/buidler.ui.js | 2 +- dist/plugin-assets/buidler.utils.js | 2 +- dist/plugin-assets/plugin.utils.js | 3 - lib/api.js | 73 +++++++++++-------- lib/ui.js | 6 +- package.json | 7 +- .../projects/ganache-solcoverjs/.gitignore | 1 + .../projects/ganache-solcoverjs/.solcover.js | 5 ++ .../ganache-solcoverjs/buidler.config.js | 8 ++ .../contracts/ContractA.sol | 17 +++++ .../contracts/ContractB.sol | 17 +++++ .../contracts/ContractC.sol | 17 +++++ .../contracts/Migrations.sol | 23 ++++++ .../ganache-solcoverjs/test/contracta.js | 15 ++++ .../ganache-solcoverjs/test/contractb.js | 15 ++++ .../ganache-solcoverjs/test/contractc.js | 20 +++++ .../ganache-solcoverjs/truffle-config.js | 7 ++ test/units/api.js | 54 ++++++++++++++ test/units/buidler/flags.js | 3 - test/units/truffle/flags.js | 1 + test/units/truffle/standard.js | 55 +++++++++++++- test/util/integration.js | 5 ++ test/util/util.js | 2 +- test/util/verifiers.js | 1 + 25 files changed, 310 insertions(+), 50 deletions(-) create mode 100644 test/integration/projects/ganache-solcoverjs/.gitignore create mode 100644 test/integration/projects/ganache-solcoverjs/.solcover.js create mode 100644 test/integration/projects/ganache-solcoverjs/buidler.config.js create mode 100644 test/integration/projects/ganache-solcoverjs/contracts/ContractA.sol create mode 100644 test/integration/projects/ganache-solcoverjs/contracts/ContractB.sol create mode 100644 test/integration/projects/ganache-solcoverjs/contracts/ContractC.sol create mode 100644 test/integration/projects/ganache-solcoverjs/contracts/Migrations.sol create mode 100644 test/integration/projects/ganache-solcoverjs/test/contracta.js create mode 100644 test/integration/projects/ganache-solcoverjs/test/contractb.js create mode 100644 test/integration/projects/ganache-solcoverjs/test/contractc.js create mode 100644 test/integration/projects/ganache-solcoverjs/truffle-config.js create mode 100644 test/units/api.js diff --git a/README.md b/README.md index 67bb69ba..5eb41396 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ module.exports = { | client | *Object* | `require("ganache-core")` | Useful if you need a specific ganache version. | | providerOptions | *Object* | `{ }` | [ganache-core options][1] | | skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. | +| istanbulFolder | *String* | `./coverage` | Folder location for Istanbul coverage reports. | | istanbulReporter | *Array* | `['html', 'lcov', 'text']` | [Istanbul coverage reporters][2] | | mocha | *Object* | `{ }` | [Mocha options][3] to merge into existing mocha config. `grep` and `invert` are useful for skipping certain tests under coverage using tags in the test descriptions.| | onServerReady[*][14] | *Function* | | Hook run *after* server is launched, *before* the tests execute. Useful if you need to use the Oraclize bridge or have setup scripts which rely on the server's availability. [More...][23] | diff --git a/dist/plugin-assets/buidler.ui.js b/dist/plugin-assets/buidler.ui.js index 35f35ff5..7624ab53 100644 --- a/dist/plugin-assets/buidler.ui.js +++ b/dist/plugin-assets/buidler.ui.js @@ -1,7 +1,7 @@ const UI = require('./../../lib/ui').UI; /** - * Truffle Plugin logging + * Buidler Plugin logging */ class PluginUI extends UI { constructor(log){ diff --git a/dist/plugin-assets/buidler.utils.js b/dist/plugin-assets/buidler.utils.js index 9ef5dffa..05de70d3 100644 --- a/dist/plugin-assets/buidler.utils.js +++ b/dist/plugin-assets/buidler.utils.js @@ -7,7 +7,7 @@ const { createProvider } = require("@nomiclabs/buidler/internal/core/providers/c // ============================= -// Buidler Specific Plugin Utils +// Buidler Plugin Utils // ============================= /** diff --git a/dist/plugin-assets/plugin.utils.js b/dist/plugin-assets/plugin.utils.js index 1dc50a93..002a51f2 100644 --- a/dist/plugin-assets/plugin.utils.js +++ b/dist/plugin-assets/plugin.utils.js @@ -1,9 +1,6 @@ /** * A collection of utilities for common tasks plugins will need in the course * of composing a workflow using the solidity-coverage API - * - * TODO: Sweep back through here and make all `config.truffle_variable` plugin - * platform neutral... */ const PluginUI = require('./truffle.ui'); diff --git a/lib/api.js b/lib/api.js index 4ed9d4c3..14ed170c 100644 --- a/lib/api.js +++ b/lib/api.js @@ -6,6 +6,7 @@ const istanbul = require('istanbul'); const util = require('util'); const assert = require('assert'); const detect = require('detect-port'); +const _ = require('lodash/lang'); const ConfigValidator = require('./validator'); const Instrumenter = require('./instrumenter'); @@ -17,7 +18,7 @@ const AppUI = require('./ui').AppUI; * Coverage Runner */ class API { - constructor(config) { + constructor(config={}) { this.coverage = new Coverage(); this.instrumenter = new Instrumenter(); this.validator = new ConfigValidator() @@ -54,7 +55,8 @@ class API { this.gasLimitString = "0xfffffffffff"; // block gas limit for ganache (higher than "gas sent") this.gasPrice = 0x01; - this.istanbulReporter = config.istanbulReporter || ['html', 'lcov', 'text']; + this.istanbulFolder = config.istanbulFolder || false; + this.istanbulReporter = config.istanbulReporter || ['html', 'lcov', 'text', 'json']; this.setLoggingLevel(config.silent); this.ui = new AppUI(this.log); @@ -65,21 +67,12 @@ class API { * Instruments a set of sources to prepare them for running under coverage * @param {Object[]} targets (see below) * @return {Object[]} (see below) - * @example: - * - * targets: - * [{ - * canonicalPath: - * relativePath: - * source: - * - * },...] - * - * outputs: - * [{ - * canonicalPath: - * source: - * }...] + * @example of input/output array: + * [{ + * source: (required) , + * canonicalPath: (required) + * relativePath: (optional) + * }] */ instrument(targets=[]) { let currentFile; // Keep track of filename in case we crash... @@ -95,7 +88,7 @@ class API { this.ui.report('instr-start'); } - this.ui.report('instr-item', [target.relativePath]); + this.ui.report('instr-item', [currentFile]); const instrumented = this.instrumenter.instrument( target.source, @@ -119,22 +112,35 @@ class API { return outputs; } + /** + * Returns a copy of the hit map created during instrumentation. + * Useful if you'd like to delegate coverage collection to multiple processes. + * @return {Object} instrumentationData + */ + getInstrumentationData(){ + return _.cloneDeep(this.instrumenter.instrumentationData) + } + + /** + * Sets the hit map object generated during instrumentation. Useful if you'd like + * to collect data for a pre-existing instrumentation. + * @param {Object} data + */ + setInstrumentationData(data={}){ + this.instrumenter.instrumentationData = _.cloneDeep(data); + } + /** * Launches an in-process ethereum client server, hooking the DataCollector to its VM. * @param {Object} client ganache client * @return {String} address of server to connect to */ async ganache(client){ - let retry = false; - let address = `http://${this.host}:${this.port}`; - // Check for port-in-use if (await detect(this.port) !== this.port){ throw new Error(this.ui.generate('server-fail', [this.port])) } - if(!this.client) this.client = client; // Prefer client from options - this.collector = new DataCollector(this.instrumenter.instrumentationData); this.providerOptions.gasLimit = this.gasLimitString; @@ -143,16 +149,17 @@ class API { // Launch server and attach to vm step of supplied client try { if (this.config.forceBackupServer) throw new Error() - await this.attachToVM() + await this.attachToVM(client) } - // Fallback to ganache-core-sc (eq: ganache-core 2.7.0) + // Fallback to ganache-cli) catch(err) { - this.ui.report('vm-fail', []); - this.client = require('ganache-core-sc'); - await this.attachToVM(); + const _ganache = require('ganache-cli'); + this.ui.report('vm-fail', [_ganache.version]); + await this.attachToVM(_ganache); } + const address = `http://${this.host}:${this.port}`; this.ui.report('server', [address]); return address; } @@ -162,7 +169,7 @@ class API { */ async report() { const collector = new istanbul.Collector(); - const reporter = new istanbul.Reporter(); + const reporter = new istanbul.Reporter(false, this.istanbulFolder); return new Promise((resolve, reject) => { try { @@ -177,7 +184,8 @@ class API { // Pify doesn't like this one... reporter.write(collector, true, (err) => { - if (err) throw err; + if (err) return reject(err); + this.ui.report('istanbul'); resolve(); }); @@ -204,9 +212,11 @@ class API { // ======== // Provider // ======== - async attachToVM(){ + async attachToVM(client){ const self = this; + // Prefer client from options + if(!this.client) this.client = client; this.server = this.client.server(this.providerOptions); this.assertHasBlockchain(this.server.provider); @@ -225,7 +235,6 @@ class API { return vm; } - // NB: EADDRINUSE errors are uncatch-able? await pify(this.server.listen)(this.port); } diff --git a/lib/ui.js b/lib/ui.js index 97b534a0..cbad7772 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -56,9 +56,9 @@ class AppUI extends UI { const w = ":warning:"; const kinds = { - 'vm-fail': `${w} ${c.red('There was a problem attaching to the ganache-core VM.')} `+ - `${c.red('Check the provider option syntax in solidity-coverage docs.')}\n`+ - `${w} ${c.red('Using ganache-core-sc (eq. core v2.7.0) instead.')}\n`, + 'vm-fail': `${w} ${c.red('There was a problem attaching to the ganache VM.')}\n` + + `${w} ${c.red('For help, see the "client" & "providerOptions" syntax in solidity-coverage docs.')}\n`+ + `${w} ${c.red(`Using ganache-cli (v${args[0]}) instead.`)}\n`, 'instr-start': `\n${c.bold('Instrumenting for coverage...')}` + diff --git a/package.json b/package.json index 9f411918..3d634697 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ }, "scripts": { "nyc": "SILENT=true nyc --exclude '**/sc_temp/**' --exclude '**/test/**'", - "test": "npm run nyc -- mocha test/units/* --timeout 100000 --no-warnings --exit", - "test:ci": "SILENT=true node --max-old-space-size=3072 ./node_modules/.bin/nyc --reporter=lcov --exclude '**/sc_temp/**' --exclude '**/test/**/' -- mocha test/units/* --timeout 100000 --no-warnings --exit", - "test:debug": "mocha test/units/* --timeout 100000 --no-warnings --exit" + "test": "SILENT=true node --max-old-space-size=4096 ./node_modules/.bin/nyc -- mocha test/units/* --timeout 100000 --no-warnings --exit", + "test:ci": "SILENT=true node --max-old-space-size=4096 ./node_modules/.bin/nyc --reporter=lcov --exclude '**/sc_temp/**' --exclude '**/test/**/' -- mocha test/units/* --timeout 100000 --no-warnings --exit", + "test:debug": "node --max-old-space-size=4096 ./node_modules/.bin/mocha test/units/* --timeout 100000 --no-warnings --exit" }, "homepage": "https://github.com/sc-forks/solidity-coverage", "repository": { @@ -35,6 +35,7 @@ "globby": "^10.0.1", "istanbul": "^0.4.5", "jsonschema": "^1.2.4", + "lodash": "^4.17.15", "node-dir": "^0.1.17", "node-emoji": "^1.10.0", "pify": "^4.0.1", diff --git a/test/integration/projects/ganache-solcoverjs/.gitignore b/test/integration/projects/ganache-solcoverjs/.gitignore new file mode 100644 index 00000000..736e8ae5 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/.gitignore @@ -0,0 +1 @@ +!node_modules \ No newline at end of file diff --git a/test/integration/projects/ganache-solcoverjs/.solcover.js b/test/integration/projects/ganache-solcoverjs/.solcover.js new file mode 100644 index 00000000..6e2f5326 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/.solcover.js @@ -0,0 +1,5 @@ +module.exports = { + client: require('ganache-cli'), + silent: process.env.SILENT ? true : false, + istanbulReporter: ['json-summary', 'text'], +} diff --git a/test/integration/projects/ganache-solcoverjs/buidler.config.js b/test/integration/projects/ganache-solcoverjs/buidler.config.js new file mode 100644 index 00000000..084a9f23 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/buidler.config.js @@ -0,0 +1,8 @@ +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../dist/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/ganache-solcoverjs/contracts/ContractA.sol b/test/integration/projects/ganache-solcoverjs/contracts/ContractA.sol new file mode 100644 index 00000000..9d8d1344 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/contracts/ContractA.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractA { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/ganache-solcoverjs/contracts/ContractB.sol b/test/integration/projects/ganache-solcoverjs/contracts/ContractB.sol new file mode 100644 index 00000000..daa42f7d --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/contracts/ContractB.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractB { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/ganache-solcoverjs/contracts/ContractC.sol b/test/integration/projects/ganache-solcoverjs/contracts/ContractC.sol new file mode 100644 index 00000000..454c86cd --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/contracts/ContractC.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractC { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/ganache-solcoverjs/contracts/Migrations.sol b/test/integration/projects/ganache-solcoverjs/contracts/Migrations.sol new file mode 100644 index 00000000..c378ffb0 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity >=0.4.21 <0.6.0; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + constructor() public { + owner = msg.sender; + } + + modifier restricted() { + if (msg.sender == owner) _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/test/integration/projects/ganache-solcoverjs/test/contracta.js b/test/integration/projects/ganache-solcoverjs/test/contracta.js new file mode 100644 index 00000000..cc778027 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/test/contracta.js @@ -0,0 +1,15 @@ +const ContractA = artifacts.require("ContractA"); + +contract("contracta", function(accounts) { + let instance; + + before(async () => instance = await ContractA.new()) + + it('sends [ @skipForCoverage ]', async function(){ + await instance.sendFn(); + }); + + it('calls [ @skipForCoverage ]', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/ganache-solcoverjs/test/contractb.js b/test/integration/projects/ganache-solcoverjs/test/contractb.js new file mode 100644 index 00000000..71ebfb7a --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/test/contractb.js @@ -0,0 +1,15 @@ +const ContractB = artifacts.require("ContractB"); + +contract("contractB [ @skipForCoverage ]", function(accounts) { + let instance; + + before(async () => instance = await ContractB.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/ganache-solcoverjs/test/contractc.js b/test/integration/projects/ganache-solcoverjs/test/contractc.js new file mode 100644 index 00000000..9b3d950d --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/test/contractc.js @@ -0,0 +1,20 @@ +const ContractC = artifacts.require("ContractC"); + +contract("contractc", function(accounts) { + let instance; + + before(async () => instance = await ContractC.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) + + it('sends', async function(){ + await instance.sendFn(); + }); + +}); diff --git a/test/integration/projects/ganache-solcoverjs/truffle-config.js b/test/integration/projects/ganache-solcoverjs/truffle-config.js new file mode 100644 index 00000000..b398b071 --- /dev/null +++ b/test/integration/projects/ganache-solcoverjs/truffle-config.js @@ -0,0 +1,7 @@ +module.exports = { + networks: {}, + mocha: {}, + compilers: { + solc: {} + } +} diff --git a/test/units/api.js b/test/units/api.js new file mode 100644 index 00000000..c6fc90c0 --- /dev/null +++ b/test/units/api.js @@ -0,0 +1,54 @@ +const assert = require('assert'); +const util = require('./../util/util.js'); +const API = require('./../../lib/api.js'); + +describe('api', () => { + const opts = {silent: true}; + + it('getInstrumentationData', function(){ + const api = new API(opts); + const canonicalPath = 'statements/single.sol' + const source = util.getCode(canonicalPath); + + api.instrument([{ + source: source, + canonicalPath: canonicalPath + }]); + + const data = api.getInstrumentationData(); + + const hash = Object.keys(data)[0]; + assert(data[hash].hits === 0); + }); + + it('setInstrumentationData', function(){ + let api = new API(opts); + + const canonicalPath = 'statements/single.sol' + const source = util.getCode(canonicalPath); + + api.instrument([{ + source: source, + canonicalPath: canonicalPath + }]); + + const cloneA = api.getInstrumentationData(); + const hash = Object.keys(cloneA)[0]; + + // Verify cloning + cloneA[hash].hits = 5; + const cloneB = api.getInstrumentationData(); + assert(cloneB[hash].hits === 0); + + // Verify setting + api = new API(opts); + api.instrument([{ + source: source, + canonicalPath: canonicalPath + }]); + + api.setInstrumentationData(cloneA); + const cloneC = api.getInstrumentationData(); + assert(cloneC[hash].hits === 5); + }); +}) diff --git a/test/units/buidler/flags.js b/test/units/buidler/flags.js index 435e2970..8e451583 100644 --- a/test/units/buidler/flags.js +++ b/test/units/buidler/flags.js @@ -10,9 +10,6 @@ const plugin = require('../../../dist/buidler.plugin'); // ======================= // CLI Options / Flags // ======================= -async function delay(){ - return new Promise(res => setTimeout(() => res(), 1000)) -} describe('Buidler Plugin: command line options', function() { let buidlerConfig; diff --git a/test/units/truffle/flags.js b/test/units/truffle/flags.js index 5cef07c4..f3c63cc0 100644 --- a/test/units/truffle/flags.js +++ b/test/units/truffle/flags.js @@ -22,6 +22,7 @@ describe('Truffle Plugin: command line options', function() { solcoverConfig = {}; truffleConfig = mock.getDefaultTruffleConfig(); verify.cleanInitialState(); + }) afterEach(() => mock.clean()); diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 1597a385..5d0824bf 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -47,7 +47,7 @@ describe('Truffle Plugin: standard use cases', function() { }); // Instrumentation speed is fine - but this takes solc almost a minute to compile - // so annoying. Unskip whenever modifying the instrumentation files though..... + // Unskip whenever modifying the instrumentation files though..... it.skip('with many unbracketed statements (time check)', async function() { truffleConfig.compilers.solc.version = "0.4.24"; @@ -156,7 +156,10 @@ describe('Truffle Plugin: standard use cases', function() { }); // Truffle test asserts deployment cost is greater than 20,000,000 gas - it.skip('deployment cost > block gasLimit', async function() { + // Test times out on CircleCI @ 100000 ms. Fine locally though. + it('deployment cost > block gasLimit', async function() { + if (process.env.CI) return; + mock.install('Expensive', 'block-gas-limit.js', solcoverConfig); await plugin(truffleConfig); }); @@ -181,6 +184,24 @@ describe('Truffle Plugin: standard use cases', function() { assert(output[path].fnMap['2'].name === 'getX', 'cov missing "getX"'); }); + // This test tightly coupled to the ganache version in truffle dev dep + it('uses the server from truffle by default', async function(){ + truffleConfig.logger = mock.testLogger; + truffleConfig.version = true; + + // Baseline inequality check + const truffleClientVersion = "v2.5.7"; + + // Truffle client + mock.install('Simple', 'simple.js', solcoverConfig); + await plugin(truffleConfig); + + assert( + mock.loggerOutput.val.includes(truffleClientVersion), + `Should use truffles ganache: ${mock.loggerOutput.val}` + ); + }); + it('uses the fallback server', async function(){ truffleConfig.logger = mock.testLogger; solcoverConfig.forceBackupServer = true; @@ -189,11 +210,39 @@ describe('Truffle Plugin: standard use cases', function() { await plugin(truffleConfig); assert( - mock.loggerOutput.val.includes("Using ganache-core-sc"), + mock.loggerOutput.val.includes("Using ganache-cli"), `Should notify about backup server module: ${mock.loggerOutput.val}` ); }); + // This test tightly coupled to the ganache version in production deps + // "test-files" project solcoverjs includes `client: require('ganache-cli')` + it('config: client', async function(){ + truffleConfig.logger = mock.testLogger; + truffleConfig.version = true; + + const configClientVersion = "v2.8.0"; + + // Config client + mock.installFullProject('ganache-solcoverjs'); + await plugin(truffleConfig); + + assert( + mock.loggerOutput.val.includes(configClientVersion), + `Should use solcover provided ganache: ${mock.loggerOutput.val}` + ); + }); + + it('config: istanbulFolder', async function(){ + solcoverConfig.istanbulFolder = mock.pathToTemp('specialFolder'); + + // Truffle client + mock.install('Simple', 'simple.js', solcoverConfig); + await plugin(truffleConfig); + + assert(verify.pathExists(solcoverConfig.istanbulFolder)); + }); + // This project has [ @skipForCoverage ] tags in the test descriptions // at selected 'contract' and 'it' blocks. it('config: mocha options', async function() { diff --git a/test/util/integration.js b/test/util/integration.js index 8f37e5e6..dbc6d420 100644 --- a/test/util/integration.js +++ b/test/util/integration.js @@ -55,6 +55,10 @@ function pathToContract(config, file) { return path.join('contracts', file); } +function pathToTemp(_path) { + return path.join(temp, _path); +} + function getOutput(config){ const workingDir = config.working_directory || config.paths.root; const jsonPath = path.join(workingDir, "coverage.json"); @@ -303,6 +307,7 @@ const testLogger = { module.exports = { + pathToTemp: pathToTemp, testLogger: testLogger, loggerOutput: loggerOutput, getDefaultTruffleConfig: getDefaultTruffleConfig, diff --git a/test/util/util.js b/test/util/util.js index 85874055..ff101db3 100644 --- a/test/util/util.js +++ b/test/util/util.js @@ -118,11 +118,11 @@ function initializeProvider(ganache){ } module.exports = { + getCode: getCode, pathPrefix: pathPrefix, filePath: filePath, report: report, instrumentAndCompile: instrumentAndCompile, bootstrapCoverage: bootstrapCoverage, initializeProvider: initializeProvider, - } diff --git a/test/util/verifiers.js b/test/util/verifiers.js index 38bbb5cb..b5a25d77 100644 --- a/test/util/verifiers.js +++ b/test/util/verifiers.js @@ -45,6 +45,7 @@ function coverageNotGenerated(config){ } module.exports = { + pathExists: pathExists, lineCoverage: lineCoverage, coverageMissing: coverageMissing, cleanInitialState: cleanInitialState, From d0f188f966b959b7b9645d34119c29662959a604 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sat, 23 Nov 2019 10:34:59 -0800 Subject: [PATCH 07/21] Add autoLauchServer option / update config validator (#437) --- README.md | 10 +++++----- lib/api.js | 23 +++++++++++++++-------- lib/validator.js | 3 +++ test/units/api.js | 36 +++++++++++++++++++++++++++++++++++- test/units/validator.js | 29 +++++++++++++++++++++++++++-- 5 files changed, 85 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5eb41396..3f19fa67 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ truffle run coverage [command-options] ## Command Options | Option | Example | Description | |--------------|------------------------------------|--------------------------------| -| file (Truffle) | `--file="test/registry/*.js"` | Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)| -| testFiles (Buidler) | `--testFiles test/file.js` | JS test file(s) to run.| +| file | `--file="test/registry/*.js"` | (Truffle) Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)| +| testFiles | `--testFiles test/file.js` | (Buidler) JS test file(s) to run.| | solcoverjs | `--solcoverjs ./../.solcover.js` | Relative path from working directory to config. Useful for monorepo packages that share settings. (Path must be "./" prefixed) | | network | `--network development` | Use network settings defined in the Truffle or Buidler config | | temp[*][14] | `--temp build` | :warning: **Caution** :warning: Path to a *disposable* folder to store compilation artifacts in. Useful when your test setup scripts include hard-coded paths to a build directory. [More...][14] | @@ -69,12 +69,12 @@ module.exports = { | providerOptions | *Object* | `{ }` | [ganache-core options][1] | | skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. | | istanbulFolder | *String* | `./coverage` | Folder location for Istanbul coverage reports. | -| istanbulReporter | *Array* | `['html', 'lcov', 'text']` | [Istanbul coverage reporters][2] | +| istanbulReporter | *Array* | `['html', 'lcov', 'text', 'json']` | [Istanbul coverage reporters][2] | | mocha | *Object* | `{ }` | [Mocha options][3] to merge into existing mocha config. `grep` and `invert` are useful for skipping certain tests under coverage using tags in the test descriptions.| | onServerReady[*][14] | *Function* | | Hook run *after* server is launched, *before* the tests execute. Useful if you need to use the Oraclize bridge or have setup scripts which rely on the server's availability. [More...][23] | | onCompileComplete[*][14] | *Function* | | Hook run *after* compilation completes, *before* tests are run. Useful if you have secondary compilation steps or need to modify built artifacts. [More...][23]| -| onTestsComplete[*][14] | *Function* | | Hook run *after* the tests complete, *before* Istanbul reports are generated.| -| onIstanbulComplete[*][14] | *Function* | | Hook run *after* the Istanbul reports are generated, *before* the ganache server is shut down. Useful if you need to clean resources up.| +| onTestsComplete[*][14] | *Function* | | Hook run *after* the tests complete, *before* Istanbul reports are generated. [More...][23]| +| onIstanbulComplete[*][14] | *Function* | | Hook run *after* the Istanbul reports are generated, *before* the ganache server is shut down. Useful if you need to clean resources up. [More...][23]| [* Advanced use][14] diff --git a/lib/api.js b/lib/api.js index 14ed170c..0d710e15 100644 --- a/lib/api.js +++ b/lib/api.js @@ -46,6 +46,7 @@ class API { this.port = config.port || this.defaultPort; this.host = config.host || "127.0.0.1"; this.providerOptions = config.providerOptions || {}; + this.autoLaunchServer = config.autoLaunchServer === false ? false : true; this.skipFiles = config.skipFiles || []; @@ -60,7 +61,6 @@ class API { this.setLoggingLevel(config.silent); this.ui = new AppUI(this.log); - } /** @@ -131,11 +131,15 @@ class API { } /** - * Launches an in-process ethereum client server, hooking the DataCollector to its VM. - * @param {Object} client ganache client - * @return {String} address of server to connect to + * Enables coverage collection on in-process ethereum client server, hooking the DataCollector + * to its VM. By default, method will return a url after server has begun listening on the port + * specified in the config. When `autoLaunchServer` is false, method returns`ganache.server` so + * the consumer can control the 'server.listen' invocation themselves. + * @param {Object} client ganache client + * @param {Boolean} autoLaunchServer boolean + * @return {String | Server} address of server to connect to, or initialized, unlaunched server. */ - async ganache(client){ + async ganache(client, autoLaunchServer){ // Check for port-in-use if (await detect(this.port) !== this.port){ throw new Error(this.ui.generate('server-fail', [this.port])) @@ -146,7 +150,7 @@ class API { this.providerOptions.gasLimit = this.gasLimitString; this.providerOptions.allowUnlimitedContractSize = true; - // Launch server and attach to vm step of supplied client + // Attach to vm step of supplied client try { if (this.config.forceBackupServer) throw new Error() await this.attachToVM(client) @@ -159,6 +163,11 @@ class API { await this.attachToVM(_ganache); } + if (autoLaunchServer === false || this.autoLaunchServer === false){ + return this.server; + } + + await pify(this.server.listen)(this.port); const address = `http://${this.host}:${this.port}`; this.ui.report('server', [address]); return address; @@ -234,8 +243,6 @@ class API { vm.on('step', self.collector.step.bind(self.collector)); return vm; } - - await pify(this.server.listen)(this.port); } assertHasBlockchain(provider){ diff --git a/lib/validator.js b/lib/validator.js index 1b224034..59b1703e 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -18,9 +18,12 @@ const configSchema = { port: {type: "number"}, providerOptions: {type: "object"}, silent: {type: "boolean"}, + autoLaunchServer: {type: "boolean"}, + istanbulFolder: {type: "string"}, // Hooks: onServerReady: {type: "function", format: "isFunction"}, + onCompileComplete: {type: "function", format: "isFunction"}, onTestComplete: {type: "function", format: "isFunction"}, onIstanbulComplete: {type: "function", format: "isFunction"}, diff --git a/test/units/api.js b/test/units/api.js index c6fc90c0..88ba3df1 100644 --- a/test/units/api.js +++ b/test/units/api.js @@ -1,9 +1,13 @@ const assert = require('assert'); const util = require('./../util/util.js'); const API = require('./../../lib/api.js'); +const detect = require('detect-port'); +const Ganache = require('ganache-cli'); describe('api', () => { - const opts = {silent: true}; + let opts; + + beforeEach(() => opts = {silent: true}) it('getInstrumentationData', function(){ const api = new API(opts); @@ -51,4 +55,34 @@ describe('api', () => { const cloneC = api.getInstrumentationData(); assert(cloneC[hash].hits === 5); }); + + it('ganache: autoLaunchServer === false', async function(){ + const api = new API(opts); + const port = api.port; + const server = await api.ganache(Ganache, false); + + assert(typeof port === 'number') + assert(typeof server === 'object'); + assert(typeof server.listen === 'function'); + + const freePort = await detect(port); + + assert(freePort === port); + }); + + it('config: autoLaunchServer: false', async function(){ + opts.autoLaunchServer = false; + + const api = new API(opts); + const port = api.port; + const server = await api.ganache(Ganache); + + assert(typeof port === 'number') + assert(typeof server === 'object'); + assert(typeof server.listen === 'function'); + + const freePort = await detect(port); + + assert(freePort === port); + }) }) diff --git a/test/units/validator.js b/test/units/validator.js index cc9aee41..67976200 100644 --- a/test/units/validator.js +++ b/test/units/validator.js @@ -22,6 +22,7 @@ describe('config validation', () => { const options = [ "cwd", "host", + "istanbulFolder" ] options.forEach(name => { @@ -41,6 +42,29 @@ describe('config validation', () => { }); }); + it('validates the "boolean" options', function(){ + const options = [ + "silent", + "autoLaunchServer", + ] + + options.forEach(name => { + // Pass + solcoverjs = {}; + solcoverjs[name] = false; + assert(validator.validate(solcoverjs), `${name} boolean should be valid`) + + // Fail + solcoverjs[name] = "false"; + try { + validator.validate(solcoverjs); + assert.fail() + } catch (err){ + assert(err.message.includes(`"${name}" is not of a type(s) boolean`), err.message); + } + }); + }); + it('validates the "object" options', function(){ const options = [ "client", @@ -86,7 +110,7 @@ describe('config validation', () => { }); }); - it('validates string array options', function(){ + it('validates the "string[]" options', function(){ const options = [ "skipFiles", "istanbulReporter", @@ -109,9 +133,10 @@ describe('config validation', () => { }); }); - it('validates function options', function(){ + it('validates the "function" options', function(){ const options = [ + "onCompileComplete", "onServerReady", "onTestComplete", "onIstanbulComplete", From 404c73d205a72ae583201955a1c373478f981366 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 24 Nov 2019 12:31:34 -0800 Subject: [PATCH 08/21] Add simple E2E for Buidler (#438) --- .circleci/config.yml | 10 ++++++++++ package.json | 3 +-- scripts/run-buidler.sh | 37 +++++++++++++++++++++++++++++++++++++ scripts/run-metacoin.sh | 7 +++++++ truffle-plugin.json | 2 +- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100755 scripts/run-buidler.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 61484596..ec2d2fb4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,6 +73,15 @@ jobs: name: MetaCoin E2E command: | ./scripts/run-metacoin.sh + e2e-buidler: + machine: true + steps: + - checkout + - <<: *step_install_nvm + - run: + name: Buidler E2E + command: | + ./scripts/run-buidler.sh workflows: version: 2 build: @@ -80,6 +89,7 @@ workflows: - unit-test - e2e-zeppelin - e2e-metacoin + - e2e-buidler # TODO: re-enable. # At the moment we're using forks so this is pointless #nightly: diff --git a/package.json b/package.json index 3d634697..065270f6 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,7 @@ "name": "solidity-coverage", "version": "0.7.0-beta.2", "description": "", - "main": "index.js", - "buidler": "dist/buidler.coverage.js", + "main": "dist/buidler.plugin.js", "bin": { "solidity-coverage": "./dist/bin.js" }, diff --git a/scripts/run-buidler.sh b/scripts/run-buidler.sh new file mode 100755 index 00000000..bc7dd3f4 --- /dev/null +++ b/scripts/run-buidler.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# E2E CI: installs PR candidate on sc-forks/buidler-e2e (a simple example, +# similar to Metacoin) and runs coverage +# + +set -o errexit + +# Get rid of any caches +sudo rm -rf node_modules +echo "NVM CURRENT >>>>>" && nvm current + +# Use PR env variables (for forks) or fallback on local if PR not available +SED_REGEX="s/git@github.com:/https:\/\/github.com\//" + +if [[ -v CIRCLE_PR_REPONAME ]]; then + PR_PATH="https://github.com/$CIRCLE_PR_USERNAME/$CIRCLE_PR_REPONAME#$CIRCLE_SHA1" +else + PR_PATH=$(echo "$CIRCLE_REPOSITORY_URL#$CIRCLE_SHA1" | sudo sed "$SED_REGEX") +fi + +echo "PR_PATH >>>>> $PR_PATH" + +# Install buidler e2e test +git clone https://github.com/sc-forks/buidler-e2e.git +cd buidler-e2e +npm install + +# Install and run solidity-coverage @ PR +npm install --save-dev $PR_PATH +npx buidler coverage + +# Test that coverage/ was generated +if [ ! -d "coverage" ]; then + echo "ERROR: no coverage folder was created." + exit 1 +fi diff --git a/scripts/run-metacoin.sh b/scripts/run-metacoin.sh index 29debd08..91854459 100755 --- a/scripts/run-metacoin.sh +++ b/scripts/run-metacoin.sh @@ -39,3 +39,10 @@ cat truffle-config.js npm init --yes yarn add $PR_PATH --dev npx truffle run coverage + +# Test that coverage/ was generated +if [ ! -d "coverage" ]; then + echo "ERROR: no coverage folder was created." + exit 1 +fi + diff --git a/truffle-plugin.json b/truffle-plugin.json index 2e545e1d..31df017d 100644 --- a/truffle-plugin.json +++ b/truffle-plugin.json @@ -1,5 +1,5 @@ { "commands": { - "coverage": "dist/truffle.plugin.js" + "coverage": "truffle.plugin.js" } } From 33b33f940996978052b5d03093fca516360ed9e2 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 24 Nov 2019 16:19:48 -0800 Subject: [PATCH 09/21] Moloch E2E (#439) --- .circleci/config.yml | 29 ++++++++++++++--------------- scripts/run-moloch.sh | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 15 deletions(-) create mode 100755 scripts/run-moloch.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index ec2d2fb4..11eb785d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,7 @@ version: 2.0 -# Necessary for running in machine mode, which is necessary to execute the -# Zeppelin and MetaCoin E2E scripts + +# Necessary for running in machine mode, +# which is necessary to execute the E2E scripts step_install_nvm: &step_install_nvm run: name: "Install nvm for machine" @@ -12,6 +13,7 @@ step_install_nvm: &step_install_nvm nvm alias default v8.15.0 echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV + jobs: unit-test: machine: true @@ -82,6 +84,15 @@ jobs: name: Buidler E2E command: | ./scripts/run-buidler.sh + e2e-moloch: + machine: true + steps: + - checkout + - <<: *step_install_nvm + - run: + name: Moloch E2E + command: | + ./scripts/run-moloch.sh workflows: version: 2 build: @@ -90,16 +101,4 @@ workflows: - e2e-zeppelin - e2e-metacoin - e2e-buidler - # TODO: re-enable. - # At the moment we're using forks so this is pointless - #nightly: - # triggers: - # - schedule: - # cron: "0 1 * * *" # 1am UTC - # filters: - # branches: - # only: - # - master - # jobs: - #- e2e-zeppelin - #- e2e-colony + - e2e-moloch diff --git a/scripts/run-moloch.sh b/scripts/run-moloch.sh new file mode 100755 index 00000000..4c1191ee --- /dev/null +++ b/scripts/run-moloch.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# +# E2E CI: installs PR candidate on sc-forks/buidler-e2e (a simple example, +# similar to Metacoin) and runs coverage +# + +set -o errexit + +# Get rid of any caches +sudo rm -rf node_modules +echo "NVM CURRENT >>>>>" && nvm current + +# Use PR env variables (for forks) or fallback on local if PR not available +SED_REGEX="s/git@github.com:/https:\/\/github.com\//" + +if [[ -v CIRCLE_PR_REPONAME ]]; then + PR_PATH="https://github.com/$CIRCLE_PR_USERNAME/$CIRCLE_PR_REPONAME#$CIRCLE_SHA1" +else + PR_PATH=$(echo "$CIRCLE_REPOSITORY_URL#$CIRCLE_SHA1" | sudo sed "$SED_REGEX") +fi + +echo "PR_PATH >>>>> $PR_PATH" + +# Install buidler e2e test +git clone https://github.com/sc-forks/moloch.git +cd moloch +npm install +npm uninstall --save-dev solidity-coverage + +# Install and run solidity-coverage @ PR +npm install --save-dev $PR_PATH +npm run coverage + +# Test that coverage/ was generated +if [ ! -d "coverage" ]; then + echo "ERROR: no coverage folder was created." + exit 1 +fi From 4f73e1585c3ce3586fa79f29a2bbb2d3d8c370f9 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 24 Nov 2019 17:32:24 -0800 Subject: [PATCH 10/21] Add buidler config and run info (#440) * Add buidler config and run info * Sub 'add' for 'use' * Add docs links --- README.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3f19fa67..4ff578b0 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ ![npm (tag)](https://img.shields.io/npm/v/solidity-coverage/beta) [![CircleCI](https://circleci.com/gh/sc-forks/solidity-coverage.svg?style=svg)][20] [![codecov](https://codecov.io/gh/sc-forks/solidity-coverage/branch/beta/graph/badge.svg)][21] +[![buidler](https://buidler.dev/buidler-plugin-badge.svg?1)][26] + ## Code coverage for Solidity testing ![coverage example][22] @@ -17,9 +19,9 @@ $ npm install --save-dev solidity-coverage@beta ``` -## Truffle V5 +### Truffle V5 -**Add** this package to your plugins array in `truffle-config.js` +**Add** this package to your plugins array in `truffle-config.js` ([Truffle docs][27]) ```javascript module.exports = { networks: {...}, @@ -31,6 +33,21 @@ module.exports = { truffle run coverage [command-options] ``` +### Buidler + +**Add** the plugin in `buidler.config.js` ([Buidler docs][26]) +```javascript +usePlugin('solidity-coverage') + +module.exports = { + networks: {...}, +} +``` +**Run** +``` +npx buidler coverage [command-options] +``` + ## Usage notes: + Coverage runs tests a little more slowly. + Coverage launches its own in-process ganache server. @@ -62,7 +79,7 @@ module.exports = { ``` -| Option | Type | Default | Description | +| Option | Type | Default | Description | | ------ | ---- | ------- | ----------- | | silent | *Boolean* | false | Suppress logging output | | client | *Object* | `require("ganache-core")` | Useful if you need a specific ganache version. | @@ -152,3 +169,5 @@ $ yarn [23]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/advanced.md#workflow-hooks [24]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/advanced.md#skipping-tests [25]: https://github.com/sc-forks/solidity-coverage/issues/417 +[26]: https://buidler.dev/ +[27]: https://www.trufflesuite.com/docs From 97de9c6012b44202f2736e7368696064f0006f73 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Tue, 26 Nov 2019 23:43:00 -0800 Subject: [PATCH 11/21] Add builder-ethers test to CI (#441) * Let plugins manage which client is used * Use requested network name --- dist/buidler.plugin.js | 15 +++++--------- dist/plugin-assets/buidler.utils.js | 20 ++++++++++-------- dist/truffle.plugin.js | 3 ++- lib/api.js | 9 ++++---- scripts/run-buidler.sh | 32 ++++++++++++++++++++++++++++- scripts/run-moloch.sh | 1 + test/units/buidler/flags.js | 13 +++++++----- test/units/buidler/standard.js | 19 +++++++++++++++++ 8 files changed, 82 insertions(+), 30 deletions(-) diff --git a/dist/buidler.plugin.js b/dist/buidler.plugin.js index 8c005daf..dfdd0dc1 100644 --- a/dist/buidler.plugin.js +++ b/dist/buidler.plugin.js @@ -46,14 +46,10 @@ function plugin() { // ============== // Server launch // ============== - const network = buidlerUtils.setupNetwork( - env, - api, - args, - ui - ); - - const address = await api.ganache(ganache); + const network = buidlerUtils.setupNetwork(env, api, ui); + + const client = api.client || ganache; + const address = await api.ganache(client); const web3 = new Web3(address); const accounts = await web3.eth.getAccounts(); const nodeInfo = await web3.eth.getNodeInfo(); @@ -68,9 +64,8 @@ function plugin() { pkg.version ]); - // Network Info ui.report('network', [ - api.defaultNetworkName, + env.network.name, api.port ]); diff --git a/dist/plugin-assets/buidler.utils.js b/dist/plugin-assets/buidler.utils.js index 05de70d3..f4044a1f 100644 --- a/dist/plugin-assets/buidler.utils.js +++ b/dist/plugin-assets/buidler.utils.js @@ -16,7 +16,7 @@ const { createProvider } = require("@nomiclabs/buidler/internal/core/providers/c * @param {BuidlerConfig} config * @return {BuidlerConfig} updated config */ -function normalizeConfig(config, args){ +function normalizeConfig(config, args={}){ config.workingDir = config.paths.root; config.contractsDir = config.paths.sources; config.testDir = config.paths.tests; @@ -27,11 +27,15 @@ function normalizeConfig(config, args){ return config; } -function setupNetwork(env, api, taskArgs, ui){ +function setupNetwork(env, api, ui){ let networkConfig = {}; - if (taskArgs.network){ - networkConfig = env.config.networks[taskArgs.network]; + let networkName = (env.buidlerArguments.network !== 'buidlerevm') + ? env.buidlerArguments.network + : api.defaultNetworkName; + + if (networkName !== api.defaultNetworkName){ + networkConfig = env.config.networks[networkName]; const configPort = networkConfig.url.split(':')[2]; @@ -48,13 +52,13 @@ function setupNetwork(env, api, taskArgs, ui){ networkConfig.gas = api.gasLimit; networkConfig.gasPrice = api.gasPrice; - const provider = createProvider(api.defaultNetworkName, networkConfig); + const provider = createProvider(networkName, networkConfig); - env.config.networks[api.defaultNetworkName] = networkConfig; - env.config.defaultNetwork = api.defaultNetworkName; + env.config.networks[networkName] = networkConfig; + env.config.defaultNetwork = networkName; env.network = { - name: api.defaultNetworkName, + name: networkName, config: networkConfig, provider: provider, } diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index 57445cd0..dce3c9d2 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -36,7 +36,8 @@ async function plugin(config){ truffleUtils.setNetwork(config, api); // Server launch - const address = await api.ganache(truffle.ganache); + const client = api.client || truffle.ganache; + const address = await api.ganache(client); const web3 = new Web3(address); const accounts = await web3.eth.getAccounts(); diff --git a/lib/api.js b/lib/api.js index 0d710e15..6084c723 100644 --- a/lib/api.js +++ b/lib/api.js @@ -39,10 +39,9 @@ class API { this.onIstanbulComplete = config.onIstanbulComplete || this.defaultHook; this.server = null; - this.provider = null; this.defaultPort = 8555; - this.defaultNetworkName = 'soliditycoverage'; this.client = config.client; + this.defaultNetworkName = 'soliditycoverage'; this.port = config.port || this.defaultPort; this.host = config.host || "127.0.0.1"; this.providerOptions = config.providerOptions || {}; @@ -224,9 +223,9 @@ class API { async attachToVM(client){ const self = this; - // Prefer client from options - if(!this.client) this.client = client; - this.server = this.client.server(this.providerOptions); + // Fallback to client from options + if(!client) client = this.client; + this.server = client.server(this.providerOptions); this.assertHasBlockchain(this.server.provider); await this.vmIsResolved(this.server.provider); diff --git a/scripts/run-buidler.sh b/scripts/run-buidler.sh index bc7dd3f4..104d0479 100755 --- a/scripts/run-buidler.sh +++ b/scripts/run-buidler.sh @@ -21,6 +21,12 @@ fi echo "PR_PATH >>>>> $PR_PATH" +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "Simple buidler/buidler-trufflev5 " +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" + # Install buidler e2e test git clone https://github.com/sc-forks/buidler-e2e.git cd buidler-e2e @@ -28,10 +34,34 @@ npm install # Install and run solidity-coverage @ PR npm install --save-dev $PR_PATH +cat package.json + +npx buidler coverage + +# Test that coverage/ was generated +if [ ! -d "coverage" ]; then + echo "ERROR: no coverage folder was created for buidler-trufflev5." + exit 1 +fi + +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "Simple buidler/buidler-ethers " +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" +cd .. +git clone https://github.com/sc-forks/example-buidler-ethers.git +cd example-buidler-ethers +npm install + +# Install and run solidity-coverage @ PR +npm install --save-dev $PR_PATH +cat package.json + npx buidler coverage # Test that coverage/ was generated if [ ! -d "coverage" ]; then - echo "ERROR: no coverage folder was created." + echo "ERROR: no coverage folder was created for buidler-ethers." exit 1 fi diff --git a/scripts/run-moloch.sh b/scripts/run-moloch.sh index 4c1191ee..e3fc9818 100755 --- a/scripts/run-moloch.sh +++ b/scripts/run-moloch.sh @@ -28,6 +28,7 @@ npm install npm uninstall --save-dev solidity-coverage # Install and run solidity-coverage @ PR +# Should run on network 'localhost' npm install --save-dev $PR_PATH npm run coverage diff --git a/test/units/buidler/flags.js b/test/units/buidler/flags.js index 8e451583..5cf7e317 100644 --- a/test/units/buidler/flags.js +++ b/test/units/buidler/flags.js @@ -53,16 +53,14 @@ describe('Buidler Plugin: command line options', function() { }); it('--network (declared port mismatches)', async function(){ - const taskArgs = { - network: 'development' // 8545 - } - solcoverConfig.port = 8222; mock.install('Simple', 'simple.js', solcoverConfig); mock.buidlerSetupEnv(this); - await this.env.run("coverage", taskArgs); + this.env.buidlerArguments.network = "development"; + + await this.env.run("coverage"); assert( mock.loggerOutput.val.includes("The 'port' values"), @@ -74,6 +72,11 @@ describe('Buidler Plugin: command line options', function() { `Should have used default coverage port 8545: ${mock.loggerOutput.val}` ); + assert( + mock.loggerOutput.val.includes("development"), + `Should have used specified network name: ${mock.loggerOutput.val}` + ); + const expected = [{ file: mock.pathToContract(buidlerConfig, 'Simple.sol'), pct: 100 diff --git a/test/units/buidler/standard.js b/test/units/buidler/standard.js index 527cca19..36a7abf4 100644 --- a/test/units/buidler/standard.js +++ b/test/units/buidler/standard.js @@ -51,6 +51,25 @@ describe('Buidler Plugin: standard use cases', function() { ); }); + it('default network ("buidlerevm")', async function(){ + mock.install('Simple', 'simple.js', solcoverConfig); + mock.buidlerSetupEnv(this); + + this.env.buidlerArguments.network = "buidlerevm" + + await this.env.run("coverage"); + + assert( + mock.loggerOutput.val.includes("8555"), + `Should have used default coverage port 8555: ${mock.loggerOutput.val}` + ); + + assert( + mock.loggerOutput.val.includes("soliditycoverage"), + `Should have used specified network name: ${mock.loggerOutput.val}` + ); + }); + it('with relative path solidity imports', async function() { mock.installFullProject('import-paths'); mock.buidlerSetupEnv(this); From 653fc51ab9301c7ae52fa4a159f2a409b9019eea Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 28 Nov 2019 15:17:17 -0800 Subject: [PATCH 12/21] Stop camel-casing testfiles flag (#443) --- README.md | 2 +- dist/buidler.plugin.js | 6 +++--- test/units/buidler/flags.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4ff578b0..2fceb17e 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ npx buidler coverage [command-options] | Option | Example | Description | |--------------|------------------------------------|--------------------------------| | file | `--file="test/registry/*.js"` | (Truffle) Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)| -| testFiles | `--testFiles test/file.js` | (Buidler) JS test file(s) to run.| +| testfiles | `--testfiles test/file.js` | (Buidler) JS test file(s) to run.| | solcoverjs | `--solcoverjs ./../.solcover.js` | Relative path from working directory to config. Useful for monorepo packages that share settings. (Path must be "./" prefixed) | | network | `--network development` | Use network settings defined in the Truffle or Buidler config | | temp[*][14] | `--temp build` | :warning: **Caution** :warning: Path to a *disposable* folder to store compilation artifacts in. Useful when your test setup scripts include hard-coded paths to a build directory. [More...][14] | diff --git a/dist/buidler.plugin.js b/dist/buidler.plugin.js index dfdd0dc1..3f33867b 100644 --- a/dist/buidler.plugin.js +++ b/dist/buidler.plugin.js @@ -26,7 +26,7 @@ function plugin() { task("coverage", "Generates a code coverage report for tests") - .addOptionalParam("testFiles", ui.flags.file, null, types.string) + .addOptionalParam("testfiles", ui.flags.file, null, types.string) .addOptionalParam("solcoverjs", ui.flags.solcoverjs, null, types.string) .addOptionalParam('temp', ui.flags.temp, null, types.string) @@ -112,10 +112,10 @@ function plugin() { // ====== // Tests // ====== - const testFiles = args.testFiles ? [args.testFiles] : []; + const testfiles = args.testfiles ? [args.testfiles] : []; try { - await env.run(TASK_TEST, {testFiles: testFiles}) + await env.run(TASK_TEST, {testFiles: testfiles}) } catch (e) { error = e; } diff --git a/test/units/buidler/flags.js b/test/units/buidler/flags.js index 5cf7e317..e5ee9946 100644 --- a/test/units/buidler/flags.js +++ b/test/units/buidler/flags.js @@ -85,9 +85,9 @@ describe('Buidler Plugin: command line options', function() { verify.lineCoverage(expected); }); - it('--testFiles test/', async function() { + it.only('--testfiles test/', async function() { const taskArgs = { - testFiles: path.join( + testfiles: path.join( buidlerConfig.paths.root, 'test/specific_a.js' ) From f87c274c2f03418b3e5fe55fcfad4354930cd59d Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 28 Nov 2019 15:37:12 -0800 Subject: [PATCH 13/21] Rename the dist folder 'plugins' (#444) --- index.js | 2 -- package.json | 4 ++-- {dist => plugins}/bin.js | 0 {dist => plugins}/buidler.plugin.js | 6 +++--- {dist/plugin-assets => plugins/resources}/buidler.ui.js | 0 {dist/plugin-assets => plugins/resources}/buidler.utils.js | 0 {dist/plugin-assets => plugins/resources}/plugin.utils.js | 0 .../plugin-assets => plugins/resources}/truffle.library.js | 0 .../resources}/truffle.library.js.map | 0 {dist/plugin-assets => plugins/resources}/truffle.ui.js | 0 {dist/plugin-assets => plugins/resources}/truffle.utils.js | 0 {dist => plugins}/truffle.plugin.js | 6 +++--- test/integration/projects/bad-solcoverjs/buidler.config.js | 2 +- .../projects/ganache-solcoverjs/buidler.config.js | 2 +- test/integration/projects/import-paths/buidler.config.js | 2 +- test/integration/projects/libraries/buidler.config.js | 2 +- test/integration/projects/multiple-suites/buidler.config.js | 2 +- test/integration/projects/no-sources/buidler.config.js | 2 +- test/integration/projects/skipping/buidler.config.js | 2 +- test/integration/projects/test-files/buidler.config.js | 2 +- test/units/buidler/errors.js | 2 +- test/units/buidler/flags.js | 4 ++-- test/units/buidler/standard.js | 2 +- test/units/truffle/errors.js | 4 ++-- test/units/truffle/flags.js | 2 +- test/units/truffle/standard.js | 2 +- test/util/integration.js | 2 +- 27 files changed, 25 insertions(+), 27 deletions(-) delete mode 100644 index.js rename {dist => plugins}/bin.js (100%) rename {dist => plugins}/buidler.plugin.js (95%) rename {dist/plugin-assets => plugins/resources}/buidler.ui.js (100%) rename {dist/plugin-assets => plugins/resources}/buidler.utils.js (100%) rename {dist/plugin-assets => plugins/resources}/plugin.utils.js (100%) rename {dist/plugin-assets => plugins/resources}/truffle.library.js (100%) rename {dist/plugin-assets => plugins/resources}/truffle.library.js.map (100%) rename {dist/plugin-assets => plugins/resources}/truffle.ui.js (100%) rename {dist/plugin-assets => plugins/resources}/truffle.utils.js (100%) rename {dist => plugins}/truffle.plugin.js (94%) diff --git a/index.js b/index.js deleted file mode 100644 index 36fdc6fc..00000000 --- a/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// stub: this is package.json's "main" -// truffle require.resolve's this in order to check plugin is installed \ No newline at end of file diff --git a/package.json b/package.json index 065270f6..ed1ff650 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "solidity-coverage", "version": "0.7.0-beta.2", "description": "", - "main": "dist/buidler.plugin.js", + "main": "plugins/buidler.plugin.js", "bin": { - "solidity-coverage": "./dist/bin.js" + "solidity-coverage": "./plugins/bin.js" }, "directories": { "test": "test" diff --git a/dist/bin.js b/plugins/bin.js similarity index 100% rename from dist/bin.js rename to plugins/bin.js diff --git a/dist/buidler.plugin.js b/plugins/buidler.plugin.js similarity index 95% rename from dist/buidler.plugin.js rename to plugins/buidler.plugin.js index 3f33867b..46071621 100644 --- a/dist/buidler.plugin.js +++ b/plugins/buidler.plugin.js @@ -1,7 +1,7 @@ const API = require('./../lib/api'); -const utils = require('./plugin-assets/plugin.utils'); -const buidlerUtils = require('./plugin-assets/buidler.utils'); -const PluginUI = require('./plugin-assets/buidler.ui'); +const utils = require('./resources/plugin.utils'); +const buidlerUtils = require('./resources/buidler.utils'); +const PluginUI = require('./resources/buidler.ui'); const pkg = require('./../package.json'); const death = require('death'); diff --git a/dist/plugin-assets/buidler.ui.js b/plugins/resources/buidler.ui.js similarity index 100% rename from dist/plugin-assets/buidler.ui.js rename to plugins/resources/buidler.ui.js diff --git a/dist/plugin-assets/buidler.utils.js b/plugins/resources/buidler.utils.js similarity index 100% rename from dist/plugin-assets/buidler.utils.js rename to plugins/resources/buidler.utils.js diff --git a/dist/plugin-assets/plugin.utils.js b/plugins/resources/plugin.utils.js similarity index 100% rename from dist/plugin-assets/plugin.utils.js rename to plugins/resources/plugin.utils.js diff --git a/dist/plugin-assets/truffle.library.js b/plugins/resources/truffle.library.js similarity index 100% rename from dist/plugin-assets/truffle.library.js rename to plugins/resources/truffle.library.js diff --git a/dist/plugin-assets/truffle.library.js.map b/plugins/resources/truffle.library.js.map similarity index 100% rename from dist/plugin-assets/truffle.library.js.map rename to plugins/resources/truffle.library.js.map diff --git a/dist/plugin-assets/truffle.ui.js b/plugins/resources/truffle.ui.js similarity index 100% rename from dist/plugin-assets/truffle.ui.js rename to plugins/resources/truffle.ui.js diff --git a/dist/plugin-assets/truffle.utils.js b/plugins/resources/truffle.utils.js similarity index 100% rename from dist/plugin-assets/truffle.utils.js rename to plugins/resources/truffle.utils.js diff --git a/dist/truffle.plugin.js b/plugins/truffle.plugin.js similarity index 94% rename from dist/truffle.plugin.js rename to plugins/truffle.plugin.js index dce3c9d2..06bbadeb 100644 --- a/dist/truffle.plugin.js +++ b/plugins/truffle.plugin.js @@ -1,7 +1,7 @@ const API = require('./../lib/api'); -const utils = require('./plugin-assets/plugin.utils'); -const truffleUtils = require('./plugin-assets/truffle.utils'); -const PluginUI = require('./plugin-assets/truffle.ui'); +const utils = require('./resources/plugin.utils'); +const truffleUtils = require('./resources/truffle.utils'); +const PluginUI = require('./resources/truffle.ui'); const pkg = require('./../package.json'); const death = require('death'); diff --git a/test/integration/projects/bad-solcoverjs/buidler.config.js b/test/integration/projects/bad-solcoverjs/buidler.config.js index 084a9f23..d1f48df0 100644 --- a/test/integration/projects/bad-solcoverjs/buidler.config.js +++ b/test/integration/projects/bad-solcoverjs/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/ganache-solcoverjs/buidler.config.js b/test/integration/projects/ganache-solcoverjs/buidler.config.js index 084a9f23..d1f48df0 100644 --- a/test/integration/projects/ganache-solcoverjs/buidler.config.js +++ b/test/integration/projects/ganache-solcoverjs/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/import-paths/buidler.config.js b/test/integration/projects/import-paths/buidler.config.js index f170d4cc..347da202 100644 --- a/test/integration/projects/import-paths/buidler.config.js +++ b/test/integration/projects/import-paths/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/libraries/buidler.config.js b/test/integration/projects/libraries/buidler.config.js index 46ea0f59..ba0d0937 100644 --- a/test/integration/projects/libraries/buidler.config.js +++ b/test/integration/projects/libraries/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/multiple-suites/buidler.config.js b/test/integration/projects/multiple-suites/buidler.config.js index 084a9f23..d1f48df0 100644 --- a/test/integration/projects/multiple-suites/buidler.config.js +++ b/test/integration/projects/multiple-suites/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/no-sources/buidler.config.js b/test/integration/projects/no-sources/buidler.config.js index 46ea0f59..ba0d0937 100644 --- a/test/integration/projects/no-sources/buidler.config.js +++ b/test/integration/projects/no-sources/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/skipping/buidler.config.js b/test/integration/projects/skipping/buidler.config.js index 084a9f23..d1f48df0 100644 --- a/test/integration/projects/skipping/buidler.config.js +++ b/test/integration/projects/skipping/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/integration/projects/test-files/buidler.config.js b/test/integration/projects/test-files/buidler.config.js index 817a3eb3..a0b6dbc8 100644 --- a/test/integration/projects/test-files/buidler.config.js +++ b/test/integration/projects/test-files/buidler.config.js @@ -1,5 +1,5 @@ const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); -loadPluginFile(__dirname + "/../dist/buidler.plugin"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); module.exports={ diff --git a/test/units/buidler/errors.js b/test/units/buidler/errors.js index 9ab3e485..d425c257 100644 --- a/test/units/buidler/errors.js +++ b/test/units/buidler/errors.js @@ -7,7 +7,7 @@ const ganache = require('ganache-cli') const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/buidler.plugin'); +const plugin = require('../../../plugins/buidler.plugin'); // ======= // Errors diff --git a/test/units/buidler/flags.js b/test/units/buidler/flags.js index e5ee9946..e2471935 100644 --- a/test/units/buidler/flags.js +++ b/test/units/buidler/flags.js @@ -5,7 +5,7 @@ const shell = require('shelljs'); const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/buidler.plugin'); +const plugin = require('../../../plugins/buidler.plugin'); // ======================= // CLI Options / Flags @@ -85,7 +85,7 @@ describe('Buidler Plugin: command line options', function() { verify.lineCoverage(expected); }); - it.only('--testfiles test/', async function() { + it('--testfiles test/', async function() { const taskArgs = { testfiles: path.join( buidlerConfig.paths.root, diff --git a/test/units/buidler/standard.js b/test/units/buidler/standard.js index 36a7abf4..fcba2bf8 100644 --- a/test/units/buidler/standard.js +++ b/test/units/buidler/standard.js @@ -5,7 +5,7 @@ const shell = require('shelljs'); const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/buidler.plugin'); +const plugin = require('../../../plugins/buidler.plugin'); // ======================= // Standard Use-case Tests diff --git a/test/units/truffle/errors.js b/test/units/truffle/errors.js index 0521ec34..2a5dc17a 100644 --- a/test/units/truffle/errors.js +++ b/test/units/truffle/errors.js @@ -7,7 +7,7 @@ const ganache = require('ganache-core-sc'); const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/truffle.plugin'); +const plugin = require('../../../plugins/truffle.plugin'); // ======= // Errors @@ -208,7 +208,7 @@ describe('Truffle Plugin: error cases', function() { }) it('user runs "solidity-coverage" as shell command', function(){ - const pathToCommand = './dist/bin.js'; + const pathToCommand = './plugins/bin.js'; const pkg = require('../../../package.json'); assert( diff --git a/test/units/truffle/flags.js b/test/units/truffle/flags.js index f3c63cc0..bbd62eb6 100644 --- a/test/units/truffle/flags.js +++ b/test/units/truffle/flags.js @@ -5,7 +5,7 @@ const shell = require('shelljs'); const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/truffle.plugin'); +const plugin = require('../../../plugins/truffle.plugin'); // ======================= // CLI Options / Flags diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 5d0824bf..1c281fe6 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -5,7 +5,7 @@ const shell = require('shelljs'); const verify = require('../../util/verifiers') const mock = require('../../util/integration'); -const plugin = require('../../../dist/truffle.plugin'); +const plugin = require('../../../plugins/truffle.plugin'); // ======================= // Standard Use-case Tests diff --git a/test/util/integration.js b/test/util/integration.js index dbc6d420..60d2ddc5 100644 --- a/test/util/integration.js +++ b/test/util/integration.js @@ -159,7 +159,7 @@ function getDefaultBuidlerConfig() { function getBuidlerConfigJS(config){ const prefix =` const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); - loadPluginFile(__dirname + "/../dist/buidler.plugin"); + loadPluginFile(__dirname + "/../plugins/buidler.plugin"); usePlugin("@nomiclabs/buidler-truffle5"); ` From 3612a815e6d299cb9b4a55cca627052e51e289f3 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 28 Nov 2019 16:28:41 -0800 Subject: [PATCH 14/21] Make api require-able, expose plugin utils (#445) --- api.js | 4 ++++ lib/api.js | 10 +++++++--- plugins/resources/plugin.utils.js | 1 - test/units/api.js | 14 +++++++++++++- 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 api.js diff --git a/api.js b/api.js new file mode 100644 index 00000000..09f653f2 --- /dev/null +++ b/api.js @@ -0,0 +1,4 @@ +// For require('solidity-coverage/api'); +const api = require('./lib/api'); + +module.exports = api; diff --git a/lib/api.js b/lib/api.js index 6084c723..480d33f4 100644 --- a/lib/api.js +++ b/lib/api.js @@ -3,7 +3,6 @@ const pify = require('pify'); const fs = require('fs'); const path = require('path'); const istanbul = require('istanbul'); -const util = require('util'); const assert = require('assert'); const detect = require('detect-port'); const _ = require('lodash/lang'); @@ -13,6 +12,8 @@ const Instrumenter = require('./instrumenter'); const Coverage = require('./coverage'); const DataCollector = require('./collector'); const AppUI = require('./ui').AppUI; +const utils = require('./../plugins/resources/plugin.utils'); + /** * Coverage Runner @@ -60,6 +61,7 @@ class API { this.setLoggingLevel(config.silent); this.ui = new AppUI(this.log); + this.utils = utils; } /** @@ -175,9 +177,11 @@ class API { /** * Generate coverage / write coverage report / run istanbul */ - async report() { + async report(_folder) { + const folder = _folder || this.istanbulFolder; + const collector = new istanbul.Collector(); - const reporter = new istanbul.Reporter(false, this.istanbulFolder); + const reporter = new istanbul.Reporter(false, folder); return new Promise((resolve, reject) => { try { diff --git a/plugins/resources/plugin.utils.js b/plugins/resources/plugin.utils.js index 002a51f2..20c3034a 100644 --- a/plugins/resources/plugin.utils.js +++ b/plugins/resources/plugin.utils.js @@ -267,7 +267,6 @@ module.exports = { loadSolcoverJS: loadSolcoverJS, reportSkipped: reportSkipped, save: save, - checkContext: checkContext, toRelativePath: toRelativePath, setupTempFolders: setupTempFolders } diff --git a/test/units/api.js b/test/units/api.js index 88ba3df1..39f9e314 100644 --- a/test/units/api.js +++ b/test/units/api.js @@ -1,6 +1,6 @@ const assert = require('assert'); const util = require('./../util/util.js'); -const API = require('./../../lib/api.js'); +const API = require('./../../api.js'); const detect = require('detect-port'); const Ganache = require('ganache-cli'); @@ -85,4 +85,16 @@ describe('api', () => { assert(freePort === port); }) + + it('api.utils', async function(){ + const api = new API(opts); + assert(api.utils.assembleFiles !== undefined) + assert(api.utils.checkContext !== undefined) + assert(api.utils.finish !== undefined) + assert(api.utils.getTempLocations !== undefined) + assert(api.utils.setupTempFolders !== undefined) + assert(api.utils.loadSource !== undefined) + assert(api.utils.loadSolcoverJS !== undefined) + assert(api.utils.save !== undefined) + }); }) From f2cdb634982e15b252c09ee4d0b86ba896698d84 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 29 Nov 2019 13:45:47 -0800 Subject: [PATCH 15/21] Add API documentation (#447) --- README.md | 11 + docs/api.md | 368 ++++++++++++++++++++++++++++++ lib/api.js | 5 +- plugins/resources/plugin.utils.js | 11 +- test/units/api.js | 25 +- utils.js | 4 + 6 files changed, 403 insertions(+), 21 deletions(-) create mode 100644 docs/api.md create mode 100644 utils.js diff --git a/README.md b/README.md index 2fceb17e..d502fb36 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,16 @@ module.exports = { [* Advanced use][14] +## API + +Solidity-coverage's core methods and many utilities are available as an API. + +```javascript +const CoverageAPI = require('solidity-coverage/api'); +``` + +[Documentation available here][28]. + ## FAQ Common problems & questions: @@ -171,3 +181,4 @@ $ yarn [25]: https://github.com/sc-forks/solidity-coverage/issues/417 [26]: https://buidler.dev/ [27]: https://www.trufflesuite.com/docs +[28]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/api.md diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..8c8d7c63 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,368 @@ +# Solidity-Coverage API Documentation + +`solidity-coverage`'s API provides test coverage measurement for the Solidity language. +The repository contains two complete coverage tool/plugin implementations (for Buidler and Truffle) +which can be used as sources if you're building something similar. + +`solidity-coverage`'s core algorithm resembles the one used by [Istanbul][3] for javascript programs. +It tracks line and branch locations by 'instrumenting' solidity contracts with special solidity +statements and detecting their execution in a coverage-enabled EVM. As such, its API spans the +full set of tasks typically required to run a solidity test suite. + ++ compile ++ ethereum client launch ++ test ++ report outcome and exit + +[3]: https://github.com/gotwarlost/istanbul + +The API's corresponding methods are: + ++ `instrument`: Rewrites contracts for instrumented compilation. Generates an instrumentation data map. ++ `ganache`: Launches a ganache client with coverage collection enabled in its VM. As the client + runs it will mark line/branch hits on the instrumentation data map. ++ `report`: Generates a coverage report from the data collected by the VM after tests complete. Converts + the instrumentation data map into an object IstanbulJS can process. ++ `finish`: Shuts client down + +The library also includes some file system [utilities](#Utils) which are helpful for managing the +disposable set of contracts/artifacts which coverage must use in lieu of the 'real' contracts/artifacts. + +# Table of Contents + +- [API Methods](#api) + * [constructor](#constructor) + * [instrument](#instrument) + * [ganache](#ganache) + * [report](#report) + * [finish](#finish) + * [getInstrumentationData](#getinstrumentationdata) + * [setInstrumentationData](#setinstrumentationdata) +- [Utils Methods](#utils) + * [loadSolcoverJS](#loadsolcoverjs) + * [assembleFiles](#assemblefiles) + * [getTempLocations](#gettemplocations) + * [setupTempFolders](#setuptempfolders) + * [save](#save) + * [finish](#finish-1) + +# API + +**Example** +```javascript +const CoverageAPI = require("solidity-coverage/api"); +const api = new CoverageAPI(options); +``` + +## constructor + +Creates a coverage API instance. Configurable. + +**Parameters** + +- `options` **Object** : API options + +| Option | Type | Default | Description | +| ------ | ---- | ------- | ----------- | +| port | *Number* | 8555 | Port to launch client on | +| silent | *Boolean* | false | Suppress logging output | +| client | *Object* | `require("ganache-core")` | JS Ethereum client | +| providerOptions | *Object* | `{ }` | [ganache-core options][1] | +| skipFiles | *Array* | `[]` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. | +| istanbulFolder | *String* | `./coverage` | Folder location for Istanbul coverage reports. | +| istanbulReporter | *Array* | `['html', 'lcov', 'text', 'json']` | [Istanbul coverage reporters][2] | + +[1]: https://github.com/trufflesuite/ganache-core#options +[2]: https://istanbul.js.org/docs/advanced/alternative-reporters/ + +-------------- + +## instrument + +Instruments a set of sources to prepare them for compilation. + +:warning: **Important:** Instrumented sources must be compiled with **solc optimization OFF** :warning: + +**Parameters** + +- `contracts` **Object[]**: Array of solidity sources and their paths + +Returns **Object[]** in the same format as the `contracts` param, but with sources instrumented. + +**Example** +```javascript +const contracts = [{ + source: "contract Simple { uint x = 5; }", + canonicalPath: "/Users/user/project/contracts/Simple.sol", + relativePath: "Simple.sol" // Optional, used for pretty printing. +},...] + +const instrumented = api.instrument(contracts) +``` + +-------------- + +## ganache + +Enables coverage data collection on an in-process ganache server. By default, will return +a url after server has begun listening on the port specified in the [config](#constructor) +(or 8555 by default). When `autoLaunchServer` is false, method returns`ganache.server` +so the consumer can control the 'server.listen' invocation themselves. + +**Parameters** + +- `client` **Object**: (*Optional*) ganache module +- `autoLaunchServer` **Boolean**: (*Optional*) + +Returns **Promise** Address of server to connect to, or initialized, unlaunched server + +**Example** +```javascript +const client = require('ganache-cli'); + +const api = new CoverageAPI( { client: client } ); +const address = await api.ganache(); + +> http://127.0.0.1:8555 + +// Alternatively... + +const server = await api.ganache(client, false); +await pify(server.listen()(8545)); +``` + +-------------- + +## report + +Generates coverage report using IstanbulJS + +**Parameters** + +- `istanbulFolder` **String**: (*Optional*) path to folder IstanbulJS will deposit coverage reports in. + +Returns **Promise** + +**Example** +```javascript +await api.report('./coverage_4A3cd2b'); // Default folder name is 'coverage' +``` + +------------- + +## finish + +Shuts down coverage-enabled ganache server instance + +Returns **Promise** + +**Example** +```javascript +const client = require('ganache-cli'); + +await api.ganache(client); // Server listening... +await api.finish(); // Server shut down. +``` + +------------- + +## getInstrumentationData + +Returns a copy of the hit map created during instrumentation. Useful if you'd like to delegate +coverage collection to multiple processes. + +Returns **Object** instrumentation data; + + +**Example** +```javascript +const contracts = api.instrument(contracts); +const data = api.getInstrumentationData(); +save(data); +``` + +------------- + +## setInstrumentationData + +Sets the hit map object generated during instrumentation. Useful if you'd like +to collect or convert data to coverage for an instrumentation which was generated +in a different process. + +**Example** +```javascript +const data = load(data); +api.setIntrumentationData(data); + +// Client will collect data for the loaded map +const address = await api.ganache(client); + +// Or to `report` instrumentation data which was collected in a different process. +const data = load(data); +api.setInstrumentationData(data); + +api.report(); +``` + +---------------------------------------------------------------------------------------------------- + +# Utils + +```javascript +const utils = require('solidity-coverage/utils'); +``` + +Many of the utils methods take a `config` object param which +defines the absolute paths to your project root and contracts directory. + +**Example** +```javascript +const config = { + workingDir: process.cwd(), + contractsDir: path.join(process.cwd(), 'contracts'), +} +``` +------------- + +## loadSolcoverJS + +Loads `.solcoverjs`. Users may specify options described in the README in `.solcover.js` config +file which your application needs to consume. + +**Parameters** + +- `config` **Object**: [See *config* above](#Utils) + +Returns **Object** Normalized coverage config + + +**Example** +```javascript +const solcoverJS = utils.loadSolcoverJS(config); +const api = new CoverageAPI(solcoverJS); +``` + +------------- + +## assembleFiles + +Loads contracts from the filesystem in a format that can be passed directly to the +[api.instrument](#instrument) method. Filters by an optional `skipFiles` parameter. + +**Parameters** + +- `config` **Object**: [See *config* above](#Utils) +- `skipFiles` **String[]**: (*Optional*) Array of files or folders to skip + [See API *constructor*](#constructor) + +Returns **Object** with `targets` and `skipped` keys. These are Object arrays of contract sources +and paths. + +**Example** +```javascript +const { + targets, + skipped +} = utils.assembleFiles(config, ['Migrations.sol']) + +const instrumented = api.instrument(targets); +``` + +-------------- + +## getTempLocations + +Returns a pair of canonically named temporary directory paths for contracts +and artifacts. Instrumented assets can be compiled from and written to these so the unit tests can +use them as sources. + +**Parameters** + +- `config` **Object**: [See *config* above](#Utils) + +Returns **Object** with two absolute paths to disposable folders, `tempContractsDir`, `tempArtifactsDir`. +These directories are named `.coverage_contracts` and `.coverage_artifacts`. + +**Example** +```javascript +const { + tempContractsDir, + tempArtifactsDir +} = utils.getTempLocations(config) + +utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir) + +// Later, you can call `utils.finish` to delete these... +utils.finish(config, api) +``` + +---------- + +## setupTempFolders + +Creates temporary directories to store instrumented contracts and their compilation artifacts in. + +**Parameters** + +- `config` **Object**: [See *config* above](#Utils) +- `tempContractsDir` **String**: absolute path to temporary contracts directory +- `tempArtifactsDir` **String**: absolute path to temporary artifacts directory + +**Example** +```javascript +const { + tempContractsDir, + tempArtifactsDir +} = utils.getTempLocations(config) + +utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir); +``` +------------- + +## save + +Writes an array of instrumented sources in the object format returned by +[api.instrument](#instrument) to a temporary directory. + +**Parameters** + +- `contracts` **Object[]**: array of contracts & paths generated by [api.instrument](#instrument) +- `originalDir` **String**: absolute path to original contracts directory +- `tempDir` **String**: absolute path to temp contracts directory (the destination of the save) + +**Example** +```javascript +const { + tempContractsDir, + tempArtifactsDir +} = utils.getTempLocations(config) + +utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir); + +const instrumented = api.instrument(targets); + +utils.save(instrumented, config.contractsDir, tempContractsDir); +``` + +------------- + +## finish + +Deletes temporary folders and shuts the ganache server down. Is tolerant - if folders or ganache +server don't exist it will return silently. + +**Parameters** + +- `config` **Object**: [See *config* above](#Utils) +- `api` **Object**: (*Optional*) coverage api instance whose own `finish` method will be called + +Returns **Promise** + +**Example** +```javascript +await utils.finish(); +``` + + + + diff --git a/lib/api.js b/lib/api.js index 480d33f4..3b5d1cf9 100644 --- a/lib/api.js +++ b/lib/api.js @@ -12,8 +12,6 @@ const Instrumenter = require('./instrumenter'); const Coverage = require('./coverage'); const DataCollector = require('./collector'); const AppUI = require('./ui').AppUI; -const utils = require('./../plugins/resources/plugin.utils'); - /** * Coverage Runner @@ -61,7 +59,6 @@ class API { this.setLoggingLevel(config.silent); this.ui = new AppUI(this.log); - this.utils = utils; } /** @@ -138,7 +135,7 @@ class API { * the consumer can control the 'server.listen' invocation themselves. * @param {Object} client ganache client * @param {Boolean} autoLaunchServer boolean - * @return {String | Server} address of server to connect to, or initialized, unlaunched server. + * @return { (String | Server) } address of server to connect to, or initialized, unlaunched server. */ async ganache(client, autoLaunchServer){ // Check for port-in-use diff --git a/plugins/resources/plugin.utils.js b/plugins/resources/plugin.utils.js index 20c3034a..72fa5a31 100644 --- a/plugins/resources/plugin.utils.js +++ b/plugins/resources/plugin.utils.js @@ -61,8 +61,8 @@ function setupTempFolders(config, tempContractsDir, tempArtifactsDir){ /** * Save a set of instrumented files to a temporary directory. * @param {Object[]} targets array of targets generated by `assembleTargets` - * @param {[type]} originalDir absolute path to parent directory of original source - * @param {[type]} tempDir absolute path to temp parent directory + * @param {[type]} originalDir absolute path to original contracts directory + * @param {[type]} tempDir absolute path to temp contracts directory */ function save(targets, originalDir, tempDir){ let _path; @@ -189,10 +189,11 @@ function assembleSkipped(config, targets, skipFiles=[]){ return skipFiles; } -function loadSolcoverJS(config){ +function loadSolcoverJS(config={}){ let solcoverjs; let coverageConfig; - let ui = new PluginUI(config.logger.log); + let log = config.logger ? config.logger.log : console.log; + let ui = new PluginUI(log); // Handle --solcoverjs flag (config.solcoverjs) @@ -215,7 +216,7 @@ function loadSolcoverJS(config){ } // Truffle writes to coverage config - coverageConfig.log = config.logger.log; + coverageConfig.log = log; coverageConfig.cwd = config.workingDir; coverageConfig.originalContractsDir = config.contractsDir; diff --git a/test/units/api.js b/test/units/api.js index 39f9e314..4290e7a0 100644 --- a/test/units/api.js +++ b/test/units/api.js @@ -1,9 +1,11 @@ const assert = require('assert'); -const util = require('./../util/util.js'); -const API = require('./../../api.js'); const detect = require('detect-port'); const Ganache = require('ganache-cli'); +const util = require('./../util/util.js'); +const API = require('./../../api.js'); +const utils = require('./../../utils.js'); + describe('api', () => { let opts; @@ -86,15 +88,14 @@ describe('api', () => { assert(freePort === port); }) - it('api.utils', async function(){ - const api = new API(opts); - assert(api.utils.assembleFiles !== undefined) - assert(api.utils.checkContext !== undefined) - assert(api.utils.finish !== undefined) - assert(api.utils.getTempLocations !== undefined) - assert(api.utils.setupTempFolders !== undefined) - assert(api.utils.loadSource !== undefined) - assert(api.utils.loadSolcoverJS !== undefined) - assert(api.utils.save !== undefined) + it('utils', async function(){ + assert(utils.assembleFiles !== undefined) + assert(utils.checkContext !== undefined) + assert(utils.finish !== undefined) + assert(utils.getTempLocations !== undefined) + assert(utils.setupTempFolders !== undefined) + assert(utils.loadSource !== undefined) + assert(utils.loadSolcoverJS !== undefined) + assert(utils.save !== undefined) }); }) diff --git a/utils.js b/utils.js new file mode 100644 index 00000000..6520168e --- /dev/null +++ b/utils.js @@ -0,0 +1,4 @@ +// For require('solidity-coverage/utils'); +const utils = require('./plugins/resources/plugin.utils'); + +module.exports = utils; From d9af5ac57106aad4bca5cb04818941186bdf422e Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 29 Nov 2019 16:34:01 -0800 Subject: [PATCH 16/21] Gracefully overwrite eth-gas-reporter (#448) --- plugins/resources/truffle.utils.js | 6 ++++++ test/units/truffle/standard.js | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/plugins/resources/truffle.utils.js b/plugins/resources/truffle.utils.js index 3f430bdd..80ac81ae 100644 --- a/plugins/resources/truffle.utils.js +++ b/plugins/resources/truffle.utils.js @@ -194,6 +194,12 @@ function normalizeConfig(config){ config.testDir = config.test_directory; config.artifactsDir = config.build_directory; + // eth-gas-reporter freezes the in-process client because it uses sync calls + if (typeof config.mocha === "object" && config.mocha.reporter === 'eth-gas-reporter'){ + config.mocha.reporter = 'spec'; + delete config.mocha.reporterOptions; + } + return config; } diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 1c281fe6..dd54b3a8 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -215,6 +215,14 @@ describe('Truffle Plugin: standard use cases', function() { ); }); + // This test errors if the reporter is not re-designated as 'spec' correctly + it('gracefully disables eth-gas-reporter', async function(){ + truffleConfig.mocha = { reporter: 'eth-gas-reporter' }; + + mock.install('Simple', 'simple.js', solcoverConfig); + await plugin(truffleConfig); + }); + // This test tightly coupled to the ganache version in production deps // "test-files" project solcoverjs includes `client: require('ganache-cli')` it('config: client', async function(){ From e25728ac88492755155eb1bc134d2917d491b065 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 29 Nov 2019 17:30:01 -0800 Subject: [PATCH 17/21] Allow Truffle V4 style solc config (#449) --- plugins/resources/truffle.utils.js | 6 ++++++ test/units/truffle/standard.js | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/plugins/resources/truffle.utils.js b/plugins/resources/truffle.utils.js index 80ac81ae..9c00b594 100644 --- a/plugins/resources/truffle.utils.js +++ b/plugins/resources/truffle.utils.js @@ -200,6 +200,12 @@ function normalizeConfig(config){ delete config.mocha.reporterOptions; } + // Truffle V4 style solc settings are honored over V5 settings. Apparently it's common + // for both to be present in the same config (as an error). + if (typeof config.solc === "object" ){ + config.solc.optimizer = { enabled: false }; + } + return config; } diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index dd54b3a8..436a457e 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -216,13 +216,36 @@ describe('Truffle Plugin: standard use cases', function() { }); // This test errors if the reporter is not re-designated as 'spec' correctly - it('gracefully disables eth-gas-reporter', async function(){ + it('disables eth-gas-reporter', async function(){ truffleConfig.mocha = { reporter: 'eth-gas-reporter' }; mock.install('Simple', 'simple.js', solcoverConfig); await plugin(truffleConfig); }); + it('disables optimization when truffle-config uses V4 format', async function(){ + solcoverConfig = { + silent: process.env.SILENT ? true : false, + istanbulReporter: ['json-summary', 'text'] + }; + + truffleConfig.solc = { + optimizer: { enabled: true, runs: 200 } + }; + + mock.install('Simple', 'simple.js', solcoverConfig); + await plugin(truffleConfig); + + const expected = [ + { + file: mock.pathToContract(truffleConfig, 'Simple.sol'), + pct: 100 + } + ]; + + verify.lineCoverage(expected); + }); + // This test tightly coupled to the ganache version in production deps // "test-files" project solcoverjs includes `client: require('ganache-cli')` it('config: client', async function(){ From 40c7ce38a1d96003d5dce01a0b3d1a40d1207cc3 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 29 Nov 2019 20:20:12 -0800 Subject: [PATCH 18/21] Add imports only test, fix instrumenter (#450) --- lib/instrumenter.js | 6 +++++- .../import-paths/contracts/OnlyUsesImports.sol | 5 +++++ .../node_modules/package/AnotherImport.sol | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/integration/projects/import-paths/contracts/OnlyUsesImports.sol create mode 100644 test/integration/projects/import-paths/node_modules/package/AnotherImport.sol diff --git a/lib/instrumenter.js b/lib/instrumenter.js index 42b6a6ee..4c91e775 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -70,7 +70,11 @@ class Instrumenter { // Walk the AST, recording injection points ast = SolidityParser.parse(contract.instrumented, {range: true}); - contract.contractName = ast.children.filter(node => this._isRootNode(node))[0].name; + + const root = ast.children.filter(node => this._isRootNode(node)); + + // Handle contracts which only contain import statements + contract.contractName = (root.length) ? root[0].name : null; parse[ast.type](contract, ast); // We have to iterate through these points in descending order diff --git a/test/integration/projects/import-paths/contracts/OnlyUsesImports.sol b/test/integration/projects/import-paths/contracts/OnlyUsesImports.sol new file mode 100644 index 00000000..ceb4c417 --- /dev/null +++ b/test/integration/projects/import-paths/contracts/OnlyUsesImports.sol @@ -0,0 +1,5 @@ +pragma solidity >=0.4.21 <0.6.0; + +import "package/AnotherImport.sol"; + +interface Void {} diff --git a/test/integration/projects/import-paths/node_modules/package/AnotherImport.sol b/test/integration/projects/import-paths/node_modules/package/AnotherImport.sol new file mode 100644 index 00000000..caba5cda --- /dev/null +++ b/test/integration/projects/import-paths/node_modules/package/AnotherImport.sol @@ -0,0 +1,10 @@ +pragma solidity >=0.4.21 <0.6.0; + +contract AnotherImport { + uint x; + constructor() public {} + + function isNodeModulesMethod() public { + x = 5; + } +} \ No newline at end of file From f7603acbc0ea6e8d7c128a22b6d36e05cefc9287 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 29 Nov 2019 21:49:37 -0800 Subject: [PATCH 19/21] Use recursive-readdir to resolve test files (#451) --- package.json | 2 +- plugins/resources/truffle.utils.js | 7 +++--- plugins/truffle.plugin.js | 2 +- .../projects/tests-folder/.solcover.js | 4 ++++ .../projects/tests-folder/buidler.config.js | 8 +++++++ .../tests-folder/contracts/ContractA.sol | 17 ++++++++++++++ .../tests-folder/contracts/ContractB.sol | 17 ++++++++++++++ .../tests-folder/contracts/ContractC.sol | 17 ++++++++++++++ .../tests-folder/contracts/Migrations.sol | 23 +++++++++++++++++++ .../projects/tests-folder/test/contracta.js | 15 ++++++++++++ .../tests-folder/test/folder/contractb.js | 15 ++++++++++++ .../tests-folder/test/folder/contractc.js | 20 ++++++++++++++++ .../projects/tests-folder/truffle-config.js | 7 ++++++ test/units/truffle/standard.js | 23 +++++++++++++++++++ yarn.lock | 16 ++++++------- 15 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 test/integration/projects/tests-folder/.solcover.js create mode 100644 test/integration/projects/tests-folder/buidler.config.js create mode 100644 test/integration/projects/tests-folder/contracts/ContractA.sol create mode 100644 test/integration/projects/tests-folder/contracts/ContractB.sol create mode 100644 test/integration/projects/tests-folder/contracts/ContractC.sol create mode 100644 test/integration/projects/tests-folder/contracts/Migrations.sol create mode 100644 test/integration/projects/tests-folder/test/contracta.js create mode 100644 test/integration/projects/tests-folder/test/folder/contractb.js create mode 100644 test/integration/projects/tests-folder/test/folder/contractc.js create mode 100644 test/integration/projects/tests-folder/truffle-config.js diff --git a/package.json b/package.json index ed1ff650..0f126a7c 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,9 @@ "istanbul": "^0.4.5", "jsonschema": "^1.2.4", "lodash": "^4.17.15", - "node-dir": "^0.1.17", "node-emoji": "^1.10.0", "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", "shelljs": "^0.8.3", "solidity-parser-antlr": "0.4.7", "web3": "1.2.1", diff --git a/plugins/resources/truffle.utils.js b/plugins/resources/truffle.utils.js index 9c00b594..f33f109f 100644 --- a/plugins/resources/truffle.utils.js +++ b/plugins/resources/truffle.utils.js @@ -1,8 +1,7 @@ const PluginUI = require('./truffle.ui'); - const globalModules = require('global-modules'); const TruffleProvider = require('@truffle/provider'); -const dir = require('node-dir'); +const recursive = require('recursive-readdir'); const globby = require('globby'); const path = require('path'); @@ -15,7 +14,7 @@ const path = require('path'); * @param {Object} config truffleConfig * @return {String[]} list of files to pass to mocha */ -function getTestFilePaths(config){ +async function getTestFilePaths(config){ let target; let ui = new PluginUI(config.logger.log); @@ -23,7 +22,7 @@ function getTestFilePaths(config){ // Handle --file cli option (subset of tests) (typeof config.file === 'string') ? target = globby.sync([config.file]) - : target = dir.files(config.testDir, { sync: true }) || []; + : target = await recursive(config.testDir); // Filter native solidity tests and warn that they're skipped const solregex = /.*\.(sol)$/; diff --git a/plugins/truffle.plugin.js b/plugins/truffle.plugin.js index 06bbadeb..5df66dc4 100644 --- a/plugins/truffle.plugin.js +++ b/plugins/truffle.plugin.js @@ -96,7 +96,7 @@ async function plugin(config){ ); config.all = true; - config.test_files = truffleUtils.getTestFilePaths(config); + config.test_files = await truffleUtils.getTestFilePaths(config); config.compilers.solc.settings.optimizer.enabled = false; // Compile Instrumented Contracts diff --git a/test/integration/projects/tests-folder/.solcover.js b/test/integration/projects/tests-folder/.solcover.js new file mode 100644 index 00000000..71b990cc --- /dev/null +++ b/test/integration/projects/tests-folder/.solcover.js @@ -0,0 +1,4 @@ +module.exports = { + "silent": false, + "istanbulReporter": [ "json-summary", "text"] +} diff --git a/test/integration/projects/tests-folder/buidler.config.js b/test/integration/projects/tests-folder/buidler.config.js new file mode 100644 index 00000000..d1f48df0 --- /dev/null +++ b/test/integration/projects/tests-folder/buidler.config.js @@ -0,0 +1,8 @@ +const { loadPluginFile } = require("@nomiclabs/buidler/plugins-testing"); +loadPluginFile(__dirname + "/../plugins/buidler.plugin"); +usePlugin("@nomiclabs/buidler-truffle5"); + +module.exports={ + defaultNetwork: "buidlerevm", + logger: process.env.SILENT ? { log: () => {} } : console, +}; \ No newline at end of file diff --git a/test/integration/projects/tests-folder/contracts/ContractA.sol b/test/integration/projects/tests-folder/contracts/ContractA.sol new file mode 100644 index 00000000..9d8d1344 --- /dev/null +++ b/test/integration/projects/tests-folder/contracts/ContractA.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractA { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/tests-folder/contracts/ContractB.sol b/test/integration/projects/tests-folder/contracts/ContractB.sol new file mode 100644 index 00000000..daa42f7d --- /dev/null +++ b/test/integration/projects/tests-folder/contracts/ContractB.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractB { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/tests-folder/contracts/ContractC.sol b/test/integration/projects/tests-folder/contracts/ContractC.sol new file mode 100644 index 00000000..454c86cd --- /dev/null +++ b/test/integration/projects/tests-folder/contracts/ContractC.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.0; + + +contract ContractC { + uint x; + constructor() public { + } + + function sendFn() public { + x = 5; + } + + function callFn() public pure returns (uint){ + uint y = 5; + return y; + } +} diff --git a/test/integration/projects/tests-folder/contracts/Migrations.sol b/test/integration/projects/tests-folder/contracts/Migrations.sol new file mode 100644 index 00000000..c378ffb0 --- /dev/null +++ b/test/integration/projects/tests-folder/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity >=0.4.21 <0.6.0; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + constructor() public { + owner = msg.sender; + } + + modifier restricted() { + if (msg.sender == owner) _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/test/integration/projects/tests-folder/test/contracta.js b/test/integration/projects/tests-folder/test/contracta.js new file mode 100644 index 00000000..cc778027 --- /dev/null +++ b/test/integration/projects/tests-folder/test/contracta.js @@ -0,0 +1,15 @@ +const ContractA = artifacts.require("ContractA"); + +contract("contracta", function(accounts) { + let instance; + + before(async () => instance = await ContractA.new()) + + it('sends [ @skipForCoverage ]', async function(){ + await instance.sendFn(); + }); + + it('calls [ @skipForCoverage ]', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/tests-folder/test/folder/contractb.js b/test/integration/projects/tests-folder/test/folder/contractb.js new file mode 100644 index 00000000..71ebfb7a --- /dev/null +++ b/test/integration/projects/tests-folder/test/folder/contractb.js @@ -0,0 +1,15 @@ +const ContractB = artifacts.require("ContractB"); + +contract("contractB [ @skipForCoverage ]", function(accounts) { + let instance; + + before(async () => instance = await ContractB.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/integration/projects/tests-folder/test/folder/contractc.js b/test/integration/projects/tests-folder/test/folder/contractc.js new file mode 100644 index 00000000..9b3d950d --- /dev/null +++ b/test/integration/projects/tests-folder/test/folder/contractc.js @@ -0,0 +1,20 @@ +const ContractC = artifacts.require("ContractC"); + +contract("contractc", function(accounts) { + let instance; + + before(async () => instance = await ContractC.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) + + it('sends', async function(){ + await instance.sendFn(); + }); + +}); diff --git a/test/integration/projects/tests-folder/truffle-config.js b/test/integration/projects/tests-folder/truffle-config.js new file mode 100644 index 00000000..b398b071 --- /dev/null +++ b/test/integration/projects/tests-folder/truffle-config.js @@ -0,0 +1,7 @@ +module.exports = { + networks: {}, + mocha: {}, + compilers: { + solc: {} + } +} diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 436a457e..8a19dd94 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -79,6 +79,29 @@ describe('Truffle Plugin: standard use cases', function() { verify.lineCoverage(expected); }); + + it('tests in first layer and in a sub-folder', async function() { + mock.installFullProject('tests-folder'); + await plugin(truffleConfig); + + const expected = [ + { + file: mock.pathToContract(truffleConfig, 'ContractA.sol'), + pct: 100 + }, + { + file: mock.pathToContract(truffleConfig, 'ContractB.sol'), + pct: 100, + }, + { + file: mock.pathToContract(truffleConfig, 'ContractC.sol'), + pct: 100, + }, + ]; + + verify.lineCoverage(expected); + }); + it('with relative path solidity imports', async function() { mock.installFullProject('import-paths'); await plugin(truffleConfig); diff --git a/yarn.lock b/yarn.lock index 5c3e4251..a7ad95dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5038,7 +5038,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -5229,13 +5229,6 @@ node-alias@^1.0.4: chalk "^1.1.1" lodash "^4.2.0" -node-dir@^0.1.17: - version "0.1.17" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU= - dependencies: - minimatch "^3.0.2" - node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -6222,6 +6215,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +recursive-readdir@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + regenerate@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" From c1d9ea1872a436b01d85631ed2c9a0041db197f5 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sat, 30 Nov 2019 01:35:26 -0800 Subject: [PATCH 20/21] Improve API docs overview (#452) --- docs/api.md | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/docs/api.md b/docs/api.md index 8c8d7c63..eac6c08e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,32 +1,30 @@ -# Solidity-Coverage API Documentation +# Solidity-Coverage API -`solidity-coverage`'s API provides test coverage measurement for the Solidity language. -The repository contains two complete coverage tool/plugin implementations (for Buidler and Truffle) -which can be used as sources if you're building something similar. +solidity-coverage tracks which lines are hit as your tests run by instrumenting the contracts with special solidity statements and detecting their execution in a coverage-enabled EVM. -`solidity-coverage`'s core algorithm resembles the one used by [Istanbul][3] for javascript programs. -It tracks line and branch locations by 'instrumenting' solidity contracts with special solidity -statements and detecting their execution in a coverage-enabled EVM. As such, its API spans the -full set of tasks typically required to run a solidity test suite. +As such, the API spans the full set of tasks typically required to run a solidity test suite. The +table below shows how its core methods relate to the stages of a test run: -+ compile -+ ethereum client launch -+ test -+ report outcome and exit +| Test Stage | API Method | Description | +|---------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| compilation | `instrument` | A **pre-compilation** step: Rewrites contracts and generates an instrumentation data map. | +| client launch | `ganache` | A **substitute** step: Launches a ganache client with coverage collection enabled in its VM. As the client,runs it will mark line/branch hits on the instrumentation data map. | +| test | `report` | A **post-test** step: Generates a coverage report from the data collected by the VM after tests complete. | +| exit | `finish` | A **substitute** step: Shuts client down | [3]: https://github.com/gotwarlost/istanbul -The API's corresponding methods are: +**Additional Resources:** + ++ the library includes [file system utilities](#Utils) for managing the +disposable set of contracts/artifacts which coverage must use in lieu of the 'real' (uninstrumented) +contracts. + ++ there are two complete [coverage tool/plugin implementations][5] (for Buidler and Truffle) +which can be used as sources if you're building something similar. -+ `instrument`: Rewrites contracts for instrumented compilation. Generates an instrumentation data map. -+ `ganache`: Launches a ganache client with coverage collection enabled in its VM. As the client - runs it will mark line/branch hits on the instrumentation data map. -+ `report`: Generates a coverage report from the data collected by the VM after tests complete. Converts - the instrumentation data map into an object IstanbulJS can process. -+ `finish`: Shuts client down +[5]: https://github.com/sc-forks/solidity-coverage/tree/beta/plugins -The library also includes some file system [utilities](#Utils) which are helpful for managing the -disposable set of contracts/artifacts which coverage must use in lieu of the 'real' contracts/artifacts. # Table of Contents @@ -226,8 +224,8 @@ const config = { ## loadSolcoverJS -Loads `.solcoverjs`. Users may specify options described in the README in `.solcover.js` config -file which your application needs to consume. +Loads `.solcoverjs`. Users may specify [options][7] in `.solcover.js` config file which your +application needs to consume. **Parameters** @@ -242,6 +240,8 @@ const solcoverJS = utils.loadSolcoverJS(config); const api = new CoverageAPI(solcoverJS); ``` +[7]: https://github.com/sc-forks/solidity-coverage/tree/beta#config-options + ------------- ## assembleFiles @@ -360,9 +360,8 @@ Returns **Promise** **Example** ```javascript -await utils.finish(); +await utils.finish(config, api); ``` - From 28ab3d2191e2cf67f4d3e1f1f09f8e4a6cb4f096 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sat, 30 Nov 2019 11:26:48 -0800 Subject: [PATCH 21/21] More API docs cleanup --- docs/api.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/api.md b/docs/api.md index eac6c08e..71d0d435 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # Solidity-Coverage API -solidity-coverage tracks which lines are hit as your tests run by instrumenting the contracts with special solidity statements and detecting their execution in a coverage-enabled EVM. +Solidity-coverage tracks which lines are hit as your tests run by instrumenting the contracts with special solidity statements and detecting their execution in a coverage-enabled EVM. As such, the API spans the full set of tasks typically required to run a solidity test suite. The table below shows how its core methods relate to the stages of a test run: @@ -8,7 +8,7 @@ table below shows how its core methods relate to the stages of a test run: | Test Stage | API Method | Description | |---------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | compilation | `instrument` | A **pre-compilation** step: Rewrites contracts and generates an instrumentation data map. | -| client launch | `ganache` | A **substitute** step: Launches a ganache client with coverage collection enabled in its VM. As the client,runs it will mark line/branch hits on the instrumentation data map. | +| client launch | `ganache` | A **substitute** step: Launches a ganache client with coverage collection enabled in its VM. As the client runs it will mark line/branch hits on the instrumentation data map. | | test | `report` | A **post-test** step: Generates a coverage report from the data collected by the VM after tests complete. | | exit | `finish` | A **substitute** step: Shuts client down | @@ -102,10 +102,10 @@ const instrumented = api.instrument(contracts) ## ganache -Enables coverage data collection on an in-process ganache server. By default, will return -a url after server has begun listening on the port specified in the [config](#constructor) -(or 8555 by default). When `autoLaunchServer` is false, method returns`ganache.server` -so the consumer can control the 'server.listen' invocation themselves. +Enables coverage data collection on an in-process ganache server. By default, this method launches +the server, begins listening on the port specified in the [config](#constructor) (or 8555 if unspecified), and +returns a url string. When `autoLaunchServer` is false, method returns `ganache.server` so you can control +the `server.listen` invocation yourself. **Parameters** @@ -137,7 +137,7 @@ Generates coverage report using IstanbulJS **Parameters** -- `istanbulFolder` **String**: (*Optional*) path to folder IstanbulJS will deposit coverage reports in. +- `istanbulFolder` **String**: (*Optional*) path to folder Istanbul will deposit coverage reports in. Returns **Promise** @@ -176,7 +176,7 @@ Returns **Object** instrumentation data; ```javascript const contracts = api.instrument(contracts); const data = api.getInstrumentationData(); -save(data); +save(data); // Pseudo-code ``` ------------- @@ -189,14 +189,14 @@ in a different process. **Example** ```javascript -const data = load(data); +const data = load(data); // Pseudo-code api.setIntrumentationData(data); // Client will collect data for the loaded map const address = await api.ganache(client); // Or to `report` instrumentation data which was collected in a different process. -const data = load(data); +const data = load(data); // Pseudo-code api.setInstrumentationData(data); api.report(); @@ -224,7 +224,7 @@ const config = { ## loadSolcoverJS -Loads `.solcoverjs`. Users may specify [options][7] in `.solcover.js` config file which your +Loads `.solcoverjs`. Users may specify [options][7] in a `.solcover.js` config file which your application needs to consume. **Parameters**