Skip to content

Commit

Permalink
support leading dots in --extension
Browse files Browse the repository at this point in the history
- update documentation for the feature and multipart extensions
- rename integration test `file-utils.spec.js` to `lookup-files.spec.js` and "modernize" it

Signed-off-by: Christopher Hiller <boneskull@boneskull.com>
  • Loading branch information
boneskull committed Oct 12, 2020
1 parent 2852505 commit 9c28990
Show file tree
Hide file tree
Showing 4 changed files with 290 additions and 137 deletions.
6 changes: 5 additions & 1 deletion docs/index.md
Expand Up @@ -984,7 +984,11 @@ Files having this extension will be considered test files. Defaults to `js`.

Specifying `--extension` will _remove_ `.js` as a test file extension; use `--extension js` to re-add it. For example, to load `.mjs` and `.js` test files, you must supply `--extension mjs --extension js`.

The option can be given multiple times. The option accepts a comma-delimited list: `--extension a,b` is equivalent to `--extension a --extension b`
The option can be given multiple times. The option accepts a comma-delimited list: `--extension a,b` is equivalent to `--extension a --extension b`.

> _New in v8.2.0._
`--extension` now supports multipart extensions (e.g., `spec.js`), leading dots (`.js`) and combinations thereof (`.spec.js`);

### `--file <file|directory|glob>`

Expand Down
61 changes: 31 additions & 30 deletions lib/cli/lookup-files.js
@@ -1,5 +1,4 @@
'use strict';

/**
* Contains `lookupFiles`, which takes some globs/dirs/options and returns a list of files.
* @module
Expand All @@ -14,6 +13,7 @@ var errors = require('../errors');
var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
var createMissingArgumentError = errors.createMissingArgumentError;
var {sQuote, dQuote} = require('../utils');
const debug = require('debug')('mocha:cli:lookup-files');

/**
* Determines if pathname would be a "hidden" file (or directory) on UN*X.
Expand All @@ -30,25 +30,26 @@ var {sQuote, dQuote} = require('../utils');
* @example
* isHiddenOnUnix('.profile'); // => true
*/
function isHiddenOnUnix(pathname) {
return path.basename(pathname)[0] === '.';
}
const isHiddenOnUnix = pathname => path.basename(pathname).startsWith('.');

/**
* Determines if pathname has a matching file extension.
*
* Supports multi-part extensions.
*
* @private
* @param {string} pathname - Pathname to check for match.
* @param {string[]} exts - List of file extensions (sans period).
* @return {boolean} whether file extension matches.
* @param {string[]} exts - List of file extensions, w/-or-w/o leading period
* @return {boolean} `true` if file extension matches.
* @example
* hasMatchingExtname('foo.html', ['js', 'css']); // => false
* hasMatchingExtname('foo.html', ['js', 'css']); // false
* hasMatchingExtname('foo.js', ['.js']); // true
* hasMatchingExtname('foo.js', ['js']); // ture
*/
function hasMatchingExtname(pathname, exts) {
return exts.some(function(element) {
return pathname.endsWith('.' + element);
});
}
const hasMatchingExtname = (pathname, exts = []) =>
exts
.map(ext => (ext.startsWith('.') ? ext : `.${ext}`))
.some(ext => pathname.endsWith(ext));

/**
* Lookup file names at the given `path`.
Expand All @@ -66,27 +67,28 @@ function hasMatchingExtname(pathname, exts) {
* @throws {Error} if no files match pattern.
* @throws {TypeError} if `filepath` is directory and `extensions` not provided.
*/
module.exports = function lookupFiles(filepath, extensions, recursive) {
extensions = extensions || [];
recursive = recursive || false;
var files = [];
var stat;
module.exports = function lookupFiles(
filepath,
extensions = [],
recursive = false
) {
const files = [];
let stat;

if (!fs.existsSync(filepath)) {
var pattern;
let pattern;
if (glob.hasMagic(filepath)) {
// Handle glob as is without extensions
pattern = filepath;
} else {
// glob pattern e.g. 'filepath+(.js|.ts)'
var strExtensions = extensions
.map(function(v) {
return '.' + v;
})
const strExtensions = extensions
.map(ext => (ext.startsWith('.') ? ext : `.${ext}`))
.join('|');
pattern = filepath + '+(' + strExtensions + ')';
pattern = `${filepath}+(${strExtensions})`;
debug('looking for files using glob pattern: %s', pattern);
}
files = glob.sync(pattern, {nodir: true});
files.push(...glob.sync(pattern, {nodir: true}));
if (!files.length) {
throw createNoFilesMatchPatternError(
'Cannot find any files matching pattern ' + dQuote(filepath),
Expand All @@ -108,20 +110,19 @@ module.exports = function lookupFiles(filepath, extensions, recursive) {
}

// Handle directory
fs.readdirSync(filepath).forEach(function(dirent) {
var pathname = path.join(filepath, dirent);
var stat;
fs.readdirSync(filepath).forEach(dirent => {
const pathname = path.join(filepath, dirent);
let stat;

try {
stat = fs.statSync(pathname);
if (stat.isDirectory()) {
if (recursive) {
files = files.concat(lookupFiles(pathname, extensions, recursive));
files.push(...lookupFiles(pathname, extensions, recursive));
}
return;
}
} catch (err) {
// ignore error
} catch (ignored) {
return;
}
if (!extensions.length) {
Expand Down

0 comments on commit 9c28990

Please sign in to comment.