diff --git a/README.md b/README.md index 2e2c7916..74803df3 100644 --- a/README.md +++ b/README.md @@ -659,9 +659,9 @@ Standard completion callback. Type: `Object` -Call `result.toString()` for convenience or see below for an example of the -structure of the `result` object. Passing the value `true` to `toString()` -uses rule aliases (ex: `no-hard-tabs`) instead of names (ex: `MD010`). +Map of input file names and string identifiers to issues within. + +See the [Usage section](#usage) for an example of the structure of this object. ### Config @@ -837,7 +837,7 @@ console.log(getVersion()); ## Usage -Invoke `lint` and use the `result` object's `toString` method: +Invoke `lint` as an asynchronous call: ```javascript import { lint as lintAsync } from "markdownlint/async"; @@ -852,34 +852,21 @@ const options = { lintAsync(options, function callback(error, results) { if (!error && results) { - console.log(results.toString()); + console.dir(results, { "colors": true, "depth": null }); } }); ``` -Output: - -```text -bad.string: 3: MD010/no-hard-tabs Hard tabs [Column: 19] -bad.string: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.string"] -bad.string: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This string fails some rules."] -bad.string: 1: MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "#bad.string"] -bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17] -bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"] -bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."] -bad.md: 1: MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "#bad.md"] -``` - Or as a synchronous call: ```javascript import { lint as lintSync } from "markdownlint/sync"; const results = lintSync(options); -console.log(results.toString()); +console.dir(results, { "colors": true, "depth": null }); ``` -To examine the `result` object directly via a `Promise`-based call: +Or as a `Promise`-based call: ```javascript import { lint as lintPromise } from "markdownlint/promise"; @@ -888,7 +875,7 @@ const results = await lintPromise(options); console.dir(results, { "colors": true, "depth": null }); ``` -Output: +All of which return an object like: ```json { @@ -900,38 +887,36 @@ Output: "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md010.md", "errorDetail": "Column: 17", "errorContext": null, - "errorRange": [ 17, 1 ] }, + "errorRange": [ 17, 1 ], + "fixInfo": { "editColumn": 17, "deleteCount": 1, "insertText": ' ' } } { "lineNumber": 1, "ruleNames": [ "MD018", "no-missing-space-atx" ], "ruleDescription": "No space after hash on atx style heading", "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md018.md", "errorDetail": null, "errorContext": "#bad.md", - "errorRange": [ 1, 2 ] }, + "errorRange": [ 1, 2 ], + "fixInfo": { "editColumn": 2, "insertText": ' ' } } { "lineNumber": 3, "ruleNames": [ "MD018", "no-missing-space-atx" ], "ruleDescription": "No space after hash on atx style heading", "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md018.md", "errorDetail": null, "errorContext": "#This file fails\tsome rules.", - "errorRange": [ 1, 2 ] }, + "errorRange": [ 1, 2 ], + "fixInfo": { "editColumn": 2, "insertText": ' ' } } { "lineNumber": 1, "ruleNames": [ "MD041", "first-line-heading", "first-line-h1" ], "ruleDescription": "First line in a file should be a top-level heading", "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md041.md", "errorDetail": null, "errorContext": "#bad.md", - "errorRange": null } + "errorRange": null, + "fixInfo": null } ] } ``` -Integration with the [gulp](https://gulpjs.com/) build system is -straightforward: [`gulpfile.cjs`](example/gulpfile.cjs). - -Integration with the [Grunt](https://gruntjs.com/) build system is similar: -[`Gruntfile.cjs`](example/Gruntfile.cjs). - ## Browser `markdownlint` also works in the browser. @@ -957,7 +942,7 @@ const options = { } }; -const results = globalThis.markdownlint.lintSync(options).toString(); +const results = globalThis.markdownlint.lintSync(options); ``` ## Examples diff --git a/example/Gruntfile.cjs b/example/Gruntfile.cjs deleted file mode 100644 index 571d403d..00000000 --- a/example/Gruntfile.cjs +++ /dev/null @@ -1,28 +0,0 @@ -// @ts-check - -"use strict"; - -module.exports = function wrapper(grunt) { - grunt.initConfig({ - "markdownlint": { - "example": { - "src": [ "*.md" ] - } - } - }); - - grunt.registerMultiTask("markdownlint", function task() { - const done = this.async(); - import("markdownlint/async").then(({ lint }) => { - lint( - { "files": this.filesSrc }, - function callback(err, result) { - const resultString = err || ((result || "").toString()); - if (resultString) { - grunt.fail.warn("\n" + resultString + "\n"); - } - done(!err || !resultString); - }); - }).catch(done); - }); -}; diff --git a/example/gulpfile.cjs b/example/gulpfile.cjs deleted file mode 100644 index 25dcdd58..00000000 --- a/example/gulpfile.cjs +++ /dev/null @@ -1,24 +0,0 @@ -// @ts-check - -"use strict"; - -const gulp = require("gulp"); -const through2 = require("through2"); - -// Simple task wrapper -gulp.task("markdownlint", function task() { - return gulp.src("*.md", { "read": false }) - .pipe(through2.obj(function obj(file, enc, next) { - import("markdownlint/async").then(({ lint }) => { - lint( - { "files": [ file.relative ] }, - function callback(err, result) { - const resultString = (result || "").toString(); - if (resultString) { - console.log(resultString); - } - next(err, file); - }); - }).catch(next); - })); -}); diff --git a/example/standalone.mjs b/example/standalone.mjs index 2614e14b..866d0a8b 100644 --- a/example/standalone.mjs +++ b/example/standalone.mjs @@ -18,18 +18,18 @@ const options = { if (true) { - // Makes a synchronous call, uses result.toString for pretty formatting + // Makes a synchronous call const results = lintSync(options); - console.log(results.toString()); + console.dir(results, { "colors": true, "depth": null }); } if (true) { - // Makes an asynchronous call, uses result.toString for pretty formatting + // Makes an asynchronous call lintAsync(options, function callback(error, results) { if (!error && results) { - console.log(results.toString()); + console.dir(results, { "colors": true, "depth": null }); } }); @@ -37,7 +37,7 @@ if (true) { if (true) { - // Makes a Promise-based asynchronous call, displays the result object directly + // Makes a Promise-based asynchronous call const results = await lintPromise(options); console.dir(results, { "colors": true, "depth": null }); diff --git a/example/typescript/type-check.ts b/example/typescript/type-check.ts index 5abc47f0..4bc3e04c 100644 --- a/example/typescript/type-check.ts +++ b/example/typescript/type-check.ts @@ -171,13 +171,15 @@ lintAsync(options, assertLintResultsCallback); assertLintResultsCallback(null, await lintPromise(options)); })(); +const needsFixing = "# Heading\n"; + assert.equal( applyFix( - "# Fixing\n", + needsFixing, { - "insertText": "Head", - "editColumn": 3, - "deleteCount": 3 + "insertText": " ", + "editColumn": 2, + "deleteCount": 2 }, "\n" ), @@ -186,17 +188,12 @@ assert.equal( assert.equal( applyFixes( - "# Fixing\n", - [ - { - "lineNumber": 1, - "fixInfo": { - "insertText": "Head", - "editColumn": 3, - "deleteCount": 3 - } + needsFixing, + lintSync({ + "strings": { + needsFixing } - ] + })["needsFixing"] ), "# Heading\n" ); diff --git a/helpers/helpers.cjs b/helpers/helpers.cjs index 97e97f7f..20875652 100644 --- a/helpers/helpers.cjs +++ b/helpers/helpers.cjs @@ -554,6 +554,7 @@ function convertLintErrorsVersion3To2(errors) { "lineNumber": -1 }; return errors.filter((error, index, array) => { + // @ts-ignore delete error.fixInfo; const previous = array[index - 1] || noPrevious; return ( @@ -646,3 +647,31 @@ module.exports.convertToResultVersion1 = function convertToResultVersion1(result module.exports.convertToResultVersion2 = function convertToResultVersion2(results) { return copyAndTransformResults(results, convertLintErrorsVersion3To2); }; + +/** + * Formats lint results to an array of strings. + * + * @param {LintResults|undefined} lintResults Lint results. + * @returns {string[]} Lint error strings. + */ +module.exports.formatLintResults = function formatLintResults(lintResults) { + const results = []; + const entries = Object.entries(lintResults || {}); + entries.sort((a, b) => a[0].localeCompare(b[0])); + for (const [ source, lintErrors ] of entries) { + for (const lintError of lintErrors) { + results.push( + source + ": " + + lintError.lineNumber + ": " + + lintError.ruleNames.join("/") + " " + + lintError.ruleDescription + + (lintError.errorDetail ? + " [" + lintError.errorDetail + "]" : + "") + + (lintError.errorContext ? + " [Context: \"" + lintError.errorContext + "\"]" : + "")); + } + } + return results; +}; diff --git a/lib/exports.d.mts b/lib/exports.d.mts index 7d9639af..64f50b53 100644 --- a/lib/exports.d.mts +++ b/lib/exports.d.mts @@ -3,6 +3,7 @@ export type Configuration = import("./markdownlint.mjs").Configuration; export type ConfigurationParser = import("./markdownlint.mjs").ConfigurationParser; export type ConfigurationStrict = import("./markdownlint.mjs").ConfigurationStrict; export type FixInfo = import("./markdownlint.mjs").FixInfo; +export type FixInfoNormalized = import("./markdownlint.mjs").FixInfoNormalized; export type LintCallback = import("./markdownlint.mjs").LintCallback; export type LintContentCallback = import("./markdownlint.mjs").LintContentCallback; export type LintError = import("./markdownlint.mjs").LintError; @@ -23,8 +24,6 @@ export type RuleConfiguration = import("./markdownlint.mjs").RuleConfiguration; export type RuleFunction = import("./markdownlint.mjs").RuleFunction; export type RuleOnError = import("./markdownlint.mjs").RuleOnError; export type RuleOnErrorFixInfo = import("./markdownlint.mjs").RuleOnErrorFixInfo; -export type RuleOnErrorFixInfoNormalized = import("./markdownlint.mjs").RuleOnErrorFixInfoNormalized; export type RuleOnErrorInfo = import("./markdownlint.mjs").RuleOnErrorInfo; export type RuleParams = import("./markdownlint.mjs").RuleParams; -export type ToStringCallback = import("./markdownlint.mjs").ToStringCallback; export { applyFix, applyFixes, getVersion } from "./markdownlint.mjs"; diff --git a/lib/exports.mjs b/lib/exports.mjs index dc0d137d..b27030d4 100644 --- a/lib/exports.mjs +++ b/lib/exports.mjs @@ -7,6 +7,7 @@ export { resolveModule } from "./resolve-module.cjs"; /** @typedef {import("./markdownlint.mjs").ConfigurationParser} ConfigurationParser */ /** @typedef {import("./markdownlint.mjs").ConfigurationStrict} ConfigurationStrict */ /** @typedef {import("./markdownlint.mjs").FixInfo} FixInfo */ +/** @typedef {import("./markdownlint.mjs").FixInfoNormalized} FixInfoNormalized */ /** @typedef {import("./markdownlint.mjs").LintCallback} LintCallback */ /** @typedef {import("./markdownlint.mjs").LintContentCallback} LintContentCallback */ /** @typedef {import("./markdownlint.mjs").LintError} LintError */ @@ -27,7 +28,5 @@ export { resolveModule } from "./resolve-module.cjs"; /** @typedef {import("./markdownlint.mjs").RuleFunction} RuleFunction */ /** @typedef {import("./markdownlint.mjs").RuleOnError} RuleOnError */ /** @typedef {import("./markdownlint.mjs").RuleOnErrorFixInfo} RuleOnErrorFixInfo */ -/** @typedef {import("./markdownlint.mjs").RuleOnErrorFixInfoNormalized} RuleOnErrorFixInfoNormalized */ /** @typedef {import("./markdownlint.mjs").RuleOnErrorInfo} RuleOnErrorInfo */ /** @typedef {import("./markdownlint.mjs").RuleParams} RuleParams */ -/** @typedef {import("./markdownlint.mjs").ToStringCallback} ToStringCallback */ diff --git a/lib/markdownlint.d.mts b/lib/markdownlint.d.mts index 331262e9..98550b53 100644 --- a/lib/markdownlint.d.mts +++ b/lib/markdownlint.d.mts @@ -63,19 +63,19 @@ export function readConfigSync(file: string, parsers?: ConfigurationParser[], fs * Applies the specified fix to a Markdown content line. * * @param {string} line Line of Markdown content. - * @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance. + * @param {FixInfo} fixInfo FixInfo instance. * @param {string} [lineEnding] Line ending to use. * @returns {string | null} Fixed content or null if deleted. */ -export function applyFix(line: string, fixInfo: RuleOnErrorFixInfo, lineEnding?: string): string | null; +export function applyFix(line: string, fixInfo: FixInfo, lineEnding?: string): string | null; /** * Applies as many of the specified fixes as possible to Markdown content. * * @param {string} input Lines of Markdown content. - * @param {RuleOnErrorInfo[]} errors RuleOnErrorInfo instances. + * @param {LintError[]} errors LintError instances. * @returns {string} Fixed content. */ -export function applyFixes(input: string, errors: RuleOnErrorInfo[]): string; +export function applyFixes(input: string, errors: LintError[]): string; /** * Gets the (semantic) version of the library. * @@ -320,27 +320,6 @@ export type RuleOnErrorFixInfo = { */ insertText?: string; }; -/** - * RuleOnErrorInfo with all optional properties present. - */ -export type RuleOnErrorFixInfoNormalized = { - /** - * Line number (1-based). - */ - lineNumber: number; - /** - * Column of the fix (1-based). - */ - editColumn: number; - /** - * Count of characters to delete. - */ - deleteCount: number; - /** - * Text to insert (after deleting). - */ - insertText: string; -}; /** * Rule definition. */ @@ -442,10 +421,6 @@ export type Options = { * A markdown-it plugin. */ export type Plugin = any[]; -/** - * Function to pretty-print lint results. - */ -export type ToStringCallback = (ruleAliases?: boolean) => string; /** * Lint results. */ @@ -483,11 +458,11 @@ export type LintError = { /** * Column number (1-based) and length. */ - errorRange: number[]; + errorRange: number[] | null; /** * Fix information. */ - fixInfo?: FixInfo; + fixInfo: FixInfo | null; }; /** * Fix information. @@ -510,6 +485,27 @@ export type FixInfo = { */ insertText?: string; }; +/** + * FixInfo with all optional properties present. + */ +export type FixInfoNormalized = { + /** + * Line number (1-based). + */ + lineNumber: number; + /** + * Column of the fix (1-based). + */ + editColumn: number; + /** + * Count of characters to delete. + */ + deleteCount: number; + /** + * Text to insert (after deleting). + */ + insertText: string; +}; /** * Called with the result of linting a string or document. */ diff --git a/lib/markdownlint.mjs b/lib/markdownlint.mjs index b3d8f25f..73194b20 100644 --- a/lib/markdownlint.mjs +++ b/lib/markdownlint.mjs @@ -522,6 +522,7 @@ function lintContent( "config": null }); // Function to run for each rule + /** @type {LintError[]} */ const results = []; /** * @param {Rule} rule Rule. @@ -1194,9 +1195,9 @@ export function readConfigSync(file, parsers, fs) { /** * Normalizes the fields of a RuleOnErrorFixInfo instance. * - * @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance. + * @param {FixInfo} fixInfo RuleOnErrorFixInfo instance. * @param {number} [lineNumber] Line number. - * @returns {RuleOnErrorFixInfoNormalized} Normalized RuleOnErrorFixInfo instance. + * @returns {FixInfoNormalized} Normalized RuleOnErrorFixInfo instance. */ function normalizeFixInfo(fixInfo, lineNumber = 0) { return { @@ -1211,7 +1212,7 @@ function normalizeFixInfo(fixInfo, lineNumber = 0) { * Applies the specified fix to a Markdown content line. * * @param {string} line Line of Markdown content. - * @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance. + * @param {FixInfo} fixInfo FixInfo instance. * @param {string} [lineEnding] Line ending to use. * @returns {string | null} Fixed content or null if deleted. */ @@ -1227,7 +1228,7 @@ export function applyFix(line, fixInfo, lineEnding = "\n") { * Applies as many of the specified fixes as possible to Markdown content. * * @param {string} input Lines of Markdown content. - * @param {RuleOnErrorInfo[]} errors RuleOnErrorInfo instances. + * @param {LintError[]} errors LintError instances. * @returns {string} Fixed content. */ export function applyFixes(input, errors) { @@ -1424,16 +1425,6 @@ export function getVersion() { * @property {string} [insertText] Text to insert (after deleting). */ -/** - * RuleOnErrorInfo with all optional properties present. - * - * @typedef {Object} RuleOnErrorFixInfoNormalized - * @property {number} lineNumber Line number (1-based). - * @property {number} editColumn Column of the fix (1-based). - * @property {number} deleteCount Count of characters to delete. - * @property {string} insertText Text to insert (after deleting). - */ - /** * Rule definition. * @@ -1492,19 +1483,10 @@ export function getVersion() { * @typedef {Array} Plugin */ -/** - * Function to pretty-print lint results. - * - * @callback ToStringCallback - * @param {boolean} [ruleAliases] True to use rule aliases. - * @returns {string} Pretty-printed results. - */ - /** * Lint results. * * @typedef {Object.} LintResults - * @property {ToStringCallback} toString String representation. */ /** @@ -1517,8 +1499,8 @@ export function getVersion() { * @property {string} ruleInformation Link to more information. * @property {string} errorDetail Detail about the error. * @property {string} errorContext Context for the error. - * @property {number[]} errorRange Column number (1-based) and length. - * @property {FixInfo} [fixInfo] Fix information. + * @property {number[]|null} errorRange Column number (1-based) and length. + * @property {FixInfo|null} fixInfo Fix information. */ /** @@ -1531,6 +1513,16 @@ export function getVersion() { * @property {string} [insertText] Text to insert (after deleting). */ +/** + * FixInfo with all optional properties present. + * + * @typedef {Object} FixInfoNormalized + * @property {number} lineNumber Line number (1-based). + * @property {number} editColumn Column of the fix (1-based). + * @property {number} deleteCount Count of characters to delete. + * @property {string} insertText Text to insert (after deleting). + */ + /** * Called with the result of linting a string or document. * diff --git a/package.json b/package.json index bea19cdf..7bb06b08 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "build-declaration": "tsc --allowJs --checkJs --declaration --emitDeclarationOnly --module nodenext --outDir dts --rootDir . --target es2015 lib/exports.mjs lib/exports-async.mjs lib/exports-promise.mjs lib/exports-sync.mjs lib/markdownlint.mjs lib/resolve-module.cjs && node scripts/index.mjs copy dts/lib/exports.d.mts lib/exports.d.mts && node scripts/index.mjs copy dts/lib/exports-async.d.mts lib/exports-async.d.mts && node scripts/index.mjs copy dts/lib/exports-promise.d.mts lib/exports-promise.d.mts && node scripts/index.mjs copy dts/lib/exports-sync.d.mts lib/exports-sync.d.mts && node scripts/index.mjs copy dts/lib/markdownlint.d.mts lib/markdownlint.d.mts && node scripts/index.mjs copy dts/lib/resolve-module.d.cts lib/resolve-module.d.cts && node scripts/index.mjs remove dts", "build-demo": "node scripts/index.mjs copy node_modules/markdown-it/dist/markdown-it.min.js demo/markdown-it.min.js && cd demo && webpack --no-stats", "build-docs": "node doc-build/build-rules.mjs", - "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", "ci": "npm-run-all --continue-on-error --parallel build-demo lint serial-config-docs serial-declaration test-cover && git diff --exit-code", "clone-test-repos-apache-airflow": "cd test-repos && git clone https://github.com/apache/airflow apache-airflow --depth 1 --no-tags --quiet", "clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet", @@ -54,7 +53,7 @@ "clone-test-repos-webpack-webpack-js-org": "cd test-repos && git clone https://github.com/webpack/webpack.js.org webpack-webpack-js-org --depth 1 --no-tags --quiet", "clone-test-repos": "mkdir test-repos && cd test-repos && npm run clone-test-repos-apache-airflow && npm run clone-test-repos-dotnet-docs && npm run clone-test-repos-electron-electron && npm run clone-test-repos-eslint-eslint && npm run clone-test-repos-mdn-content && npm run clone-test-repos-mkdocs-mkdocs && npm run clone-test-repos-mochajs-mocha && npm run clone-test-repos-pi-hole-docs && npm run clone-test-repos-v8-v8-dev && npm run clone-test-repos-webhintio-hint && npm run clone-test-repos-webpack-webpack-js-org", "declaration": "npm run build-declaration && npm run test-declaration", - "example": "cd example && node standalone.mjs && grunt markdownlint --force && gulp markdownlint", + "example": "cd example && node standalone.mjs", "lint": "eslint --max-warnings 0", "lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos-*.mjs", "serial-config-docs": "npm run build-config && npm run build-docs", diff --git a/test/markdownlint-test-helpers.mjs b/test/markdownlint-test-helpers.mjs index 64ff908f..3b6fe392 100644 --- a/test/markdownlint-test-helpers.mjs +++ b/test/markdownlint-test-helpers.mjs @@ -5,7 +5,7 @@ import path from "node:path"; import test from "ava"; import { characterEntities } from "character-entities"; import { gemoji } from "gemoji"; -import helpers from "../helpers/helpers.cjs"; +import helpers, { formatLintResults } from "../helpers/helpers.cjs"; import { lint } from "markdownlint/promise"; import { forEachInlineCodeSpan } from "../lib/markdownit.cjs"; import { getReferenceLinkImageData } from "../lib/cache.mjs"; @@ -529,3 +529,17 @@ test("hasOverlap", (t) => { t.false(helpers.hasOverlap(rangeB, rangeA), JSON.stringify({ rangeB, rangeA })); } }); + +test("formatLintResults", async(t) => { + t.plan(2); + t.deepEqual(formatLintResults(undefined), []); + const lintResults = await lint({ "strings": { "content": "# Heading
" } }); + t.deepEqual( + formatLintResults(lintResults), + [ + "content: 1: MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: \"# Heading
\"]", + "content: 1: MD033/no-inline-html Inline HTML [Element: br]", + "content: 1: MD047/single-trailing-newline Files should end with a single newline character" + ] + ); +}); diff --git a/test/markdownlint-test-repos.mjs b/test/markdownlint-test-repos.mjs index d9b691ce..317835ca 100644 --- a/test/markdownlint-test-repos.mjs +++ b/test/markdownlint-test-repos.mjs @@ -5,6 +5,7 @@ const { join } = path.posix; import { globby } from "globby"; import jsoncParser from "jsonc-parser"; import jsYaml from "js-yaml"; +import { formatLintResults } from "markdownlint/helpers"; import { lint, readConfig } from "markdownlint/promise"; import { markdownlintParallel } from "./markdownlint-test-parallel.mjs"; @@ -49,9 +50,8 @@ export function lintTestRepo(t, globPatterns, configPath, configOverrides, paral files, config }).then((results) => { - const resultsString = results.toString(); t.snapshot( - resultsString, + formatLintResults(results).join("\n"), "Expected linting violations" ); }); diff --git a/test/markdownlint-test.mjs b/test/markdownlint-test.mjs index 06318fce..7345fab5 100644 --- a/test/markdownlint-test.mjs +++ b/test/markdownlint-test.mjs @@ -49,46 +49,42 @@ function getMarkdownItFactory(markdownItPlugins) { } test("simpleAsync", (t) => new Promise((resolve) => { + t.plan(3); + const options = { + "strings": { + "content": "# Heading" + } + }; + lintAsync(options, (err, actual) => { + t.falsy(err); + t.is(actual?.content.length, 1); + t.is(actual?.content[0].ruleNames[0], "MD047"); + resolve(); + }); +})); + +test("simpleSync", (t) => { t.plan(2); const options = { "strings": { "content": "# Heading" } }; - const expected = "content: 1: MD047/single-trailing-newline " + - "Files should end with a single newline character"; - lintAsync(options, (err, actual) => { - t.falsy(err); - // @ts-ignore - t.is(actual.toString(), expected, "Unexpected results."); - resolve(); - }); -})); - -test("simpleSync", (t) => { - t.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 = lintSync(options).toString(); - t.is(actual, expected, "Unexpected results."); + const actual = lintSync(options); + t.is(actual.content.length, 1); + t.is(actual.content[0].ruleNames[0], "MD047"); }); test("simplePromise", (t) => { - t.plan(1); + t.plan(2); const options = { "strings": { "content": "# Heading" } }; - const expected = "content: 1: MD047/single-trailing-newline " + - "Files should end with a single newline character"; return lintPromise(options).then((actual) => { - t.is(actual.toString(), expected, "Unexpected results."); + t.is(actual.content.length, 1); + t.is(actual.content[0].ruleNames[0], "MD047"); }); }); @@ -1281,7 +1277,7 @@ test("token-map-spans", (t) => { }); test("configParsersInvalid", async(t) => { - t.plan(1); + t.plan(2); const options = { "strings": { "content": [ @@ -1294,10 +1290,9 @@ test("configParsersInvalid", async(t) => { ].join("\n") } }; - const expected = "content: 1: MD041/first-line-heading/first-line-h1 " + - "First line in a file should be a top-level heading [Context: \"Text\"]"; const actual = await lintPromise(options); - t.is(actual.toString(), expected, "Unexpected results."); + t.is(actual.content.length, 1); + t.is(actual.content[0].ruleNames[0], "MD041"); }); test("configParsersJSON", async(t) => { @@ -1317,7 +1312,7 @@ test("configParsersJSON", async(t) => { } }; const actual = await lintPromise(options); - t.is(actual.toString(), "", "Unexpected results."); + t.is(actual.content.length, 0); }); test("configParsersJSONC", async(t) => { @@ -1339,7 +1334,7 @@ test("configParsersJSONC", async(t) => { "configParsers": [ jsoncParser.parse ] }; const actual = await lintPromise(options); - t.is(actual.toString(), "", "Unexpected results."); + t.is(actual.content.length, 0); }); test("configParsersYAML", async(t) => { @@ -1360,7 +1355,7 @@ test("configParsersYAML", async(t) => { }; // @ts-ignore const actual = await lintPromise(options); - t.is(actual.toString(), "", "Unexpected results."); + t.is(actual.content.length, 0); }); test("configParsersTOML", async(t) => { @@ -1382,7 +1377,7 @@ test("configParsersTOML", async(t) => { ] }; const actual = await lintPromise(options); - t.is(actual.toString(), "", "Unexpected results."); + t.is(actual.content.length, 0); }); test("getVersion", (t) => { diff --git a/test/snapshots/markdownlint-test-exports.mjs.md b/test/snapshots/markdownlint-test-exports.mjs.md index f03e1f08..a29305c2 100644 --- a/test/snapshots/markdownlint-test-exports.mjs.md +++ b/test/snapshots/markdownlint-test-exports.mjs.md @@ -37,6 +37,7 @@ Generated by [AVA](https://avajs.dev). 'endOfLineHtmlEntityRe', 'escapeForRegExp', 'expandTildePath', + 'formatLintResults', 'frontMatterHasTitle', 'frontMatterRe', 'getHtmlAttributeRe', diff --git a/test/snapshots/markdownlint-test-exports.mjs.snap b/test/snapshots/markdownlint-test-exports.mjs.snap index bf686f39..124c0ee3 100644 Binary files a/test/snapshots/markdownlint-test-exports.mjs.snap and b/test/snapshots/markdownlint-test-exports.mjs.snap differ diff --git a/test/snapshots/markdownlint-test-repos-small.mjs.md b/test/snapshots/markdownlint-test-repos-small.mjs.md index a9bd13be..6c922cfb 100644 --- a/test/snapshots/markdownlint-test-repos-small.mjs.md +++ b/test/snapshots/markdownlint-test-repos-small.mjs.md @@ -320,9 +320,6 @@ Generated by [AVA](https://avajs.dev). `test-repos/mochajs-mocha/.github/CODE_OF_CONDUCT.md: 63: MD034/no-bare-urls Bare URL used [Context: "report@lists.openjsf.org"]␊ test-repos/mochajs-mocha/.github/CONTRIBUTING.md: 42: MD051/link-fragments Link fragments should be valid [Context: "[⚽️ About Project Goals](#⚽️-about-project-goals)"]␊ - test-repos/mochajs-mocha/PROJECT_CHARTER.md: 51: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊ - test-repos/mochajs-mocha/PROJECT_CHARTER.md: 56: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊ - test-repos/mochajs-mocha/README.md: 39: MD045/no-alt-text Images should have alternate text (alt text)␊ test-repos/mochajs-mocha/docs/changelogs/CHANGELOG_V3_older.md: 207: MD059/descriptive-link-text Link text should be descriptive [Context: "[more]"]␊ test-repos/mochajs-mocha/docs/index.md: 34: MD051/link-fragments Link fragments should be valid [Context: "[global variable leak detection](#-check-leaks)"]␊ test-repos/mochajs-mocha/docs/index.md: 35: MD051/link-fragments Link fragments should be valid [Context: "[optionally run tests that match a regexp](#-grep-regexp-g-regexp)"]␊ @@ -350,7 +347,10 @@ Generated by [AVA](https://avajs.dev). test-repos/mochajs-mocha/docs/index.md: 2432: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "caniuse-promises"] [Context: "[caniuse-promises]: https://ca..."]␊ test-repos/mochajs-mocha/docs/index.md: 2463: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "mocha-website"] [Context: "[mocha-website]: https://mocha..."]␊ test-repos/mochajs-mocha/docs/index.md: 2230: MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"]␊ - test-repos/mochajs-mocha/docs/index.md: 2302: MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"]` + test-repos/mochajs-mocha/docs/index.md: 2302: MD059/descriptive-link-text Link text should be descriptive [Context: "[here]"]␊ + test-repos/mochajs-mocha/PROJECT_CHARTER.md: 51: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊ + test-repos/mochajs-mocha/PROJECT_CHARTER.md: 56: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊ + test-repos/mochajs-mocha/README.md: 39: MD045/no-alt-text Images should have alternate text (alt text)` ## https://github.com/pi-hole/docs @@ -738,12 +738,12 @@ Generated by [AVA](https://avajs.dev). `test-repos/webhintio-hint/packages/hint-apple-touch-icons/README.md: 198: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "icon scaling"] [Context: "[icon scaling]: https://realfa..."]␊ test-repos/webhintio-hint/packages/hint-apple-touch-icons/README.md: 202: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "web app manifest spec"] [Context: "[web app manifest spec]: https..."]␊ test-repos/webhintio-hint/packages/hint-axe/README.md: 170: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "axe rules"] [Context: "[axe rules]: https://github.co..."]␊ - test-repos/webhintio-hint/packages/hint-compat-api/README.md: 48: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "npm docs"] [Context: "[npm docs]: https://docs.npmjs..."]␊ test-repos/webhintio-hint/packages/hint-compat-api/docs/html.md: 153: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "global-attr"] [Context: "[global-attr]: https://develop..."]␊ - test-repos/webhintio-hint/packages/hint-detect-css-reflows/README.md: 96: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "understanding-critical-path"] [Context: "[understanding-critical-path]:..."]␊ + test-repos/webhintio-hint/packages/hint-compat-api/README.md: 48: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "npm docs"] [Context: "[npm docs]: https://docs.npmjs..."]␊ test-repos/webhintio-hint/packages/hint-detect-css-reflows/docs/composite.md: 73: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "understanding-critical-path"] [Context: "[understanding-critical-path]:..."]␊ test-repos/webhintio-hint/packages/hint-detect-css-reflows/docs/layout.md: 73: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "understanding-critical-path"] [Context: "[understanding-critical-path]:..."]␊ test-repos/webhintio-hint/packages/hint-detect-css-reflows/docs/paint.md: 73: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "understanding-critical-path"] [Context: "[understanding-critical-path]:..."]␊ + test-repos/webhintio-hint/packages/hint-detect-css-reflows/README.md: 96: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "understanding-critical-path"] [Context: "[understanding-critical-path]:..."]␊ test-repos/webhintio-hint/packages/hint-doctype/README.md: 130: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "npm docs"] [Context: "[npm docs]: https://docs.npmjs..."]␊ test-repos/webhintio-hint/packages/hint-highest-available-document-mode/README.md: 420: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "mod_mime"] [Context: "[mod_mime]: https://httpd.apac..."]␊ test-repos/webhintio-hint/packages/hint-http-compression/README.md: 1087: MD053/link-image-reference-definitions Link and image reference definitions should be needed [Unused link or image reference definition: "gzip is not enough"] [Context: "[gzip is not enough]: https://..."]␊ diff --git a/test/snapshots/markdownlint-test-repos-small.mjs.snap b/test/snapshots/markdownlint-test-repos-small.mjs.snap index 8938e353..366a45c6 100644 Binary files a/test/snapshots/markdownlint-test-repos-small.mjs.snap and b/test/snapshots/markdownlint-test-repos-small.mjs.snap differ