Skip to content

fix(edge-apps-library): make locale tests cross-platform for ICU version differences#693

Open
nicomiguelino wants to merge 3 commits intomasterfrom
fix/icu-version-locale-test-compat
Open

fix(edge-apps-library): make locale tests cross-platform for ICU version differences#693
nicomiguelino wants to merge 3 commits intomasterfrom
fix/icu-version-locale-test-compat

Conversation

@nicomiguelino
Copy link
Contributor

@nicomiguelino nicomiguelino commented Feb 17, 2026

User description

Summary

  • hi-IN dayPeriod output varies by ICU version: older ICU (Linux/CI) returns 'pm' while newer ICU (macOS) returns 'अ'; assert against a known-values set instead of a hardcoded string
  • hi-IN formatted string order also differs, so use toContain('02:30:45') instead of a full-string regex
  • Russian short day names are lowercase in older ICU and title-cased in newer ICU; extracted ru into a standalone test that normalizes to lowercase before comparing

PR Type

Tests


Description

  • Make hi-IN time tests ICU-tolerant

    • Accept multiple PM dayPeriod values
    • Assert time substring only
  • Stabilize ru day-name tests across ICU

    • Normalize short names to lowercase

Diagram Walkthrough

flowchart LR
  n1["Locale-dependent tests"] 
  n2["formatTime hi-IN assertions"] 
  n3["Known PM dayPeriod set"] 
  n4["Relax formatted string check"] 
  n5["getLocalizedDayNames ru assertions"] 
  n6["Lowercase normalization for short names"] 

  n1 -- "adjust" --> n2
  n2 -- "accept variants" --> n3
  n2 -- "avoid ordering variance" --> n4
  n1 -- "split out" --> n5
  n5 -- "normalize ICU casing" --> n6
Loading

File Walkthrough

Relevant files
Tests
format-time.test.ts
Loosen hi-IN assertions for ICU variance                                 

edge-apps/edge-apps-library/src/utils/format-time.test.ts

  • Add knownPmValues set for hi-IN dayPeriod
  • Replace strict dayPeriod equality with set membership
  • Relax formatted output check to toContain('02:30:45')
+5/-2     
get-localized-day-names.test.ts
Split ru test and normalize abbreviations                               

edge-apps/edge-apps-library/src/utils/get-localized-day-names.test.ts

  • Remove ru from shared locale expectation table
  • Add dedicated ru test with explicit full names
  • Compare short names after lowercasing values
+25/-13 

…ion differences

- Handle hi-IN dayPeriod variations ('pm' on Linux, 'अ' on macOS) using a known-values set
- Use toContain() for hi-IN formatted time assertion instead of a full-string regex
- Extract ru locale into a standalone test with lowercase normalization for short day names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Feb 17, 2026

PR Reviewer Guide 🔍

(Review updated until commit 75d1963)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Test Robustness

The hi-IN dayPeriod assertion relies on a hardcoded known-values set; consider normalizing casing/whitespace and/or asserting more generally (e.g., non-empty and not AM) to reduce future ICU/version drift causing flaky tests.

// hi-IN PM representation varies across ICU versions:
// older ICU (Linux/CI) returns 'pm'; newer ICU (macOS) returns 'अ' or 'अपराह्न'
const knownPmValues = new Set(['pm', 'PM', 'अ', 'अपराह्न'])
expect(knownPmValues.has(result.dayPeriod ?? '')).toBe(true)
expect(result.formatted).toContain('02:30:45')
Locale Casing

The Russian short-name normalization uses toLowerCase(); for maximum locale correctness and consistency across environments, consider toLocaleLowerCase('ru') (or explicitly document why simple lowercasing is sufficient here).

// Russian abbreviated day names vary by ICU version: older ICU (Linux/CI)
// returns lowercase ('вс', 'пн', …) while newer ICU (macOS) returns
// title-cased ('Вс', 'Пн', …). Normalize to lowercase before comparing.
expect(result.short.map((s) => s.toLowerCase())).toEqual([
  'вс',
  'пн',
  'вт',
  'ср',
  'чт',
  'пт',
  'сб',
])

@github-actions
Copy link

github-actions bot commented Feb 17, 2026

PR Code Suggestions ✨

Latest suggestions up to 75d1963
Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Verify formatted includes day period

Also assert that result.formatted includes the chosen result.dayPeriod, otherwise
this test can pass even if the formatted string accidentally drops the day period.
This keeps the test cross-ICU while still catching regressions in the final
formatted output.

