Skip to content

fix(parser): respect escape for timestamp syntax#39457

Open
IsseiHasegawa wants to merge 8 commits intoRocketChat:developfrom
IsseiHasegawa:test/message-parser-first-pr
Open

fix(parser): respect escape for timestamp syntax#39457
IsseiHasegawa wants to merge 8 commits intoRocketChat:developfrom
IsseiHasegawa:test/message-parser-first-pr

Conversation

@IsseiHasegawa
Copy link
Copy Markdown

@IsseiHasegawa IsseiHasegawa commented Mar 8, 2026

Summary

Adds a test case to ensure that timestamps with the relative format (R) are correctly parsed when used inside strike formatting.

This extends the existing timestamp test coverage for strike elements.

Testing

  • yarn workspace @rocket.chat/message-parser test tests/timestamp.test.ts

Proposed changes (including videos or screenshots)

Issue(s)

COMM-144

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Preserve escaped timestamp-like sequences as literal text when parsing.
  • Tests

    • Added tests for relative ('R') timestamp formatting within strike text.
    • Introduced fuzz tests to broaden parser input coverage and ensure deterministic parsing.
  • Chores

    • Added development tooling for property-based (fuzz) testing.

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 8, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR has conflicts, please resolve them before merging
  • This PR is missing the 'stat: QA assured' label
  • This PR is not mergeable
  • This PR is targeting the wrong base branch. It should target 8.4.0, but it targets 8.3.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 8, 2026

⚠️ No Changeset found

Latest commit: 7212c3b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 8, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds grammar support for escaped timestamp syntax and integrates it into inline and strikethrough parsing; expands test coverage with fuzz/property-based tests, a strike-format R timestamp case, and an escaped-timestamp literal test. Adds fast-check as a devDependency. No runtime API declarations changed.

Changes

Cohort / File(s) Summary
Grammar
packages/message-parser/src/grammar.pegjs
Adds EscapedTimestampRules; includes it in InlineItemPattern and StrikethroughContent so escaped <t:...> forms are treated as literal text.
Fuzz/property-based tests
packages/message-parser/tests/fuzz.test.ts
Introduces fast-check-based arbitraries for varied inline inputs (plain text, timestamps, relative timestamps, mentions, bold, strike, inline code), composes 1–8 part inputs, and adds tests that parse(input) does not throw and is deterministic.
Timestamp test
packages/message-parser/tests/timestamp.test.ts
Adds a test for ~<t:1708551317:R>~ ensuring a timestamp with R specifier parses inside strikethrough.
Escaped timestamp test
packages/message-parser/tests/escaped.test.ts
Adds a test that \\<t:1708551317:R> parses to the literal text <t:1708551317:R> (escaped angle-brackets preserved).
Package devDependency
packages/message-parser/package.json
Adds fast-check (^4.6.0) to devDependencies for fuzz/property-based tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

type: tests, area: parser

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive COMM-144 is a tracking issue for community PRs in 8.3.0 release, not a requirements issue; the PR's objectives (escaped timestamp handling, timestamp in strike formatting, fuzz testing) are not directly validated against specific coding requirements. Verify that escaped timestamp handling, strike formatting, and fuzz testing objectives align with the 8.3.0 release requirements or clarify if coding-specific requirements exist in linked issues.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly describes the main change: fixing parser to respect escape sequences for timestamp syntax, which is the primary focus of grammar and test changes.
Out of Scope Changes check ✅ Passed All changes are scoped to timestamp parsing: grammar rules for escaped timestamps, tests for strike formatting and fuzz testing, and fast-check dependency—all directly supporting the escape fix objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file


Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
packages/message-parser/tests/fuzz.test.ts (3)

43-49: This property is redundant with the next one.

