yyqdbngt opened a new pull request, #5330:
URL: https://github.com/apache/rocketmq-dashboard/pull/5330

   ### Which Issue(s) This PR Fixes
   
   - Fixes #5093
   
   ### Brief Description
   
   `normalizeAiMarkdown` (`web/src/pages/ai/render/markdown.ts`) prepares every 
assistant text block for
   `react-markdown` (`blocks/TextBlock.tsx:46`, live and replayed alike) and 
its docstring states the
   contract it has to keep: *"purely textual and idempotent: well-formed input 
comes back unchanged"*.
   Three regexes broke it:
   
   1. `/^(#{1,6})(?=\S)/` is greedy and anchored at the line start, so when the 
full marker run is
      followed by a space the engine backtracks to a shorter run that does 
satisfy `(?=\S)`: `## 概述`
      became `# # 概述`, an `h1` whose text starts with a literal `#` — every 
heading of level 2+ was
      demoted and gained a stray hash.
   2. `/^([-+*])(?=\S)/` cannot tell a list bullet from a `*`/`**` delimiter, a 
`---` rule or a signed
      number, so `**加粗**`, `*斜体*`, `---` and `-1` were all reinterpreted as 
list items.
   3. Both passes ran over the raw text, so the same markers inside a fenced 
code block were rewritten —
      a `diff` block lost its `-`/`+` markers, and the code shown was no longer 
the code returned.
   
   The repairs are now written as narrowly as the promise: the heading rule 
keeps the whole marker run
   (`/^(#{1,6})(?=[^\s#])/`, so `## 概述` and `#######` are untouched), the 
bullet rule fires only on a
   line that really opens a list (`opensAsList`: not `**`/`---`, not `-1`/`+2`, 
not `*斜体*`), and the
   function walks the text line by line, skipping everything between fence 
lines. The three repairs the
   function exists for — `##结论` → `## 结论`, `-第一项` → `- 第一项`, ` ```bashls -la ` →
   ` ```bash ` + newline — still happen, and a fence line whose info string ran 
into its command still
   opens the fence before the walk, so the command is treated as code.
   
   The new test file `web/src/pages/ai/render/__tests__/markdown.test.ts` pins 
both halves of the
   contract: every repair, and every well-formed form the old code corrupted.
   
   ### How Did You Test This Change?
   
   Red — the new test file, written and run first, with `markdown.ts` still 
unmodified:
   
   ```
   $ cd web && npx vitest run src/pages/ai/render/__tests__/markdown.test.ts
    ❯ src/pages/ai/render/__tests__/markdown.test.ts (13 tests | 9 failed) 47ms
        ✓ separates a heading marker that runs into its text 6ms
        × leaves a well-formed heading at its own level 15ms
        × leaves a run of seven hashes alone 5ms
        × leaves strong emphasis alone 1ms
        × leaves emphasis alone 1ms
        × leaves a thematic break alone 2ms
        × leaves a signed number at the start of a line alone 3ms
        ✓ separates a list bullet that runs into its text 1ms
        ✓ leaves an already separated list alone 1ms
        ✓ terminates a fence info string that runs into the command 1ms
        × leaves fenced code content alone 2ms
        × repairs markers outside a fence while the fence keeps its content 1ms
        × is idempotent 2ms
   ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
    FAIL  src/pages/ai/render/__tests__/markdown.test.ts > normalizeAiMarkdown 
> leaves a well-formed heading at its own level
   AssertionError: expected '# # 概述\n正文' to be '## 概述\n正文' // Object.is equality
   
   - Expected
   + Received
   
   - ## 概述
   + # # 概述
     正文
   
    ❯ src/pages/ai/render/__tests__/markdown.test.ts:35:46
   
    Test Files  1 failed (1)
         Tests  9 failed | 4 passed (13)
   ```
   
   Green — the same file after the fix, and the whole AI page suite (the render 
path is shared, so this
   also covers `AssistantBubble`/`TextBlock`):
   
   ```
   $ cd web && npx vitest run src/pages/ai/render/__tests__/markdown.test.ts
    Test Files  1 passed (1)
         Tests  13 passed (13)
   
   $ cd web && npx vitest run src/pages/ai
    Test Files  18 passed (18)
         Tests  207 passed (207)
   ```
   
   Also run for the two touched files: `npx tsc -b` (exit 0) and
   `npx eslint src/pages/ai/render/markdown.ts 
src/pages/ai/render/__tests__/markdown.test.ts` (exit 0).
   
   ### Checklist
   
   - [x] One coherent change; unrelated modifications are not bundled in
   - [x] Commit subject follows Conventional Commits
   - [x] Tests added or updated for non-trivial changes
   - [x] New UI text has both Chinese and English entries under `web/src/i18n/` 
— not applicable: no
         user-facing string is added.
   - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit 
checks) — not applicable:
         the change is web-only and touches no Java module.
   - [x] New source files carry the ASF license header — 
`__tests__/markdown.test.ts` carries it.
   - [x] Documentation touched where behaviour changed (README / `docs/` / 
in-app help) — not
         applicable: the module docstring is updated in place, and no 
user-facing contract changed.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to