test: pin multiple code spans with link-like content (#818) (#1042)
Investigated #818 (two backtick-wrapped domains render as one code
span covering "the text between the links", not each span on its
own). Reproduced against the current parser: parseMessage already
returns the correct tree — two separate `code` nodes ("example.com",
"other.com") with the " and " text run between them staying plain,
neither domain autolinking. No web bug found.
The timeline explains why: #818 was filed 2026-07-13, one day before
PR #873 (2026-07-14) replaced the hand-rolled regex-based renderer
with a real, vendored CommonMark parser (markdown-it) specifically to
fix this class of bug — greedy first-backtick-to-last-backtick
matching is a classic hand-rolled-regex failure mode that a
spec-compliant tokenizer doesn't have. #873 already fixed this; #818
just predates it and was never verified/closed.
No production code changed — adds the missing regression-lock vector
(both the canonical file and the byte-identical iOS fixture copy the
existing test enforces) so this can't silently regress. Native uses
its own spec-compliant parser (apple/swift-markdown, same allowlist)
so it's very likely already correct too, for the same reason — but
that's inferred from the parser choice, not verified by running the
Swift suite here; the new vector will exercise it on the next iOS
test run regardless.
Addresses #818
Co-authored-by: Claude <noreply@anthropic.com>
2 files changed,
+66
−0
ios/LChatCore/Tests/LChatCoreTests/Fixtures/markdown-vector.json+33 −0test/event-vectors/markdown.json+33 −0
diff --git a/ios/LChatCore/Tests/LChatCoreTests/Fixtures/markdown-vector.json b/ios/LChatCore/Tests/LChatCoreTests/Fixtures/markdown-vector.json| index 00cf9e7..a417b0d 100644 |
| --- a/ios/LChatCore/Tests/LChatCoreTests/Fixtures/markdown-vector.json |
| +++ b/ios/LChatCore/Tests/LChatCoreTests/Fixtures/markdown-vector.json |
| @@ -232,6 +232,39 @@ |
| } |
| ] |
| }, |
| + { |
| + "name": "multiple_code_spans_with_link_like_content", |
| + "input": "hello `example.com` and `other.com` OK?", |
| + "plain": "hello example.com and other.com OK?", |
| + "tree": [ |
| + { |
| + "t": "p", |
| + "children": [ |
| + { |
| + "t": "text", |
| + "text": "hello " |
| + }, |
| + { |
| + "t": "code", |
| + "text": "example.com" |
| + }, |
| + { |
| + "t": "text", |
| + "text": " and " |
| + }, |
| + { |
| + "t": "code", |
| + "text": "other.com" |
| + }, |
| + { |
| + "t": "text", |
| + "text": " OK?" |
| + } |
| + ] |
| + } |
| + ], |
| + "note": "issue #818: two SEPARATE code spans, each ending at its own nearest closing backtick — not one span greedily spanning first-backtick to last-backtick. Neither domain-looking span autolinks; code content never re-parses." |
| + }, |
| { |
| "name": "strike_single_tilde", |
| "input": "~s~", |
diff --git a/test/event-vectors/markdown.json b/test/event-vectors/markdown.json| index 00cf9e7..a417b0d 100644 |
| --- a/test/event-vectors/markdown.json |
| +++ b/test/event-vectors/markdown.json |
| @@ -232,6 +232,39 @@ |
| } |
| ] |
| }, |
| + { |
| + "name": "multiple_code_spans_with_link_like_content", |
| + "input": "hello `example.com` and `other.com` OK?", |
| + "plain": "hello example.com and other.com OK?", |
| + "tree": [ |
| + { |
| + "t": "p", |
| + "children": [ |
| + { |
| + "t": "text", |
| + "text": "hello " |
| + }, |
| + { |
| + "t": "code", |
| + "text": "example.com" |
| + }, |
| + { |
| + "t": "text", |
| + "text": " and " |
| + }, |
| + { |
| + "t": "code", |
| + "text": "other.com" |
| + }, |
| + { |
| + "t": "text", |
| + "text": " OK?" |
| + } |
| + ] |
| + } |
| + ], |
| + "note": "issue #818: two SEPARATE code spans, each ending at its own nearest closing backtick — not one span greedily spanning first-backtick to last-backtick. Neither domain-looking span autolinks; code content never re-parses." |
| + }, |
| { |
| "name": "strike_single_tilde", |
| "input": "~s~", |