edge-apps/edge-apps-library/src/utils/format-time.test.ts [78-82]

 // hi-IN PM representation varies across ICU versions:
 // older ICU (Linux/CI) returns 'pm'; newer ICU (macOS) returns 'अ' or 'अपराह्न'
 const knownPmValues = new Set(['pm', 'PM', 'अ', 'अपराह्न'])
-expect(knownPmValues.has(result.dayPeriod ?? '')).toBe(true)
+const dayPeriod = result.dayPeriod ?? ''
+expect(knownPmValues.has(dayPeriod)).toBe(true)
 expect(result.formatted).toContain('02:30:45')
+expect(result.formatted).toContain(dayPeriod)
Suggestion importance[1-10]: 5

__

Why: This is a correct, cross-ICU-friendly way to ensure result.formatted doesn’t silently drop the result.dayPeriod while still allowing multiple valid PM strings. Impact is moderate because the current test already checks the time portion, but not the presence of the period in the final formatted output.

Low
General
Use locale-aware lowercase normalization

Use locale-aware casing (toLocaleLowerCase('ru-RU')) to avoid subtle
environment-dependent lowercasing behavior. This makes the normalization step itself
more deterministic across runtimes.

edge-apps/edge-apps-library/src/utils/get-localized-day-names.test.ts [217-225]

-expect(result.short.map((s) => s.toLowerCase())).toEqual([
+expect(result.short.map((s) => s.toLocaleLowerCase('ru-RU'))).toEqual([
   'вс',
   'пн',
   'вт',
   'ср',
   'чт',
   'пт',
   'сб',
 ])
Suggestion importance[1-10]: 3

__

Why: Using toLocaleLowerCase('ru-RU') is a safe, valid change, but for Cyrillic abbreviations toLowerCase() is already deterministic in practice and doesn’t usually vary by environment. This mainly improves robustness/readability slightly rather than addressing a likely bug.

Low

Previous suggestions

Suggestions up to commit 75d1963
CategorySuggestion                                                                                                                                    Impact
General
Normalize punctuation and whitespace

Make the normalization resilient to ICU outputs that include punctuation or
surrounding whitespace (e.g., вс.) by trimming and stripping a trailing period.
Using locale-aware lowercasing also avoids edge-case casing issues across
environments.

edge-apps/edge-apps-library/src/utils/get-localized-day-names.test.ts [214-225]

 // Russian abbreviated day names vary by ICU version: older ICU (Linux/CI)
 // returns lowercase ('вс', 'пн', …) while newer ICU (macOS) returns
-// title-cased ('Вс', 'Пн', …). Normalize to lowercase before comparing.
-expect(result.short.map((s) => s.toLowerCase())).toEqual([
+// title-cased ('Вс', 'Пн', …). Normalize before comparing.
+const normalizedShort = result.short.map((s) =>
+  s.trim().replace(/\.$/, '').toLocaleLowerCase('ru-RU'),
+)
+expect(normalizedShort).toEqual([
   'вс',
   'пн',
   'вт',
   'ср',
   'чт',
   'пт',
   'сб',
 ])
Suggestion importance[1-10]: 5

__

Why: Trimming and stripping a trailing period makes the ru short-day assertion more resilient to ICU variations (e.g., вс. vs вс) while keeping the test’s intent intact. The change is small and maintainability-focused, with moderate value.

Low

@github-actions
Copy link

Persistent review updated to latest commit 75d1963

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR makes locale-related unit tests cross-platform compatible by handling ICU version differences between operating systems (older ICU on Linux/CI vs newer ICU on macOS). The changes focus on relaxing overly-strict test assertions that were failing due to legitimate locale formatting variations across different ICU implementations.

Changes:

  • Modified hi-IN locale test in format-time.test.ts to accept multiple valid PM representations
  • Relaxed hi-IN formatted time assertion to use substring matching instead of strict regex
  • Extracted Russian locale test in get-localized-day-names.test.ts to handle case-insensitive short day name comparison

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
edge-apps/edge-apps-library/src/utils/format-time.test.ts Updated hi-IN hour12 test to accept multiple ICU-specific PM representations and relaxed formatted string assertion
edge-apps/edge-apps-library/src/utils/get-localized-day-names.test.ts Isolated Russian locale test from parametrized loop and added lowercase normalization for abbreviated day names

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

… test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant