diff --git a/internal/check/substitution.go b/internal/check/substitution.go index c31d6491..2b6a2f3b 100644 --- a/internal/check/substitution.go +++ b/internal/check/substitution.go @@ -66,8 +66,7 @@ func NewSubstitution(cfg *core.Config, generic baseCheck, path string) (Substitu replacement := rule.Swap[regexstr] opens := strings.Count(regexstr, "(") - if opens != strings.Count(regexstr, "(?") && - opens != strings.Count(regexstr, `\(`) { + if opens != strings.Count(regexstr, "(?")+strings.Count(regexstr, `\(`) { // We rely on manually-added capture groups to associate a match // with its replacement -- e.g., // diff --git a/internal/check/substitution_test.go b/internal/check/substitution_test.go index a6ed1d77..1231f6ec 100644 --- a/internal/check/substitution_test.go +++ b/internal/check/substitution_test.go @@ -54,3 +54,63 @@ func TestIsDeterministic(t *testing.T) { } } } + +func TestRegex(t *testing.T) { + swap := map[string]interface{}{ + "extends": "substitution", + "name": "Vale.Terms", + "level": "error", + "message": "Use '%s' instead of '%s'.", + "scope": "text", + "ignorecase": true, + "swap": map[string]string{ + `(?:foo|bar)`: "sub", + }, + } + text := "foo" + rule, err := makeSubstitution(swap) + if err != nil { + t.Fatal(err) + } + + actual, err := rule.Run(nlp.NewBlock(text, text, "text"), &core.File{}) + if err != nil { + t.Fatal(err) + } + + expected := "Use 'sub' instead of 'foo'." + message := actual[0].Message + if message != expected { + t.Fatalf("Expected message `%s`, got `%s`", expected, message) + } +} + +func TestRegexEscapedParens(t *testing.T) { + swap := map[string]interface{}{ + "extends": "substitution", + "name": "Vale.Terms", + "level": "error", + "message": "Use '%s' instead of '%s'.", + "scope": "text", + "ignorecase": true, + "swap": map[string]string{ + `(?!\()(?:foo|bar)(?!\))?`: "sub", + }, + } + text := "(foo)" + rule, err := makeSubstitution(swap) + if err != nil { + t.Fatal(err) + } + + actual, err := rule.Run(nlp.NewBlock(text, text, "text"), &core.File{}) + if err != nil { + t.Fatal(err) + } + + expected := "Use 'sub' instead of 'foo'." + message := actual[0].Message + if message != expected { + t.Fatalf("Expected message `%s`, got `%s`", expected, message) + } +}