diff --git a/test/markdownlint-test-custom-rules.js b/test/markdownlint-test-custom-rules.js index 59e68a18..cf0310cb 100644 --- a/test/markdownlint-test-custom-rules.js +++ b/test/markdownlint-test-custom-rules.js @@ -1143,6 +1143,32 @@ test.cb("customRulesLintJavaScript", (t) => { }); }); +test.cb("customRulesValidateJson", (t) => { + t.plan(2); + const options = { + "customRules": customRules.validateJson, + "files": "test/validate-json.md" + }; + markdownlint(options, (err, actual) => { + t.falsy(err); + const expected = { + "test/validate-json.md": [ + { + "lineNumber": 22, + "ruleNames": [ "validate-json" ], + "ruleDescription": "Rule that validates JSON code", + "ruleInformation": null, + "errorDetail": "Unexpected end of JSON input", + "errorContext": null, + "errorRange": null + } + ] + }; + t.deepEqual(actual, expected, "Unexpected issues."); + t.end(); + }); +}); + test("customRulesAsyncThrowsInSyncContext", (t) => { t.plan(1); const options = { diff --git a/test/markdownlint-test.js b/test/markdownlint-test.js index 45227323..392ebfba 100644 --- a/test/markdownlint-test.js +++ b/test/markdownlint-test.js @@ -1109,7 +1109,7 @@ test("allBuiltInRulesHaveValidUrl", (t) => { }); test("someCustomRulesHaveValidUrl", (t) => { - t.plan(7); + t.plan(8); customRules.all.forEach(function forRule(rule) { t.true(!rule.information || (Object.getPrototypeOf(rule.information) === URL.prototype)); diff --git a/test/rules/rules.js b/test/rules/rules.js index bd080d90..ee16c96e 100644 --- a/test/rules/rules.js +++ b/test/rules/rules.js @@ -17,10 +17,14 @@ module.exports.lettersEX = lettersEX; const lintJavaScript = require("./lint-javascript"); module.exports.lintJavaScript = lintJavaScript; +const validateJson = require("./validate-json"); +module.exports.validateJson = validateJson; + module.exports.all = [ anyBlockquote, everyNLines, firstLine, lettersEX, - lintJavaScript + lintJavaScript, + validateJson ]; diff --git a/test/rules/validate-json.js b/test/rules/validate-json.js new file mode 100644 index 00000000..cfbbcc97 --- /dev/null +++ b/test/rules/validate-json.js @@ -0,0 +1,28 @@ +// @ts-check + +"use strict"; + +const { filterTokens } = require("markdownlint-rule-helpers"); + +module.exports = { + "names": [ "validate-json" ], + "description": "Rule that validates JSON code", + "tags": [ "test", "validate", "json" ], + "asynchronous": true, + "function": async(params, onError) => { + // eslint-disable-next-line max-len, node/no-unsupported-features/es-syntax + const { "default": stripJsonComments } = await import("strip-json-comments"); + filterTokens(params, "fence", (fence) => { + if (/jsonc?/i.test(fence.info)) { + try { + JSON.parse(stripJsonComments(fence.content)); + } catch (error) { + onError({ + "lineNumber": fence.lineNumber, + "detail": error.message + }); + } + } + }); + } +}; diff --git a/test/validate-json.md b/test/validate-json.md new file mode 100644 index 00000000..9af3531a --- /dev/null +++ b/test/validate-json.md @@ -0,0 +1,27 @@ +# Validate JSON + +Text + +```json +{ + "property": "value" +} +``` + +Text + +```jsonc +{ + // Comment + "property": "value" +} +``` + +Text + +```json +{ + "property": "value" +``` + +Text