parse(input) throwing already fails the determinism property on Lines 52-56, so this adds runtime without adding much signal. I’d either drop it or replace it with a stronger structural invariant on the returned AST.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/message-parser/tests/fuzz.test.ts` around lines 43 - 49, The test
named "parses valid parser-like inputs without throwing" is redundant with the
determinism property that already fails if parse(input) throws; remove that test
or replace it with a stronger structural invariant: instead of only asserting no
throw, call parse(input) and assert the returned AST meets expected shape (for
example, non-null object, has expected root type, and required fields like
nodes/children or type tags). Locate the test that uses parserInputArbitrary and
parse and either delete that test block or change its body to validate the
parsed AST structure rather than merely checking for exceptions.

23-23: Cover both strike delimiters here.

The grammar accepts both ~...~ and ~~...~~, but this arbitrary only hits the single-tilde path. A parser bug in the double-tilde branch would slip through this fuzz suite.

Proposed direction
-const strikeArbitrary = fc.oneof(timestampArbitrary, relativeTimestampArbitrary, plainTextArbitrary).map((value) => `~${value}~`);
+const strikeArbitrary = fc
+	.tuple(
+		fc.oneof(timestampArbitrary, relativeTimestampArbitrary, plainTextArbitrary),
+		fc.constantFrom('~', '~~'),
+	)
+	.map(([value, delimiter]) => `${delimiter}${value}${delimiter}`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/message-parser/tests/fuzz.test.ts` at line 23, The strikeArbitrary
currently only generates single-tilde strikes (`~...~`) so add generation for
double-tilde strikes as well: update strikeArbitrary (which composes
timestampArbitrary, relativeTimestampArbitrary, plainTextArbitrary) to randomly
choose between wrapping the inner value with "~" and with "~~" (e.g., use an
extra fc.oneof or fc.constant that yields the delimiter and then map to
`${delim}${value}${delim}`), ensuring both `~...~` and `~~...~~` branches are
covered.

17-19: Tighten the mention generator to match the grammar more closely.

This currently misses legal user-mention forms such as repeated @ prefixes and name:name/name@name, while still allowing punctuation-only cases like @- or @. that are not valid mentions. That makes the "valid parser-like inputs" label a bit misleading and leaves real mention branches under-fuzzed.

