diff --git a/lib/rules/multiline-comment-style.js b/lib/rules/multiline-comment-style.js index 6578a120126..fb50e1522ea 100644 --- a/lib/rules/multiline-comment-style.js +++ b/lib/rules/multiline-comment-style.js @@ -43,17 +43,150 @@ module.exports = { //---------------------------------------------------------------------- /** - * Gets a list of comment lines in a group - * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment - * @returns {string[]} A list of comment lines + * Checks if a comment line is starred. + * @param {string} line A string representing a comment line. + * @returns {boolean} Whether or not the comment line is starred. + */ + function isStarredCommentLine(line) { + return /^\s*\*/u.test(line); + } + + /** + * Checks if a comment group is in starred-block form. + * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. + * @returns {boolean} Whether or not the comment group is in starred block form. + */ + function isStarredBlockComment([firstComment]) { + if (firstComment.type !== "Block") { + return false; + } + + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + + // The first and last lines can only contain whitespace. + return lines.length > 0 && lines.every((line, i) => (i === 0 || i === lines.length - 1 ? /^\s*$/u : /^\s*\*/u).test(line)); + } + + /** + * Checks if a comment group is in JSDoc form. + * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. + * @returns {boolean} Whether or not the comment group is in JSDoc form. + */ + function isJSDocComment([firstComment]) { + if (firstComment.type !== "Block") { + return false; + } + + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + + return /^\*\s*$/u.test(lines[0]) && + lines.slice(1, -1).every(line => /^\s* /u.test(line)) && + /^\s*$/u.test(lines[lines.length - 1]); + } + + /** + * Processes a comment group that is currently in separate-line form, calculating the offset for each line. + * @param {Token[]} commentGroup A group of comments containing multiple line comments. + * @returns {string[]} An array of the processed lines. + */ + function processSeparateLineComments(commentGroup) { + const allLinesHaveLeadingSpace = commentGroup + .map(({ value }) => value) + .filter(line => line.trim().length) + .every(line => line.startsWith(" ")); + + return commentGroup.map(({ value }) => (allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value)); + } + + /** + * Processes a comment group that is currently in starred-block form, calculating the offset for each line. + * @param {Token} comment A single block comment token in starred-block form. + * @returns {string[]} An array of the processed lines. + */ + function processStarredBlockComment(comment) { + const lines = comment.value.split(astUtils.LINEBREAK_MATCHER) + .filter((line, i, linesArr) => !(i === 0 || i === linesArr.length - 1)) + .map(line => line.replace(/^\s*$/u, "")); + const allLinesHaveLeadingSpace = lines + .map(line => line.replace(/\s*\*/u, "")) + .filter(line => line.trim().length) + .every(line => line.startsWith(" ")); + + return lines.map(line => line.replace(allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u, "")); + } + + /** + * Processes a comment group that is currently in bare-block form, calculating the offset for each line. + * @param {Token} comment A single block comment token in bare-block form. + * @returns {string[]} An array of the processed lines. + */ + function processBareBlockComment(comment) { + const lines = comment.value.split(astUtils.LINEBREAK_MATCHER).map(line => line.replace(/^\s*$/u, "")); + const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])} `; + let offset = ""; + + /* + * Calculate the offset of the least indented line and use that as the basis for offsetting all the lines. + * The first line should not be checked because it is inline with the opening block comment delimiter. + */ + for (const [i, line] of lines.entries()) { + if (!line.trim().length || i === 0) { + continue; + } + + const [, lineOffset] = line.match(/^(\s*\*?\s*)/u); + + if (lineOffset.length < leadingWhitespace.length) { + const newOffset = leadingWhitespace.slice(lineOffset.length - leadingWhitespace.length); + + if (newOffset.length > offset.length) { + offset = newOffset; + } + } + } + + return lines.map(line => { + const match = line.match(/^(\s*\*?\s*)(.*)/u); + const [, lineOffset, lineContents] = match; + + if (lineOffset.length > leadingWhitespace.length) { + return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`; + } + + if (lineOffset.length < leadingWhitespace.length) { + return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`; + } + + return lineContents; + }); + } + + /** + * Gets a list of comment lines in a group, formatting leading whitespace as necessary. + * @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment. + * @returns {string[]} A list of comment lines. */ function getCommentLines(commentGroup) { - if (commentGroup[0].type === "Line") { - return commentGroup.map(comment => comment.value); + const [firstComment] = commentGroup; + + if (firstComment.type === "Line") { + return processSeparateLineComments(commentGroup); } - return commentGroup[0].value - .split(astUtils.LINEBREAK_MATCHER) - .map(line => line.replace(/^\s*\*?/u, "")); + + if (isStarredBlockComment(commentGroup)) { + return processStarredBlockComment(firstComment); + } + + return processBareBlockComment(firstComment); + } + + /** + * Gets the initial offset (whitespace) from the beginning of a line to a given comment token. + * @param {Token} comment The token to check. + * @returns {string} The offset from the beginning of a line to the token. + */ + function getInitialOffset(comment) { + return sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0]); } /** @@ -63,10 +196,9 @@ module.exports = { * @returns {string} A representation of the comment value in starred-block form, excluding start and end markers */ function convertToStarredBlock(firstComment, commentLinesList) { - const initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); - const starredLines = commentLinesList.map(line => `${initialOffset} *${line}`); + const initialOffset = getInitialOffset(firstComment); - return `\n${starredLines.join("\n")}\n${initialOffset} `; + return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`; } /** @@ -76,10 +208,7 @@ module.exports = { * @returns {string} A representation of the comment value in separate-line form */ function convertToSeparateLines(firstComment, commentLinesList) { - const initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); - const separateLines = commentLinesList.map(line => `// ${line.trim()}`); - - return separateLines.join(`\n${initialOffset}`); + return commentLinesList.map(line => `// ${line}`).join(`\n${getInitialOffset(firstComment)}`); } /** @@ -89,24 +218,7 @@ module.exports = { * @returns {string} A representation of the comment value in bare-block form */ function convertToBlock(firstComment, commentLinesList) { - const initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); - const blockLines = commentLinesList.map(line => line.trim()); - - return `/* ${blockLines.join(`\n${initialOffset} `)} */`; - } - - /** - * Check a comment is JSDoc form - * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment - * @returns {boolean} if commentGroup is JSDoc form, return true - */ - function isJSDoc(commentGroup) { - const lines = commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER); - - return commentGroup[0].type === "Block" && - /^\*\s*$/u.test(lines[0]) && - lines.slice(1, -1).every(line => /^\s* /u.test(line)) && - /^\s*$/u.test(lines[lines.length - 1]); + return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)} `)} */`; } /** @@ -117,6 +229,7 @@ module.exports = { */ const commentGroupCheckers = { "starred-block"(commentGroup) { + const [firstComment] = commentGroup; const commentLines = getCommentLines(commentGroup); if (commentLines.some(value => value.includes("*/"))) { @@ -126,31 +239,30 @@ module.exports = { if (commentGroup.length > 1) { context.report({ loc: { - start: commentGroup[0].loc.start, + start: firstComment.loc.start, end: commentGroup[commentGroup.length - 1].loc.end }, messageId: "expectedBlock", fix(fixer) { - const range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]]; - const starredBlock = `/*${convertToStarredBlock(commentGroup[0], commentLines)}*/`; + const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]]; return commentLines.some(value => value.startsWith("/")) ? null - : fixer.replaceTextRange(range, starredBlock); + : fixer.replaceTextRange(range, convertToStarredBlock(firstComment, commentLines)); } }); } else { - const block = commentGroup[0]; - const lines = block.value.split(astUtils.LINEBREAK_MATCHER); - const expectedLinePrefix = `${sourceCode.text.slice(block.range[0] - block.loc.start.column, block.range[0])} *`; + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + const expectedLeadingWhitespace = getInitialOffset(firstComment); + const expectedLinePrefix = `${expectedLeadingWhitespace} *`; if (!/^\*?\s*$/u.test(lines[0])) { - const start = block.value.startsWith("*") ? block.range[0] + 1 : block.range[0]; + const start = firstComment.value.startsWith("*") ? firstComment.range[0] + 1 : firstComment.range[0]; context.report({ loc: { - start: block.loc.start, - end: { line: block.loc.start.line, column: block.loc.start.column + 2 } + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } }, messageId: "startNewline", fix: fixer => fixer.insertTextAfterRange([start, start + 2], `\n${expectedLinePrefix}`) @@ -160,36 +272,54 @@ module.exports = { if (!/^\s*$/u.test(lines[lines.length - 1])) { context.report({ loc: { - start: { line: block.loc.end.line, column: block.loc.end.column - 2 }, - end: block.loc.end + start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 }, + end: firstComment.loc.end }, messageId: "endNewline", - fix: fixer => fixer.replaceTextRange([block.range[1] - 2, block.range[1]], `\n${expectedLinePrefix}/`) + fix: fixer => fixer.replaceTextRange([firstComment.range[1] - 2, firstComment.range[1]], `\n${expectedLinePrefix}/`) }); } - for (let lineNumber = block.loc.start.line + 1; lineNumber <= block.loc.end.line; lineNumber++) { + for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) { const lineText = sourceCode.lines[lineNumber - 1]; + const errorType = isStarredCommentLine(lineText) + ? "alignment" + : "missingStar"; if (!lineText.startsWith(expectedLinePrefix)) { context.report({ loc: { start: { line: lineNumber, column: 0 }, - end: { line: lineNumber, column: sourceCode.lines[lineNumber - 1].length } + end: { line: lineNumber, column: lineText.length } }, - messageId: /^\s*\*/u.test(lineText) - ? "alignment" - : "missingStar", + messageId: errorType, fix(fixer) { const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 }); - const linePrefixLength = lineText.match(/^\s*\*? ?/u)[0].length; - const commentStartIndex = lineStartIndex + linePrefixLength; - const replacementText = lineNumber === block.loc.end.line || lineText.length === linePrefixLength - ? expectedLinePrefix - : `${expectedLinePrefix} `; + if (errorType === "alignment") { + const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || []; + const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; + + return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix); + } + + const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || []; + const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; + let offset; + + for (const [idx, line] of lines.entries()) { + if (!/\S+/u.test(line)) { + continue; + } + + const lineTextToAlignWith = sourceCode.lines[firstComment.loc.start.line - 1 + idx]; + const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || []; - return fixer.replaceTextRange([lineStartIndex, commentStartIndex], replacementText); + offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`; + break; + } + + return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`); } }); } @@ -197,67 +327,68 @@ module.exports = { } }, "separate-lines"(commentGroup) { - if (!isJSDoc(commentGroup) && commentGroup[0].type === "Block") { - const commentLines = getCommentLines(commentGroup); - const block = commentGroup[0]; - const tokenAfter = sourceCode.getTokenAfter(block, { includeComments: true }); + const [firstComment] = commentGroup; + + if (firstComment.type !== "Block" || isJSDocComment(commentGroup)) { + return; + } - if (tokenAfter && block.loc.end.line === tokenAfter.loc.start.line) { - return; + const commentLines = getCommentLines(commentGroup); + const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true }); + + if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) { + return; + } + + context.report({ + loc: { + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } + }, + messageId: "expectedLines", + fix(fixer) { + return fixer.replaceText(firstComment, convertToSeparateLines(firstComment, commentLines)); } + }); + }, + "bare-block"(commentGroup) { + if (isJSDocComment(commentGroup)) { + return; + } + const [firstComment] = commentGroup; + const commentLines = getCommentLines(commentGroup); + + // Disallows consecutive line comments in favor of using a block comment. + if (firstComment.type === "Line" && commentLines.length > 1 && + !commentLines.some(value => value.includes("*/"))) { context.report({ loc: { - start: block.loc.start, - end: { line: block.loc.start.line, column: block.loc.start.column + 2 } + start: firstComment.loc.start, + end: commentGroup[commentGroup.length - 1].loc.end }, - messageId: "expectedLines", + messageId: "expectedBlock", fix(fixer) { - return fixer.replaceText(block, convertToSeparateLines(block, commentLines.filter(line => line))); + return fixer.replaceTextRange( + [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]], + convertToBlock(firstComment, commentLines) + ); } }); } - }, - "bare-block"(commentGroup) { - if (!isJSDoc(commentGroup)) { - const commentLines = getCommentLines(commentGroup); - - // disallows consecutive line comments in favor of using a block comment. - if (commentGroup[0].type === "Line" && commentLines.length > 1 && - !commentLines.some(value => value.includes("*/"))) { - context.report({ - loc: { - start: commentGroup[0].loc.start, - end: commentGroup[commentGroup.length - 1].loc.end - }, - messageId: "expectedBlock", - fix(fixer) { - const range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]]; - const block = convertToBlock(commentGroup[0], commentLines.filter(line => line)); - - return fixer.replaceTextRange(range, block); - } - }); - } - // prohibits block comments from having a * at the beginning of each line. - if (commentGroup[0].type === "Block") { - const block = commentGroup[0]; - const lines = block.value.split(astUtils.LINEBREAK_MATCHER).filter(line => line.trim()); - - if (lines.length > 0 && lines.every(line => /^\s*\*/u.test(line))) { - context.report({ - loc: { - start: block.loc.start, - end: { line: block.loc.start.line, column: block.loc.start.column + 2 } - }, - messageId: "expectedBareBlock", - fix(fixer) { - return fixer.replaceText(block, convertToBlock(block, commentLines.filter(line => line))); - } - }); + // Prohibits block comments from having a * at the beginning of each line. + if (isStarredBlockComment(commentGroup)) { + context.report({ + loc: { + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } + }, + messageId: "expectedBareBlock", + fix(fixer) { + return fixer.replaceText(firstComment, convertToBlock(firstComment, commentLines)); } - } + }); } } }; diff --git a/tests/lib/rules/multiline-comment-style.js b/tests/lib/rules/multiline-comment-style.js index 58c13581d4d..c69265ba9e2 100644 --- a/tests/lib/rules/multiline-comment-style.js +++ b/tests/lib/rules/multiline-comment-style.js @@ -130,6 +130,50 @@ ruleTester.run("multiline-comment-style", rule, { `, options: ["starred-block"] }, + { + code: ` + /* + * foo + */ + `, + options: ["starred-block"] + }, + { + code: ` + /* foo */ + `, + options: ["bare-block"] + }, + { + code: ` + /* + foo */ + `, + options: ["bare-block"] + }, + { + code: ` + /* + foo + */ + `, + options: ["bare-block"] + }, + { + code: ` + /* + foo */ + `, + options: ["bare-block"] + }, + { + code: ` + /* + foo + */ + `, + options: ["bare-block"] + }, { code: ` // this is @@ -230,6 +274,60 @@ ruleTester.run("multiline-comment-style", rule, { * 4 is 20. */ `, options: ["bare-block"] + }, + { + code: ` + /* + * foo + * bar + * baz + * qux + */ + `, + options: ["starred-block"] + }, + { + code: ` + /* foo + * bar + * baz + * qux + */ + `, + options: ["bare-block"] + }, + { + code: ` + /** + * JSDoc blocks + * are + * ignored + * ! + */ + `, + options: ["bare-block"] + }, + { + code: ` + /** + * JSDoc blocks + * are + * ignored + * ! + */ + `, + options: ["starred-block"] + }, + { + code: ` + /** + * JSDoc blocks + * are + * ignored + * ! + */ + `, + options: ["separate-lines"] } ], @@ -276,6 +374,57 @@ ruleTester.run("multiline-comment-style", rule, { `, errors: [{ messageId: "expectedBlock", line: 2 }, { messageId: "expectedBlock", line: 5 }] }, + { + code: ` + // foo + // bar + // baz + // qux + `, + output: ` + /* + * foo + * bar + * baz + * qux + */ + `, + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // + // baz + // qux + `, + output: ` + /* + * foo + *${" "} + * baz + * qux + */ + `, + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // bar + // baz + // qux + `, + output: ` + /* + * foo + * bar + * baz + * qux + */ + `, + errors: [{ messageId: "expectedBlock", line: 2 }] + }, { code: ` /* this block @@ -318,6 +467,21 @@ ruleTester.run("multiline-comment-style", rule, { `, errors: [{ messageId: "endNewline", line: 4 }] }, + { + code: ` + /* + * the following line + is missing a '*' at the start + */ + `, + output: ` + /* + * the following line + * is missing a '*' at the start + */ + `, + errors: [{ messageId: "missingStar", line: 4 }] + }, { code: ` /* @@ -333,6 +497,21 @@ ruleTester.run("multiline-comment-style", rule, { `, errors: [{ messageId: "missingStar", line: 4 }] }, + { + code: ` + /* + * the following line + is missing a '*' at the start + */ + `, + output: ` + /* + * the following line + * is missing a '*' at the start + */ + `, + errors: [{ messageId: "missingStar", line: 4 }] + }, { code: ` /* @@ -469,6 +648,72 @@ ruleTester.run("multiline-comment-style", rule, { options: ["bare-block"], errors: [{ messageId: "expectedBlock", line: 2 }] }, + { + code: ` + // foo + // + // bar + `, + output: ` + /* foo + ${" ".repeat(3)} + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + //foo + //bar + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // bar + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // bar + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // bar + // baz + // qux + `, + output: ` + /* foo + bar + baz + qux */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, { code: ` /* @@ -482,6 +727,658 @@ ruleTester.run("multiline-comment-style", rule, { `, options: ["bare-block"], errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + *foo + *bar + */ + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + * foo + * bar + */ + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + * foo + * bar + */ + `, + output: ` + /* foo + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + * foo + * bar + * baz + * qux + */ + `, + output: ` + /* foo + bar + baz + qux */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + { + "foo": 1, + "bar": 2 + } + */ + `, + output: ` + /* + *{ + * "foo": 1, + * "bar": 2 + *} + */ + `, + errors: [ + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "missingStar", line: 5 }, + { messageId: "missingStar", line: 6 }, + { messageId: "alignment", line: 7 } + ] + }, + { + code: ` + /* + { + \t"foo": 1, + \t"bar": 2 + } + */ + `, + output: ` + /* + *{ + *\t"foo": 1, + *\t"bar": 2 + *} + */ + `, + errors: [ + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "missingStar", line: 5 }, + { messageId: "missingStar", line: 6 }, + { messageId: "alignment", line: 7 } + ] + }, + { + code: ` + /* + { + \t "foo": 1, + \t "bar": 2 + } + */ + `, + output: ` + /* + *{ + *\t "foo": 1, + *\t "bar": 2 + *} + */ + `, + errors: [ + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "missingStar", line: 5 }, + { messageId: "missingStar", line: 6 }, + { messageId: "alignment", line: 7 } + ] + }, + { + code: ` + /* + { + \t"foo": 1, + \t"bar": 2 + } + */ + `, + output: ` + /* + *{ + *"foo": 1, + *"bar": 2 + *} + */ + `, + errors: [ + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "missingStar", line: 5 }, + { messageId: "missingStar", line: 6 }, + { messageId: "alignment", line: 7 } + ] + }, + { + code: ` + \t /* + \t { + \t "foo": 1, + \t "bar": 2 + } + */ + `, + output: ` + \t /* + \t *{ + \t *"foo": 1, + \t *"bar": 2 + \t *} + \t */ + `, + errors: [ + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "missingStar", line: 5 }, + { messageId: "missingStar", line: 6 }, + { messageId: "alignment", line: 7 } + ] + }, + { + code: ` + //{ + // "foo": 1, + // "bar": 2 + //} + `, + output: ` + /* + * { + * "foo": 1, + * "bar": 2 + * } + */ + `, + errors: [ + { messageId: "expectedBlock", line: 2 } + ] + }, + { + code: ` + /* + * { + * "foo": 1, + * "bar": 2 + * } + */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // } + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + * + * { + * "foo": 1, + * "bar": 2 + * } + * + */ + `, + output: ` + //${" "} + // { + // "foo": 1, + // "bar": 2 + // } + //${" "} + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + * + * { + * "foo": 1, + * "bar": 2 + * } + * + */ + `, + output: ` + /*${" "} + { + "foo": 1, + "bar": 2 + } + */ + `, + options: ["bare-block"], + errors: [ + { messageId: "expectedBareBlock", line: 2 } + ] + }, + { + code: ` + /* + * + *{ + * "foo": 1, + * "bar": 2 + *} + * + */ + `, + output: ` + /*${" "} + { + "foo": 1, + "bar": 2 + } + */ + `, + options: ["bare-block"], + errors: [ + { messageId: "expectedBareBlock", line: 2 } + ] + }, + { + code: ` + /* + *{ + * "foo": 1, + * "bar": 2 + *} + */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // } + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + * { + * "foo": 1, + * "bar": 2 + * } + */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // } + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + *{ + * "foo": 1, + * "bar": 2 + *} + */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // } + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + * { + * "foo": 1, + * "bar": 2 + *} + */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // } + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + { + "foo": 1, + "bar": 2 + } + */ + `, + output: ` + //${" "} + // { + // "foo": 1, + // "bar": 2 + // } + //${" "} + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* { + "foo": 1, + "bar": 2 + } */ + `, + output: ` + // { + // "foo": 1, + // "bar": 2 + // }${" "} + `, + options: ["separate-lines"], + errors: [ + { messageId: "expectedLines", line: 2 } + ] + }, + { + code: ` + /* + * foo + * + * bar + */ + `, + output: ` + // foo + //${" "} + // bar + `, + options: ["separate-lines"], + errors: [{ messageId: "expectedLines", line: 2 }] + }, + { + code: ` + /* + * foo + *${" "} + * bar + */ + `, + output: ` + // foo + //${" "} + // bar + `, + options: ["separate-lines"], + errors: [{ messageId: "expectedLines", line: 2 }] + }, + { + code: ` + /* + * foo + * + * bar + */ + `, + output: ` + /* foo +${" "} + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + /* + * foo + *${" "} + * bar + */ + `, + output: ` + /* foo +${" "} + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBareBlock", line: 2 }] + }, + { + code: ` + // foo + // + // bar + `, + output: ` + /* + * foo + *${" "} + * bar + */ + `, + options: ["starred-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + //${" "} + // bar + `, + output: ` + /* + * foo + *${" "} + * bar + */ + `, + options: ["starred-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + // + // bar + `, + output: ` + /* foo +${" "} + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + // foo + //${" "} + // bar + `, + output: ` + /* foo +${" "} + bar */ + `, + options: ["bare-block"], + errors: [{ messageId: "expectedBlock", line: 2 }] + }, + { + code: ` + /* foo + + bar */ + `, + output: ` + // foo + //${" "} + // bar${" "} + `, + options: ["separate-lines"], + errors: [{ messageid: "expectedlines", line: 2 }] + }, + { + code: ` + /* foo +${" "} + bar */ + `, + output: ` + // foo + //${" "} + // bar${" "} + `, + options: ["separate-lines"], + errors: [{ messageid: "expectedlines", line: 2 }] + }, + { + code: ` + /* foo + + bar */ + `, + output: ` + /* + * foo + *${" "} + * bar${" "} + */ + `, + options: ["starred-block"], + errors: [ + { messageId: "startNewline", line: 2 }, + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "endNewline", line: 4 } + ] + }, + { + code: ` + /* foo +${" "} + bar */ + `, + output: ` + /* + * foo + *${" "} + * bar${" "} + */ + `, + options: ["starred-block"], + errors: [ + { messageId: "startNewline", line: 2 }, + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "endNewline", line: 4 } + ] + }, + { + code: ` + /*foo + + bar */ + `, + output: ` + /* + *foo + * + *bar${" "} + */ + `, + options: ["starred-block"], + errors: [ + { messageId: "startNewline", line: 2 }, + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "endNewline", line: 4 } + ] + }, + { + code: ` + /*foo +${" "} + bar */ + `, + output: ` + /* + *foo + *${" "} + *bar${" "} + */ + `, + options: ["starred-block"], + errors: [ + { messageId: "startNewline", line: 2 }, + { messageId: "missingStar", line: 3 }, + { messageId: "missingStar", line: 4 }, + { messageId: "endNewline", line: 4 } + ] } ] });