diff --git a/src/services/ghost/strategies/CommentHelpers.ts b/src/services/ghost/strategies/CommentHelpers.ts index 0f961f2476c..9abd6d77aaa 100644 --- a/src/services/ghost/strategies/CommentHelpers.ts +++ b/src/services/ghost/strategies/CommentHelpers.ts @@ -6,8 +6,19 @@ import { TextDocument } from "vscode" export function isCommentLine(line: string, languageId: string): boolean { const trimmed = line.trim() - // Common single-line comment patterns - const singleLinePatterns = [ + const patterns = [ + // Structural patterns + /^\/\*$/, // C-style block start + /^\s*$/, "") // --> - .trim() + + // Remove trailing comment syntax and everything after the last occurrence + const lastCommentEnd = cleaned.lastIndexOf("*/") + if (lastCommentEnd !== -1) { + cleaned = cleaned.substring(0, lastCommentEnd).trim() + } + + const lastHtmlCommentEnd = cleaned.lastIndexOf("-->") + if (lastHtmlCommentEnd !== -1) { + cleaned = cleaned.substring(0, lastHtmlCommentEnd).trim() + } + + return cleaned.trim() }) return cleaned.filter((line) => line.length > 0).join("\n") diff --git a/src/services/ghost/strategies/__tests__/CommentHelpers.test.ts b/src/services/ghost/strategies/__tests__/CommentHelpers.test.ts new file mode 100644 index 00000000000..f0ab1d45569 --- /dev/null +++ b/src/services/ghost/strategies/__tests__/CommentHelpers.test.ts @@ -0,0 +1,325 @@ +import * as vscode from "vscode" +import { isCommentLine, extractComment, cleanComment } from "../CommentHelpers" +import { MockTextDocument } from "../../../mocking/MockTextDocument" + +describe("CommentHelpers", () => { + describe("isCommentLine", () => { + describe("empty and whitespace-only comments", () => { + test("should reject single-line comment with only syntax", () => { + expect(isCommentLine("//", "javascript")).toBe(false) + }) + + test("should reject single-line comment with only whitespace", () => { + expect(isCommentLine("// ", "javascript")).toBe(false) + expect(isCommentLine("# ", "python")).toBe(false) + }) + + test("should reject structural multi-line comment markers without content", () => { + expect(isCommentLine("/*", "javascript")).toBe(false) + expect(isCommentLine("", "html")).toBe("comment") + }) + + test("should clean full HTML comment", () => { + expect(cleanComment("", "html")).toBe("comment") + }) + }) + + describe("SQL comments", () => { + test("should clean SQL line comment", () => { + expect(cleanComment("-- comment", "sql")).toBe("comment") + }) + }) + + describe("edge cases", () => { + test("should handle empty lines in multi-line comment", () => { + const comment = "// line 1\n//\n// line 3" + const expected = "line 1\nline 3" + expect(cleanComment(comment, "javascript")).toBe(expected) + }) + + test("should handle mixed comment styles", () => { + const comment = "// line 1\n# line 2\n* line 3" + const expected = "line 1\nline 2\nline 3" + expect(cleanComment(comment, "javascript")).toBe(expected) + }) + + test("should preserve inner content with comment-like characters", () => { + expect(cleanComment("// x = y // z", "javascript")).toBe("x = y // z") + }) + + test("should handle comment with only whitespace after prefix", () => { + expect(cleanComment("// ", "javascript")).toBe("") + }) + + test("should handle comment with multiple spaces after prefix", () => { + expect(cleanComment("// comment", "javascript")).toBe("comment") + }) + + test("should remove trailing block comment end and text after it", () => { + expect(cleanComment("/* start */ middle */ end", "javascript")).toBe("start */ middle") + }) + }) + }) +})