From f91532e59887b79f4241d365979aefcce711d1a9 Mon Sep 17 00:00:00 2001 From: Claudia Barcelo Date: Fri, 2 Feb 2024 04:13:29 +0100 Subject: [PATCH 1/3] Add command option to specify the source files to run the coverage on (#806) --- plugins/hardhat.plugin.js | 1 + plugins/resources/nomiclabs.utils.js | 2 +- .../otherContracts/OtherContractA.sol | 17 +++++++++++ .../test-files/test/other_contract_a.js | 15 ++++++++++ test/units/hardhat/flags.js | 28 +++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/integration/projects/test-files/contracts/otherContracts/OtherContractA.sol create mode 100644 test/integration/projects/test-files/test/other_contract_a.js diff --git a/plugins/hardhat.plugin.js b/plugins/hardhat.plugin.js index 7bca7638..8fbda596 100644 --- a/plugins/hardhat.plugin.js +++ b/plugins/hardhat.plugin.js @@ -97,6 +97,7 @@ task("coverage", "Generates a code coverage report for tests") .addOptionalParam("testfiles", ui.flags.file, "", types.string) .addOptionalParam("solcoverjs", ui.flags.solcoverjs, "", types.string) .addOptionalParam('temp', ui.flags.temp, "", types.string) + .addOptionalParam('sources', ui.flags.sources, "", types.string) .addFlag('matrix', ui.flags.testMatrix) .addFlag('abi', ui.flags.abi) .setAction(async function(args, env){ diff --git a/plugins/resources/nomiclabs.utils.js b/plugins/resources/nomiclabs.utils.js index 0212a542..8b4c7a22 100644 --- a/plugins/resources/nomiclabs.utils.js +++ b/plugins/resources/nomiclabs.utils.js @@ -31,7 +31,7 @@ function getTestFilePaths(files){ */ function normalizeConfig(config, args={}){ config.workingDir = config.paths.root; - config.contractsDir = config.paths.sources; + config.contractsDir = args.sources? args.sources : config.paths.sources; config.testDir = config.paths.tests; config.artifactsDir = config.paths.artifacts; config.logger = config.logger ? config.logger : {log: null}; diff --git a/test/integration/projects/test-files/contracts/otherContracts/OtherContractA.sol b/test/integration/projects/test-files/contracts/otherContracts/OtherContractA.sol new file mode 100644 index 00000000..119c9f75 --- /dev/null +++ b/test/integration/projects/test-files/contracts/otherContracts/OtherContractA.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.7.0; + + +contract OtherContractA { + 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/test-files/test/other_contract_a.js b/test/integration/projects/test-files/test/other_contract_a.js new file mode 100644 index 00000000..4d78abfb --- /dev/null +++ b/test/integration/projects/test-files/test/other_contract_a.js @@ -0,0 +1,15 @@ +const OtherContractA = artifacts.require("OtherContractA"); + +contract("otherContractA", function(accounts) { + let instance; + + before(async () => instance = await OtherContractA.new()) + + it('sends', async function(){ + await instance.sendFn(); + }); + + it('calls', async function(){ + await instance.callFn(); + }) +}); diff --git a/test/units/hardhat/flags.js b/test/units/hardhat/flags.js index c044f5a0..74bcea74 100644 --- a/test/units/hardhat/flags.js +++ b/test/units/hardhat/flags.js @@ -230,5 +230,33 @@ describe('Hardhat Plugin: command line options', function() { const output = require(outputPath); assert.deepEqual(output, expected); }) + + it('--sources contract/', async function() { + + const taskArgs = { + testfiles: path.join( + hardhatConfig.paths.root, + 'test/other_contract_a.js' + ), + sources: path.join( + hardhatConfig.paths.root, + 'contracts/otherContracts' + ) + }; + mock.installFullProject('test-files'); + mock.hardhatSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + const expected = [ + { + file: mock.pathToContract(hardhatConfig, 'otherContracts/OtherContractA.sol'), + pct: 100 + } + ]; + + verify.lineCoverage(expected); + }); + }); From 75f88bf65c70c255ad2db1a8c5fe9fcc0bbc6359 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 1 Feb 2024 19:57:47 -0800 Subject: [PATCH 2/3] Support single file targets, add README docs --- README.md | 1 + plugins/resources/nomiclabs.utils.js | 8 ++++- plugins/resources/plugin.utils.js | 14 ++++++-- test/units/hardhat/flags.js | 54 +++++++++++++++++++++++----- 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 55a06a6d..f8280316 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ npx hardhat coverage [command-options] | Option | Example | Description | |--------------|------------------------------------|--------------------------------| | testfiles | `--testfiles "test/registry/*.ts"` | Test file(s) to run. (Globs must be enclosed by quotes and use [globby matching patterns][38])| +| sources | --sources "myFolder" or --sources "myFile.sol" | Path to *single* folder or file to target for coverage. Path is relative to Hardhat's `paths.sources` (usually `contracts/`)) | | 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 Hardhat 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/plugins/resources/nomiclabs.utils.js b/plugins/resources/nomiclabs.utils.js index 8b4c7a22..0c9dd871 100644 --- a/plugins/resources/nomiclabs.utils.js +++ b/plugins/resources/nomiclabs.utils.js @@ -30,8 +30,14 @@ function getTestFilePaths(files){ * @return {HardhatConfig} updated config */ function normalizeConfig(config, args={}){ + let sources; + + (args.sources) + ? sources = path.join(config.paths.sources, args.sources) + : sources = config.paths.sources; + config.workingDir = config.paths.root; - config.contractsDir = args.sources? args.sources : config.paths.sources; + config.contractsDir = sources; config.testDir = config.paths.tests; config.artifactsDir = config.paths.artifacts; config.logger = config.logger ? config.logger : {log: null}; diff --git a/plugins/resources/plugin.utils.js b/plugins/resources/plugin.utils.js index 6de507f5..a296da0a 100644 --- a/plugins/resources/plugin.utils.js +++ b/plugins/resources/plugin.utils.js @@ -131,8 +131,18 @@ function checkContext(config, tempContractsDir, tempArtifactsDir){ // ============================= function assembleFiles(config, skipFiles=[]){ - const targetsPath = path.join(config.contractsDir, '**', '*.{sol,vy}'); - const targets = shell.ls(targetsPath).map(path.normalize); + let targets; + let targetsPath; + + // The targets (contractsDir) could actually be a single named file (OR a folder) + const extName = path.extname(config.contractsDir); + + if (extName.length !== 0) { + targets = [ path.normalize(config.contractsDir) ]; + } else { + targetsPath = path.join(config.contractsDir, '**', '*.{sol,vy}'); + targets = shell.ls(targetsPath).map(path.normalize); + } skipFiles = assembleSkipped(config, targets, skipFiles); diff --git a/test/units/hardhat/flags.js b/test/units/hardhat/flags.js index 74bcea74..f8765558 100644 --- a/test/units/hardhat/flags.js +++ b/test/units/hardhat/flags.js @@ -231,17 +231,53 @@ describe('Hardhat Plugin: command line options', function() { assert.deepEqual(output, expected); }) - it('--sources contract/', async function() { + it('--sources folder', async function() { const taskArgs = { - testfiles: path.join( - hardhatConfig.paths.root, - 'test/other_contract_a.js' - ), - sources: path.join( - hardhatConfig.paths.root, - 'contracts/otherContracts' - ) + testfiles: path.join(hardhatConfig.paths.root, 'test/other_contract_a.js'), + sources: 'otherContracts' + }; + mock.installFullProject('test-files'); + mock.hardhatSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + const expected = [ + { + file: mock.pathToContract(hardhatConfig, 'otherContracts/OtherContractA.sol'), + pct: 100 + } + ]; + + verify.lineCoverage(expected); + }); + + it('--sources folder/', async function() { + + const taskArgs = { + testfiles: path.join(hardhatConfig.paths.root, 'test/other_contract_a.js'), + sources: 'otherContracts/' + }; + mock.installFullProject('test-files'); + mock.hardhatSetupEnv(this); + + await this.env.run("coverage", taskArgs); + + const expected = [ + { + file: mock.pathToContract(hardhatConfig, 'otherContracts/OtherContractA.sol'), + pct: 100 + } + ]; + + verify.lineCoverage(expected); + }); + + it('--sources folder/filename.sol', async function() { + + const taskArgs = { + testfiles: path.join(hardhatConfig.paths.root, 'test/other_contract_a.js'), + sources: 'otherContracts/OtherContractA.sol' }; mock.installFullProject('test-files'); mock.hardhatSetupEnv(this); From c5c2268582b167334a8efc2d4b06b08344eebab3 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 1 Feb 2024 20:21:45 -0800 Subject: [PATCH 3/3] Fix README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8280316..b43b825e 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ npx hardhat coverage [command-options] | Option | Example | Description | |--------------|------------------------------------|--------------------------------| | testfiles | `--testfiles "test/registry/*.ts"` | Test file(s) to run. (Globs must be enclosed by quotes and use [globby matching patterns][38])| -| sources | --sources "myFolder" or --sources "myFile.sol" | Path to *single* folder or file to target for coverage. Path is relative to Hardhat's `paths.sources` (usually `contracts/`)) | +| sources | `--sources myFolder` or `--sources myFile.sol` | Path to *single* folder or file to target for coverage. Path is relative to Hardhat's `paths.sources` (usually `contracts/`) | | 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 Hardhat 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] |