mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Add Promise-based APIs for markdownlint and readConfig, update declaration file.
This commit is contained in:
parent
1f6a2cdc96
commit
e9d63a6284
5 changed files with 201 additions and 45 deletions
55
README.md
55
README.md
|
@ -235,31 +235,44 @@ located. Multiple such comments (if present) are applied top-to-bottom.
|
||||||
|
|
||||||
### Linting
|
### Linting
|
||||||
|
|
||||||
Standard asynchronous interface:
|
Standard asynchronous API:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
* Lint specified Markdown files.
|
* Lint specified Markdown files.
|
||||||
*
|
*
|
||||||
* @param {Object} options Configuration options.
|
* @param {Options} options Configuration options.
|
||||||
* @param {Function} callback Callback (err, result) function.
|
* @param {LintCallback} callback Callback (err, result) function.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function markdownlint(options, callback) { ... }
|
function markdownlint(options, callback) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
Synchronous interface (for build scripts, etc.):
|
Synchronous API (for build scripts, etc.):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
* Lint specified Markdown files synchronously.
|
* Lint specified Markdown files synchronously.
|
||||||
*
|
*
|
||||||
* @param {Object} options Configuration options.
|
* @param {Options} options Configuration options.
|
||||||
* @returns {Object} Result object.
|
* @returns {LintResults} Results object.
|
||||||
*/
|
*/
|
||||||
function markdownlint.sync(options) { ... }
|
function markdownlint.sync(options) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Promise API (in the `promises` namespace like Node.js's
|
||||||
|
[`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)):
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Lint specified Markdown files.
|
||||||
|
*
|
||||||
|
* @param {Options} options Configuration options.
|
||||||
|
* @returns {Promise<LintResults>} Results object.
|
||||||
|
*/
|
||||||
|
function markdownlint(options) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
#### options
|
#### options
|
||||||
|
|
||||||
Type: `Object`
|
Type: `Object`
|
||||||
|
@ -518,33 +531,47 @@ other files (see above).
|
||||||
By default, configuration files are parsed as JSON (and named `.markdownlint.json`).
|
By default, configuration files are parsed as JSON (and named `.markdownlint.json`).
|
||||||
Custom parsers can be provided to handle other formats like JSONC, YAML, and TOML.
|
Custom parsers can be provided to handle other formats like JSONC, YAML, and TOML.
|
||||||
|
|
||||||
Asynchronous interface:
|
Asynchronous API:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
* Read specified configuration file.
|
* Read specified configuration file.
|
||||||
*
|
*
|
||||||
* @param {String} file Configuration file name/path.
|
* @param {string} file Configuration file name.
|
||||||
* @param {Array} [parsers] Optional parsing function(s).
|
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing function(s).
|
||||||
* @param {Function} callback Callback (err, result) function.
|
* @param {ReadConfigCallback} [callback] Callback (err, result) function.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function readConfig(file, parsers, callback) { ... }
|
function readConfig(file, parsers, callback) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
Synchronous interface:
|
Synchronous API:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
* Read specified configuration file synchronously.
|
* Read specified configuration file synchronously.
|
||||||
*
|
*
|
||||||
* @param {String} file Configuration file name/path.
|
* @param {string} file Configuration file name.
|
||||||
* @param {Array} [parsers] Optional parsing function(s).
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||||
* @returns {Object} Configuration object.
|
* @returns {Configuration} Configuration object.
|
||||||
*/
|
*/
|
||||||
function readConfigSync(file, parsers) { ... }
|
function readConfigSync(file, parsers) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Promise API (in the `promises` namespace like Node.js's
|
||||||
|
[`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)):
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* Read specified configuration file.
|
||||||
|
*
|
||||||
|
* @param {string} file Configuration file name.
|
||||||
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||||
|
* @returns {Promise<Configuration>} Configuration object.
|
||||||
|
*/
|
||||||
|
function readConfig(file, parsers) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
#### file
|
#### file
|
||||||
|
|
||||||
Type: `String`
|
Type: `String`
|
||||||
|
|
|
@ -64,11 +64,14 @@ function assertLintResultsCallback(err: Error | null, results?: markdownlint.Lin
|
||||||
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath));
|
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath));
|
||||||
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath, [ JSON.parse ]));
|
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath, [ JSON.parse ]));
|
||||||
|
|
||||||
// The following call is valid, but disallowed because TypeScript does not
|
markdownlint.readConfig(markdownlintJsonPath, assertConfigurationCallback);
|
||||||
// currently propagate {ConfigurationParser[] | null} into the .d.ts file.
|
|
||||||
// markdownlint.readConfig(markdownlintJsonPath, null, assertConfigCallback);
|
|
||||||
markdownlint.readConfig(markdownlintJsonPath, [ JSON.parse ], assertConfigurationCallback);
|
markdownlint.readConfig(markdownlintJsonPath, [ JSON.parse ], assertConfigurationCallback);
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
assertConfigurationCallback(null, await markdownlint.promises.readConfig(markdownlintJsonPath));
|
||||||
|
assertConfigurationCallback(null, await markdownlint.promises.readConfig(markdownlintJsonPath, [ JSON.parse ]))
|
||||||
|
})();
|
||||||
|
|
||||||
let options: markdownlint.Options;
|
let options: markdownlint.Options;
|
||||||
options = {
|
options = {
|
||||||
"files": [ "../bad.md" ],
|
"files": [ "../bad.md" ],
|
||||||
|
@ -91,10 +94,16 @@ options = {
|
||||||
|
|
||||||
assertLintResults(markdownlint.sync(options));
|
assertLintResults(markdownlint.sync(options));
|
||||||
markdownlint(options, assertLintResultsCallback);
|
markdownlint(options, assertLintResultsCallback);
|
||||||
|
(async () => {
|
||||||
|
assertLintResultsCallback(null, await markdownlint.promises.markdownlint(options));
|
||||||
|
})();
|
||||||
|
|
||||||
options.files = "../bad.md";
|
options.files = "../bad.md";
|
||||||
assertLintResults(markdownlint.sync(options));
|
assertLintResults(markdownlint.sync(options));
|
||||||
markdownlint(options, assertLintResultsCallback);
|
markdownlint(options, assertLintResultsCallback);
|
||||||
|
(async () => {
|
||||||
|
assertLintResultsCallback(null, await markdownlint.promises.markdownlint(options));
|
||||||
|
})();
|
||||||
|
|
||||||
const testRule = {
|
const testRule = {
|
||||||
"names": [ "test-rule" ],
|
"names": [ "test-rule" ],
|
||||||
|
@ -139,3 +148,6 @@ const testRule = {
|
||||||
options.customRules = [ testRule ];
|
options.customRules = [ testRule ];
|
||||||
assertLintResults(markdownlint.sync(options));
|
assertLintResults(markdownlint.sync(options));
|
||||||
markdownlint(options, assertLintResultsCallback);
|
markdownlint(options, assertLintResultsCallback);
|
||||||
|
(async () => {
|
||||||
|
assertLintResultsCallback(null, await markdownlint.promises.markdownlint(options));
|
||||||
|
})();
|
||||||
|
|
51
lib/markdownlint.d.ts
vendored
51
lib/markdownlint.d.ts
vendored
|
@ -8,7 +8,7 @@ export = markdownlint;
|
||||||
*/
|
*/
|
||||||
declare function markdownlint(options: Options, callback: LintCallback): void;
|
declare function markdownlint(options: Options, callback: LintCallback): void;
|
||||||
declare namespace markdownlint {
|
declare namespace markdownlint {
|
||||||
export { markdownlintSync as sync, readConfig, readConfigSync, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback };
|
export { markdownlintSync as sync, readConfig, readConfigSync, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback };
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* Configuration options.
|
||||||
|
@ -17,7 +17,7 @@ type Options = {
|
||||||
/**
|
/**
|
||||||
* Files to lint.
|
* Files to lint.
|
||||||
*/
|
*/
|
||||||
files?: string | string[];
|
files?: string[] | string;
|
||||||
/**
|
/**
|
||||||
* Strings to lint.
|
* Strings to lint.
|
||||||
*/
|
*/
|
||||||
|
@ -27,13 +27,11 @@ type Options = {
|
||||||
/**
|
/**
|
||||||
* Configuration object.
|
* Configuration object.
|
||||||
*/
|
*/
|
||||||
config?: {
|
config?: Configuration;
|
||||||
[x: string]: any;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Custom rules.
|
* Custom rules.
|
||||||
*/
|
*/
|
||||||
customRules?: Rule | Rule[];
|
customRules?: Rule[] | Rule;
|
||||||
/**
|
/**
|
||||||
* Front matter pattern.
|
* Front matter pattern.
|
||||||
*/
|
*/
|
||||||
|
@ -58,18 +56,14 @@ type Options = {
|
||||||
/**
|
/**
|
||||||
* Called with the result of the lint operation.
|
* Called with the result of the lint operation.
|
||||||
*/
|
*/
|
||||||
type LintCallback = (err: Error, results?: {
|
type LintCallback = (err: Error | null, results?: LintResults) => void;
|
||||||
[x: string]: LintError[];
|
|
||||||
}) => void;
|
|
||||||
/**
|
/**
|
||||||
* Lint specified Markdown files synchronously.
|
* Lint specified Markdown files synchronously.
|
||||||
*
|
*
|
||||||
* @param {Options} options Configuration options.
|
* @param {Options} options Configuration options.
|
||||||
* @returns {LintResults} Results object.
|
* @returns {LintResults} Results object.
|
||||||
*/
|
*/
|
||||||
declare function markdownlintSync(options: Options): {
|
declare function markdownlintSync(options: Options): LintResults;
|
||||||
[x: string]: LintError[];
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Read specified configuration file.
|
* Read specified configuration file.
|
||||||
*
|
*
|
||||||
|
@ -87,9 +81,11 @@ declare function readConfig(file: string, parsers: ConfigurationParser[] | ReadC
|
||||||
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||||
* @returns {Configuration} Configuration object.
|
* @returns {Configuration} Configuration object.
|
||||||
*/
|
*/
|
||||||
declare function readConfigSync(file: string, parsers?: ConfigurationParser[]): {
|
declare function readConfigSync(file: string, parsers?: ConfigurationParser[]): Configuration;
|
||||||
[x: string]: any;
|
declare namespace promises {
|
||||||
};
|
export { markdownlintPromise as markdownlint };
|
||||||
|
export { readConfigPromise as readConfig };
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Function to implement rule logic.
|
* Function to implement rule logic.
|
||||||
*/
|
*/
|
||||||
|
@ -117,7 +113,7 @@ type RuleParams = {
|
||||||
/**
|
/**
|
||||||
* Rule configuration.
|
* Rule configuration.
|
||||||
*/
|
*/
|
||||||
config: any;
|
config: RuleConfiguration;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Markdown-It token.
|
* Markdown-It token.
|
||||||
|
@ -341,12 +337,23 @@ type RuleConfiguration = any;
|
||||||
/**
|
/**
|
||||||
* Parses a configuration string and returns a configuration object.
|
* Parses a configuration string and returns a configuration object.
|
||||||
*/
|
*/
|
||||||
type ConfigurationParser = (text: string) => {
|
type ConfigurationParser = (text: string) => Configuration;
|
||||||
[x: string]: any;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Called with the result of the readConfig operation.
|
* Called with the result of the readConfig operation.
|
||||||
*/
|
*/
|
||||||
type ReadConfigCallback = (err: Error, config?: {
|
type ReadConfigCallback = (err: Error | null, config?: Configuration) => void;
|
||||||
[x: string]: any;
|
/**
|
||||||
}) => void;
|
* Lint specified Markdown files.
|
||||||
|
*
|
||||||
|
* @param {Options} options Configuration options.
|
||||||
|
* @returns {Promise<LintResults>} Results object.
|
||||||
|
*/
|
||||||
|
declare function markdownlintPromise(options: Options): Promise<LintResults>;
|
||||||
|
/**
|
||||||
|
* Read specified configuration file.
|
||||||
|
*
|
||||||
|
* @param {string} file Configuration file name.
|
||||||
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||||
|
* @returns {Promise<Configuration>} Configuration object.
|
||||||
|
*/
|
||||||
|
declare function readConfigPromise(file: string, parsers?: ConfigurationParser[]): Promise<Configuration>;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const util = require("util");
|
||||||
const markdownIt = require("markdown-it");
|
const markdownIt = require("markdown-it");
|
||||||
const rules = require("./rules");
|
const rules = require("./rules");
|
||||||
const helpers = require("../helpers");
|
const helpers = require("../helpers");
|
||||||
|
@ -11,7 +12,6 @@ const cache = require("./cache");
|
||||||
|
|
||||||
const deprecatedRuleNames = [ "MD002", "MD006" ];
|
const deprecatedRuleNames = [ "MD002", "MD006" ];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the list of rules for structure and reuse.
|
* Validate the list of rules for structure and reuse.
|
||||||
*
|
*
|
||||||
|
@ -834,6 +834,18 @@ function markdownlint(options, callback) {
|
||||||
return lintInput(options, false, callback);
|
return lintInput(options, false, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const markdownlintPromisify = util.promisify(markdownlint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lint specified Markdown files.
|
||||||
|
*
|
||||||
|
* @param {Options} options Configuration options.
|
||||||
|
* @returns {Promise<LintResults>} Results object.
|
||||||
|
*/
|
||||||
|
function markdownlintPromise(options) {
|
||||||
|
return markdownlintPromisify(options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lint specified Markdown files synchronously.
|
* Lint specified Markdown files synchronously.
|
||||||
*
|
*
|
||||||
|
@ -928,6 +940,20 @@ function readConfig(file, parsers, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const readConfigPromisify = util.promisify(readConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read specified configuration file.
|
||||||
|
*
|
||||||
|
* @param {string} file Configuration file name.
|
||||||
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
||||||
|
* @returns {Promise<Configuration>} Configuration object.
|
||||||
|
*/
|
||||||
|
function readConfigPromise(file, parsers) {
|
||||||
|
// @ts-ignore
|
||||||
|
return readConfigPromisify(file, parsers);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read specified configuration file synchronously.
|
* Read specified configuration file synchronously.
|
||||||
*
|
*
|
||||||
|
@ -959,10 +985,14 @@ function readConfigSync(file, parsers) {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export a/synchronous APIs
|
// Export a/synchronous/Promise APIs
|
||||||
markdownlint.sync = markdownlintSync;
|
markdownlint.sync = markdownlintSync;
|
||||||
markdownlint.readConfig = readConfig;
|
markdownlint.readConfig = readConfig;
|
||||||
markdownlint.readConfigSync = readConfigSync;
|
markdownlint.readConfigSync = readConfigSync;
|
||||||
|
markdownlint.promises = {
|
||||||
|
"markdownlint": markdownlintPromise,
|
||||||
|
"readConfig": readConfigPromise
|
||||||
|
};
|
||||||
module.exports = markdownlint;
|
module.exports = markdownlint;
|
||||||
|
|
||||||
// Type declarations
|
// Type declarations
|
||||||
|
@ -1081,11 +1111,8 @@ module.exports = markdownlint;
|
||||||
* Lint results (for resultVersion 3).
|
* Lint results (for resultVersion 3).
|
||||||
*
|
*
|
||||||
* @typedef {Object.<string, LintError[]>} LintResults
|
* @typedef {Object.<string, LintError[]>} LintResults
|
||||||
|
* @property {ToStringCallback} toString String representation.
|
||||||
*/
|
*/
|
||||||
// The following should be part of the LintResults typedef, but that causes
|
|
||||||
// TypeScript to "forget" about the string map.
|
|
||||||
// * @property {ToStringCallback} toString String representation.
|
|
||||||
// https://github.com/microsoft/TypeScript/issues/34911
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lint error.
|
* Lint error.
|
||||||
|
|
|
@ -23,6 +23,51 @@ const version = packageJson.version;
|
||||||
|
|
||||||
const deprecatedRuleNames = new Set([ "MD002", "MD006" ]);
|
const deprecatedRuleNames = new Set([ "MD002", "MD006" ]);
|
||||||
|
|
||||||
|
tape("simpleAsync", (test) => {
|
||||||
|
test.plan(2);
|
||||||
|
const options = {
|
||||||
|
"strings": {
|
||||||
|
"content": "# Heading"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const expected = "content: 1: MD047/single-trailing-newline " +
|
||||||
|
"Files should end with a single newline character";
|
||||||
|
markdownlint(options, (err, actual) => {
|
||||||
|
test.ifError(err);
|
||||||
|
test.equal(actual.toString(), expected, "Unexpected results.");
|
||||||
|
test.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tape("simpleSync", (test) => {
|
||||||
|
test.plan(1);
|
||||||
|
const options = {
|
||||||
|
"strings": {
|
||||||
|
"content": "# Heading"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const expected = "content: 1: MD047/single-trailing-newline " +
|
||||||
|
"Files should end with a single newline character";
|
||||||
|
const actual = markdownlint.sync(options).toString();
|
||||||
|
test.equal(actual, expected, "Unexpected results.");
|
||||||
|
test.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
tape("simplePromise", (test) => {
|
||||||
|
test.plan(1);
|
||||||
|
const options = {
|
||||||
|
"strings": {
|
||||||
|
"content": "# Heading"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const expected = "content: 1: MD047/single-trailing-newline " +
|
||||||
|
"Files should end with a single newline character";
|
||||||
|
markdownlint.promises.markdownlint(options).then((actual) => {
|
||||||
|
test.equal(actual.toString(), expected, "Unexpected results.");
|
||||||
|
test.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
tape("projectFilesNoInlineConfig", (test) => {
|
tape("projectFilesNoInlineConfig", (test) => {
|
||||||
test.plan(2);
|
test.plan(2);
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -698,6 +743,21 @@ tape("badFileSync", (test) => {
|
||||||
test.end();
|
test.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tape("badFilePromise", (test) => {
|
||||||
|
test.plan(3);
|
||||||
|
markdownlint.promises.markdownlint({
|
||||||
|
"files": [ "./badFile" ]
|
||||||
|
}).then(
|
||||||
|
null,
|
||||||
|
(error) => {
|
||||||
|
test.ok(error, "Did not get an error for bad file.");
|
||||||
|
test.ok(error instanceof Error, "Error not instance of Error.");
|
||||||
|
test.equal(error.code, "ENOENT", "Error code for bad file not ENOENT.");
|
||||||
|
test.end();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
tape("missingStringValue", (test) => {
|
tape("missingStringValue", (test) => {
|
||||||
test.plan(2);
|
test.plan(2);
|
||||||
markdownlint({
|
markdownlint({
|
||||||
|
@ -1197,6 +1257,29 @@ tape("configBadHybridSync", (test) => {
|
||||||
test.end();
|
test.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tape("configSinglePromise", (test) => {
|
||||||
|
test.plan(1);
|
||||||
|
markdownlint.promises.readConfig("./test/config/config-child.json")
|
||||||
|
.then((actual) => {
|
||||||
|
const expected = require("./config/config-child.json");
|
||||||
|
test.deepEqual(actual, expected, "Config object not correct.");
|
||||||
|
test.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tape("configBadFilePromise", (test) => {
|
||||||
|
test.plan(2);
|
||||||
|
markdownlint.promises.readConfig("./test/config/config-badfile.json")
|
||||||
|
.then(
|
||||||
|
null,
|
||||||
|
(error) => {
|
||||||
|
test.ok(error, "Did not get an error for bad JSON.");
|
||||||
|
test.ok(error instanceof Error, "Error not instance of Error.");
|
||||||
|
test.end();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
tape("allBuiltInRulesHaveValidUrl", (test) => {
|
tape("allBuiltInRulesHaveValidUrl", (test) => {
|
||||||
test.plan(132);
|
test.plan(132);
|
||||||
rules.forEach(function forRule(rule) {
|
rules.forEach(function forRule(rule) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue