From 6704cf6db13d28b123e61eb6f5b700165bb2a222 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Mon, 19 Jan 2026 01:20:36 +0100 Subject: [PATCH] Linter: Catch `<%# locals:() %>` in `erb-strict-locals-comment-syntax` --- .../rules/erb-strict-locals-comment-syntax.ts | 11 ++++++++++- .../erb-strict-locals-comment-syntax.test.ts | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/javascript/packages/linter/src/rules/erb-strict-locals-comment-syntax.ts b/javascript/packages/linter/src/rules/erb-strict-locals-comment-syntax.ts index c0137735..798e9282 100644 --- a/javascript/packages/linter/src/rules/erb-strict-locals-comment-syntax.ts +++ b/javascript/packages/linter/src/rules/erb-strict-locals-comment-syntax.ts @@ -7,7 +7,7 @@ import { hasBalancedParentheses, splitByTopLevelComma } from "./string-utils.js" import type { UnboundLintOffense, LintContext, FullRuleConfig } from "../types.js" import type { ParseResult, ERBContentNode } from "@herb-tools/core" -export const STRICT_LOCALS_PATTERN = /^locals:\s*\([^)]*\)\s*$/ +export const STRICT_LOCALS_PATTERN = /^locals:\s+\([^)]*\)\s*$/ function isValidStrictLocalsFormat(content: string): boolean { return STRICT_LOCALS_PATTERN.test(content) @@ -49,6 +49,10 @@ function detectMissingColonBeforeParens(content: string): boolean { return /^locals\s+\(/.test(content) } +function detectMissingSpaceAfterColon(content: string): boolean { + return /^locals:\(/.test(content) +} + function detectMissingParentheses(content: string): boolean { return /^locals:\s*[^(]/.test(content) } @@ -240,6 +244,11 @@ class ERBStrictLocalsCommentSyntaxVisitor extends BaseRuleVisitor { return } + if (detectMissingSpaceAfterColon(commentContent)) { + this.addOffense("Missing space after `locals:`. Rails Strict Locals require a space after the colon: `<%# locals: (...) %>`.", node.location) + return + } + if (detectMissingParentheses(commentContent)) { this.addOffense("Wrap parameters in parentheses: `locals: (name:)` or `locals: (name: default)`.", node.location) return diff --git a/javascript/packages/linter/test/rules/erb-strict-locals-comment-syntax.test.ts b/javascript/packages/linter/test/rules/erb-strict-locals-comment-syntax.test.ts index 66d8174b..177bccef 100644 --- a/javascript/packages/linter/test/rules/erb-strict-locals-comment-syntax.test.ts +++ b/javascript/packages/linter/test/rules/erb-strict-locals-comment-syntax.test.ts @@ -72,6 +72,22 @@ describe("ERBStrictLocalsCommentSyntaxRule", () => { `) }) + test("flags missing space after colon", () => { + expectError("Missing space after `locals:`. Rails Strict Locals require a space after the colon: `<%# locals: (...) %>`.") + + assertOffenses(dedent` + <%# locals:() %> + `) + }) + + test("flags missing space after colon with locals", () => { + expectError("Missing space after `locals:`. Rails Strict Locals require a space after the colon: `<%# locals: (...) %>`.") + + assertOffenses(dedent` + <%# locals:(title:) %> + `) + }) + test("flags missing parentheses around parameters", () => { expectError("Wrap parameters in parentheses: `locals: (name:)` or `locals: (name: default)`.")