Proposed direction
-const mentionArbitrary = fc
-	.stringMatching(/[a-z0-9._-]{1,12}/)
-	.map((value) => `@${value}`);
+const mentionNameArbitrary = fc.oneof(
+	fc.stringMatching(/[A-Za-z0-9][A-Za-z0-9._-]{0,11}/),
+	fc
+		.tuple(
+			fc.stringMatching(/[A-Za-z0-9][A-Za-z0-9._-]{0,5}/),
+			fc.constantFrom(':', '@'),
+			fc.stringMatching(/[A-Za-z0-9][A-Za-z0-9._-]{0,5}/),
+		)
+		.map(([left, separator, right]) => `${left}${separator}${right}`),
+);
+
+const mentionArbitrary = fc
+	.tuple(fc.integer({ min: 1, max: 3 }), mentionNameArbitrary)
+	.map(([prefixCount, value]) => `${'@'.repeat(prefixCount)}${value}`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/message-parser/tests/fuzz.test.ts` around lines 17 - 19, The
mentionArbitrary generator is too permissive and misses valid forms (repeated
leading @ and segment separators) while allowing punctuation-only names; update
the stringMatching regex used by mentionArbitrary to require one or more '@'
prefixes followed by one or more alphanumeric segments separated only by valid
separators (':' or '@' or '.' or '-') where each segment must contain at least
one alphanumeric character and the whole mention stays within the intended
length (e.g., 1–12 chars after prefix); keep the .map((v) => v) wrapper (or
existing map) but replace the current /[a-z0-9._-]{1,12}/ pattern with a
stricter pattern that enforces these segment rules so mentionArbitrary produces
real-world mentions like @@alice, alice:bob, and name@name while rejecting
punctuation-only cases.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/message-parser/tests/fuzz.test.ts`:
- Around line 43-49: The test named "parses valid parser-like inputs without
throwing" is redundant with the determinism property that already fails if
parse(input) throws; remove that test or replace it with a stronger structural
invariant: instead of only asserting no throw, call parse(input) and assert the
returned AST meets expected shape (for example, non-null object, has expected
root type, and required fields like nodes/children or type tags). Locate the
test that uses parserInputArbitrary and parse and either delete that test block
or change its body to validate the parsed AST structure rather than merely
checking for exceptions.
- Line 23: The strikeArbitrary currently only generates single-tilde strikes
(`~...~`) so add generation for double-tilde strikes as well: update
strikeArbitrary (which composes timestampArbitrary, relativeTimestampArbitrary,
plainTextArbitrary) to randomly choose between wrapping the inner value with "~"
and with "~~" (e.g., use an extra fc.oneof or fc.constant that yields the
delimiter and then map to `${delim}${value}${delim}`), ensuring both `~...~` and
`~~...~~` branches are covered.
- Around line 17-19: The mentionArbitrary generator is too permissive and misses
valid forms (repeated leading @ and segment separators) while allowing
punctuation-only names; update the stringMatching regex used by mentionArbitrary
to require one or more '@' prefixes followed by one or more alphanumeric
segments separated only by valid separators (':' or '@' or '.' or '-') where
each segment must contain at least one alphanumeric character and the whole
mention stays within the intended length (e.g., 1–12 chars after prefix); keep
the .map((v) => v) wrapper (or existing map) but replace the current
/[a-z0-9._-]{1,12}/ pattern with a stricter pattern that enforces these segment
rules so mentionArbitrary produces real-world mentions like @@alice, alice:bob,
and name@name while rejecting punctuation-only cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dbca6a66-b988-48f1-8147-f475bdb2d391

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6dff5 and f357ecf.

📒 Files selected for processing (1)
  • packages/message-parser/tests/fuzz.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/message-parser/tests/fuzz.test.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/DateTimeFormats.spec.tsx:20-23
Timestamp: 2026-03-06T18:09:14.766Z
Learning: In the RocketChat/Rocket.Chat gazzodown package (`packages/gazzodown`), tests are intended to run under the UTC timezone, but as of PR `#39397` this is NOT yet explicitly enforced in `jest.config.ts` or the `package.json` test scripts (which just run `jest` without `TZ=UTC`). To make timezone-sensitive snapshot tests reliable across all environments, `TZ=UTC` should be added to the test scripts in `package.json` or to `jest.config.ts` via `testEnvironmentOptions.timezone`. Without explicit UTC enforcement, snapshot tests involving date-fns formatted output or `toLocaleString()` will fail for contributors in non-UTC timezones.
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/RelativeTime.spec.tsx:63-70
Timestamp: 2026-03-06T18:02:11.732Z
Learning: In RocketChat/Rocket.Chat, tests in the `packages/gazzodown` package (and likely the broader test suite) are always expected to run in the UTC timezone. This makes `toLocaleString()` output deterministic, so snapshot tests that include locale/timezone-sensitive content (such as `title` attributes from `toLocaleString()`) are stable and do not need to be replaced with targeted assertions.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • packages/message-parser/tests/fuzz.test.ts
📚 Learning: 2026-03-06T18:09:14.766Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/DateTimeFormats.spec.tsx:20-23
Timestamp: 2026-03-06T18:09:14.766Z
Learning: In the RocketChat/Rocket.Chat gazzodown package (`packages/gazzodown`), tests are intended to run under the UTC timezone, but as of PR `#39397` this is NOT yet explicitly enforced in `jest.config.ts` or the `package.json` test scripts (which just run `jest` without `TZ=UTC`). To make timezone-sensitive snapshot tests reliable across all environments, `TZ=UTC` should be added to the test scripts in `package.json` or to `jest.config.ts` via `testEnvironmentOptions.timezone`. Without explicit UTC enforcement, snapshot tests involving date-fns formatted output or `toLocaleString()` will fail for contributors in non-UTC timezones.

Applied to files:

  • packages/message-parser/tests/fuzz.test.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • packages/message-parser/tests/fuzz.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/message-parser/tests/fuzz.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/message-parser/tests/fuzz.test.ts

@IsseiHasegawa
Copy link
Copy Markdown
Author

I added an additional property-based fuzz test using fast-check.

The generator creates parser-like inputs (timestamps, mentions, bold, strike, inline code, and plain text) and verifies:

  1. Parsing does not throw for valid generated inputs
  2. Parsing is deterministic (same input → same AST)

This helps provide additional safety coverage for future parser changes.

@coderabbitai coderabbitai bot added type: bug and removed community labels Mar 9, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/message-parser/src/grammar.pegjs">

<violation number="1" location="packages/message-parser/src/grammar.pegjs:267">
P2: Escaped timestamp rules normalize the date via timestampFromIsoTime/timestampFromHours, so escaped literals no longer round‑trip to the original text (e.g., ISO input becomes Unix seconds). Escaped output should preserve the raw matched text.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@ggazzo ggazzo added this to the 8.2.0 milestone Mar 9, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/message-parser/src/grammar.pegjs`:
- Around line 266-276: The StrikethroughContent grammar currently references
TimestampRules directly which allows escaped timestamps to bypass strike
parsing; update the StrikethroughContent rule to include EscapedTimestampRules
in the same places where TimestampRules are used (mirror how InlineItemPattern
uses EscapedTimestampRules/TimestampRules) so that sequences like
~~\<t:1708551317:R>~~ are parsed as an escaped timestamp inside a strike; ensure
you replace or augment any direct TimestampRules references in
StrikethroughContent with EscapedTimestampRules (and keep TimestampRules
fallback as needed) to preserve existing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 295c8506-2acf-4c95-9599-4c8b606d7afe

📥 Commits

Reviewing files that changed from the base of the PR and between f357ecf and f9512e1.

📒 Files selected for processing (2)
  • packages/message-parser/src/grammar.pegjs
  • packages/message-parser/tests/escaped.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/message-parser/tests/escaped.test.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/DateTimeFormats.spec.tsx:20-23
Timestamp: 2026-03-06T18:09:17.867Z
Learning: In the RocketChat/Rocket.Chat gazzodown package (`packages/gazzodown`), tests are intended to run under the UTC timezone, but as of PR `#39397` this is NOT yet explicitly enforced in `jest.config.ts` or the `package.json` test scripts (which just run `jest` without `TZ=UTC`). To make timezone-sensitive snapshot tests reliable across all environments, `TZ=UTC` should be added to the test scripts in `package.json` or to `jest.config.ts` via `testEnvironmentOptions.timezone`. Without explicit UTC enforcement, snapshot tests involving date-fns formatted output or `toLocaleString()` will fail for contributors in non-UTC timezones.
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/RelativeTime.spec.tsx:63-70
Timestamp: 2026-03-06T18:02:20.381Z
Learning: In RocketChat/Rocket.Chat, tests in the `packages/gazzodown` package (and likely the broader test suite) are always expected to run in the UTC timezone. This makes `toLocaleString()` output deterministic, so snapshot tests that include locale/timezone-sensitive content (such as `title` attributes from `toLocaleString()`) are stable and do not need to be replaced with targeted assertions.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • packages/message-parser/tests/escaped.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/message-parser/tests/escaped.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/message-parser/tests/escaped.test.ts
🔇 Additional comments (1)
packages/message-parser/tests/escaped.test.ts (1)

18-18: Nice regression case.

This keeps the assertion narrow and directly exercises the new escaped-timestamp inline path.

@IsseiHasegawa
Copy link
Copy Markdown
Author

I found and fixed the escaped timestamp parsing issue.

Previously, an input like \\<t:1708551317:R> was parsed as a plain backslash followed by a TIMESTAMP node. This update treats escaped timestamp syntax as plain text and adds a regression test for it.

I also re-ran the relevant timestamp tests and the full message-parser test suite locally.

@IsseiHasegawa IsseiHasegawa changed the title test: add strike test for relative timestamp format fix(parser): respect escape for timestamp syntax Mar 9, 2026
@IsseiHasegawa
Copy link
Copy Markdown
Author

I updated EscapedTimestampRules to preserve the raw matched timestamp text instead of reconstructing it from normalized values.

I also added EscapedTimestampRules before TimestampRules in StrikethroughContent so escaped timestamps are handled correctly inside strike formatting.

I re-ran the timestamp tests locally and they passed.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/message-parser/src/grammar.pegjs (1)

266-276: Extract the shared timestamp payload grammar.

EscapedTimestampRules now mirrors the same date alternatives and optional-format shape as TimestampRules. It works, but the next timestamp syntax change will need two grammar edits again. Please factor the common payload into a dedicated rule so the escaped and unescaped paths stay in sync.

♻️ Proposed refactor
+TimestampValue = Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp
+
-TimestampRules = "<t:" date:(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ":" format:TimestampType ">" { return timestamp(date, format); } / "<t:" date:(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ">" { return timestamp(date); }
+TimestampRules = "<t:" date:TimestampValue ":" format:TimestampType ">" { return timestamp(date, format); } / "<t:" date:TimestampValue ">" { return timestamp(date); }

 EscapedTimestampRules
-  = "\\" "<t:" rawDate:$(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ":" format:TimestampType ">" {
+  = "\\" "<t:" rawDate:$(TimestampValue) ":" format:TimestampType ">" {
       return plain(`<t:${rawDate}:${format}>`);
     }
-  / "\\" "<t:" rawDate:$(Unixtime / ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) ">" {
+  / "\\" "<t:" rawDate:$(TimestampValue) ">" {
       return plain(`<t:${rawDate}>`);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/message-parser/src/grammar.pegjs` around lines 266 - 276, Create a
shared payload rule (e.g., TimestampPayload or TimestampInner) that encapsulates
the rawDate alternatives (Unixtime / ISO8601Date /
ISO8601DateWithoutMilliseconds / Timestamp) and the optional ":"
format:TimestampType, then replace the duplicated rawDate/format parts in both
EscapedTimestampRules and TimestampRules to call that new rule so both branches
produce the same plain(`<t:${rawDate}>`) / plain(`<t:${rawDate}:${format}>`)
outputs; update InlineItemPattern to continue referencing EscapedTimestampRules
and TimestampRules unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/message-parser/src/grammar.pegjs`:
- Around line 266-276: Create a shared payload rule (e.g., TimestampPayload or
TimestampInner) that encapsulates the rawDate alternatives (Unixtime /
ISO8601Date / ISO8601DateWithoutMilliseconds / Timestamp) and the optional ":"
format:TimestampType, then replace the duplicated rawDate/format parts in both
EscapedTimestampRules and TimestampRules to call that new rule so both branches
produce the same plain(`<t:${rawDate}>`) / plain(`<t:${rawDate}:${format}>`)
outputs; update InlineItemPattern to continue referencing EscapedTimestampRules
and TimestampRules unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb8f87e0-546e-4ce4-92e8-aa0ebf51d576

📥 Commits

Reviewing files that changed from the base of the PR and between f9512e1 and 084805e.

📒 Files selected for processing (1)
  • packages/message-parser/src/grammar.pegjs
📜 Review details
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/DateTimeFormats.spec.tsx:20-23
Timestamp: 2026-03-06T18:09:17.867Z
Learning: In the RocketChat/Rocket.Chat gazzodown package (`packages/gazzodown`), tests are intended to run under the UTC timezone, but as of PR `#39397` this is NOT yet explicitly enforced in `jest.config.ts` or the `package.json` test scripts (which just run `jest` without `TZ=UTC`). To make timezone-sensitive snapshot tests reliable across all environments, `TZ=UTC` should be added to the test scripts in `package.json` or to `jest.config.ts` via `testEnvironmentOptions.timezone`. Without explicit UTC enforcement, snapshot tests involving date-fns formatted output or `toLocaleString()` will fail for contributors in non-UTC timezones.
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/RelativeTime.spec.tsx:63-70
Timestamp: 2026-03-06T18:02:20.381Z
Learning: In RocketChat/Rocket.Chat, tests in the `packages/gazzodown` package (and likely the broader test suite) are always expected to run in the UTC timezone. This makes `toLocaleString()` output deterministic, so snapshot tests that include locale/timezone-sensitive content (such as `title` attributes from `toLocaleString()`) are stable and do not need to be replaced with targeted assertions.
📚 Learning: 2026-03-06T18:09:17.867Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/DateTimeFormats.spec.tsx:20-23
Timestamp: 2026-03-06T18:09:17.867Z
Learning: In the RocketChat/Rocket.Chat gazzodown package (`packages/gazzodown`), tests are intended to run under the UTC timezone, but as of PR `#39397` this is NOT yet explicitly enforced in `jest.config.ts` or the `package.json` test scripts (which just run `jest` without `TZ=UTC`). To make timezone-sensitive snapshot tests reliable across all environments, `TZ=UTC` should be added to the test scripts in `package.json` or to `jest.config.ts` via `testEnvironmentOptions.timezone`. Without explicit UTC enforcement, snapshot tests involving date-fns formatted output or `toLocaleString()` will fail for contributors in non-UTC timezones.

Applied to files:

  • packages/message-parser/src/grammar.pegjs
📚 Learning: 2026-03-06T18:02:20.381Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/elements/Timestamp/RelativeTime.spec.tsx:63-70
Timestamp: 2026-03-06T18:02:20.381Z
Learning: In RocketChat/Rocket.Chat, tests in the `packages/gazzodown` package (and likely the broader test suite) are always expected to run in the UTC timezone. This makes `toLocaleString()` output deterministic, so snapshot tests that include locale/timezone-sensitive content (such as `title` attributes from `toLocaleString()`) are stable and do not need to be replaced with targeted assertions.

Applied to files:

  • packages/message-parser/src/grammar.pegjs
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • packages/message-parser/src/grammar.pegjs
🔇 Additional comments (1)
packages/message-parser/src/grammar.pegjs (1)

580-582: Nice catch on the strike-specific parser path.

Mirroring the escaped-before-unescaped ordering here closes the branch that previously bypassed the new inline fix.

@dougfabris dougfabris modified the milestones: 8.2.0, 8.3.0 Mar 10, 2026
@coderabbitai coderabbitai bot removed the type: bug label Mar 25, 2026
@IsseiHasegawa IsseiHasegawa requested a review from a team as a code owner March 25, 2026 02:36
@d-gubert
Copy link
Copy Markdown
Member

d-gubert commented Mar 25, 2026

Hi @IsseiHasegawa , we're migrating away from the Alsatian framework for Apps-Engine tests here #37592

So we won't be accepting files that add new Alsatian tests

@scuciatto scuciatto modified the milestones: 8.3.0, 8.4.0 Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants