1
0
Fork 0
mirror of https://github.com/maziggy/bambuddy.git synced 2026-05-09 08:25:54 +02:00

[GH-ISSUE #1213] [Bug]: Locale dependant time formatting in automated tests #882

Closed
opened 2026-05-07 00:14:40 +02:00 by BreizhHardware · 1 comment

Originally created by @maugsburger on GitHub (May 5, 2026).
Original GitHub issue: https://github.com/maziggy/bambuddy/issues/1213

Originally assigned to: @maziggy on GitHub.

Component

Bambuddy

Bug Description

Followup to https://github.com/maziggy/bambuddy/pull/1205#issuecomment-4377328522

Please never ever modify and push internal files!!!

Got it. But allow me two questions:

  1. How to tell these are "internal" files?

  2. They are mentioned in https://github.com/maziggy/bambuddy/blob/dev/CONTRIBUTING.md#testing to be used for testing; the date and time format tests failed on my system as I have locale settings leading to the times times being output using . instead of :, which lead to test failures in frontend/src/__tests__/utils/date.test.ts

Tests should not fail depending on system specific defaults, the tests must be system config agnostic.

To fix this, we could:

  1. set LC_ALL in the helper scripts, the version you rejected
  2. adjust the options in frontend/src/utils/date.ts to globally set other options (didn't check the implications in other parts of the code)
  3. be more explicit about the wanted format in the test file itself when calling formatTimeOnly – but then we don't catch potential problems in paths of the code that don't set them.
  4. adjust the regex (with the risk that other locales use further, uncovered separators):
    -    expect(result).toMatch(/2:30|02:30/); 
    +    expect(result).toMatch(/0?2[:\.]30/) ;
    

Opened this case to discuss the best option prior to changing anything.

Expected Behavior

Tests should pass independently of the systems locales.

Steps to Reproduce

Run the tests with LC_ALL="en_DK.UTF-8":

❯ npm test -- src/__tests__/utils/date.test.ts

> frontend@0.0.0 test
> vitest src/__tests__/utils/date.test.ts


 DEV  v3.2.4 /home/ma/git/bambuddy/frontend

(node:643799) Warning: `--localstorage-file` was provided without a valid path
(Use `node --trace-warnings ...` to show where the warning was created)
 ❯ src/__tests__/utils/date.test.ts (69 tests | 2 failed) 24ms
   ✓ getDatePlaceholder > returns MM/DD/YYYY for us format 1ms
   ✓ getDatePlaceholder > returns DD/MM/YYYY for eu format 0ms
   ✓ getDatePlaceholder > returns YYYY-MM-DD for iso format 0ms
   ✓ getDatePlaceholder > returns a placeholder for system format 7ms
   ✓ getTimePlaceholder > returns HH:MM AM/PM for 12h format 0ms
   ✓ getTimePlaceholder > returns HH:MM for 24h format 0ms
   ✓ getTimePlaceholder > returns a placeholder for system format 3ms
   ✓ formatDateInput > formats as MM/DD/YYYY for us format 0ms
   ✓ formatDateInput > formats as DD/MM/YYYY for eu format 0ms
   ✓ formatDateInput > formats as YYYY-MM-DD for iso format 0ms
   ✓ formatDateInput > uses toLocaleDateString for system format 0ms
   ✓ formatTimeInput > formats as 12h with AM 0ms
   ✓ formatTimeInput > formats as 12h with PM 0ms
   ✓ formatTimeInput > formats 12:00 as 12:00 PM 0ms
   ✓ formatTimeInput > formats 00:00 as 12:00 AM 0ms
   ✓ formatTimeInput > formats as 24h 0ms
   ✓ formatTimeInput > pads hours in 24h format 0ms
   ✓ parseDateInput > parses us format MM/DD/YYYY 0ms
   ✓ parseDateInput > parses eu format DD/MM/YYYY 0ms
   ✓ parseDateInput > parses iso format YYYY-MM-DD 0ms
   ✓ parseDateInput > accepts different separators 0ms
   ✓ parseDateInput > returns null for invalid input 0ms
   ✓ parseDateInput > returns null for invalid month 0ms
   ✓ parseDateInput > returns null for invalid day 0ms
   ✓ parseTimeInput > parses 24h format 1ms
   ✓ parseTimeInput > parses 12h format with AM 0ms
   ✓ parseTimeInput > parses 12h format with PM 0ms
   ✓ parseTimeInput > is case insensitive for AM/PM 0ms
   ✓ parseTimeInput > returns null for invalid input 0ms
   ✓ toDateTimeLocalValue > formats date to datetime-local value 0ms
   ✓ toDateTimeLocalValue > pads single digit values 0ms
   ✓ applyTimeFormat > sets hour12 true for 12h format 0ms
   ✓ applyTimeFormat > sets hour12 false for 24h format 0ms
   ✓ applyTimeFormat > leaves hour12 undefined for system format 0ms
   ✓ applyTimeFormat > returns the modified options object 0ms
   ✓ parseUTCDate > returns null for null/undefined input 0ms
   ✓ parseUTCDate > parses ISO string with Z suffix as-is 0ms
   ✓ parseUTCDate > parses ISO string with timezone offset as-is 0ms
   ✓ parseUTCDate > appends Z to strings without timezone indicator 0ms
   ✓ formatDate > returns empty string for null input 0ms
   ✓ formatDate > formats a valid date string 0ms
   ✓ formatDate > accepts custom options 0ms
   ✓ formatDateOnly > returns empty string for null input 0ms
   ✓ formatDateOnly > formats date without time 0ms
   ✓ formatDateTime > returns empty string for null input 0ms
   ✓ formatDateTime > formats with 12h time format 0ms
   ✓ formatDateTime > formats with 24h time format 0ms
   × formatTimeOnly > formats time with 12h format 2ms
     → expected '02.30 pm' to match /2:30|02:30/
   × formatTimeOnly > formats time with 24h format 1ms
     → expected '14.30' to contain '14:30'
   ✓ formatETA > returns time only for same day 1ms
   ✓ formatETA > includes "Tomorrow" for next day 0ms
   ✓ formatETA > uses translation function for tomorrow 0ms
   ✓ formatETA > shows weekday for dates beyond tomorrow 0ms
   ✓ formatDuration > returns "--" for null/undefined 0ms
   ✓ formatDuration > returns "--" for negative values 0ms
   ✓ formatDuration > formats minutes only when under 1 hour 0ms
   ✓ formatDuration > formats hours and minutes 0ms
   ✓ formatRelativeTime > returns "-" for null input 0ms
   ✓ formatRelativeTime > returns translated unknown for null with translation 0ms
   ✓ formatRelativeTime > returns "Just now" for times less than 1 minute ago 0ms
   ✓ formatRelativeTime > returns "Now" for times less than 1 minute in future 0ms
   ✓ formatRelativeTime > returns minutes ago for times under 1 hour ago 0ms
   ✓ formatRelativeTime > returns "in Xm" for times under 1 hour in future 0ms
   ✓ formatRelativeTime > returns hours ago for times under 1 day ago 0ms
   ✓ formatRelativeTime > returns "in Xh" for times under 1 day in future 0ms
   ✓ formatRelativeTime > returns days ago for times under 7 days ago 0ms
   ✓ formatRelativeTime > returns "in Xd" for times under 7 days in future 0ms
   ✓ formatRelativeTime > returns formatted date for times older than 7 days 0ms
   ✓ formatRelativeTime > uses translation function when provided 0ms

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  src/__tests__/utils/date.test.ts > formatTimeOnly > formats time with 12h format
AssertionError: expected '02.30 pm' to match /2:30|02:30/

- Expected: 
/2:30|02:30/

+ Received: 
"02.30 pm"

 ❯ src/__tests__/utils/date.test.ts:299:20
    297|     const date = new Date(2025, 5, 15, 14, 30);
    298|     const result = formatTimeOnly(date, '12h');
    299|     expect(result).toMatch(/2:30|02:30/);
       |                    ^
    300|     expect(result.toUpperCase()).toContain('PM');
    301|   });

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯

 FAIL  src/__tests__/utils/date.test.ts > formatTimeOnly > formats time with 24h format
AssertionError: expected '14.30' to contain '14:30'

Expected: "14:30"
Received: "14.30"

 ❯ src/__tests__/utils/date.test.ts:306:20
    304|     const date = new Date(2025, 5, 15, 14, 30);
    305|     const result = formatTimeOnly(date, '24h');
    306|     expect(result).toContain('14:30');
       |                    ^
    307|   });
    308| });

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯


 Test Files  1 failed (1)
      Tests  2 failed | 67 passed (69)
   Start at  10:42:16
   Duration  971ms (transform 392ms, setup 561ms, collect 16ms, tests 24ms, environment 211ms, prepare 45ms)

Bambuddy Version

dev

Installation Method

Manual (git clone)

Operating System

Linux (Arch)

Checklist

  • I have searched existing issues to ensure this bug hasn't already been reported
  • I am using the latest version of Bambuddy
  • My printer is set to LAN Only mode
  • My printer has Developer Mode enabled
Originally created by @maugsburger on GitHub (May 5, 2026). Original GitHub issue: https://github.com/maziggy/bambuddy/issues/1213 Originally assigned to: @maziggy on GitHub. ### Component Bambuddy ### Bug Description Followup to https://github.com/maziggy/bambuddy/pull/1205#issuecomment-4377328522 > Please never ever modify and push internal files!!! Got it. But allow me two questions: 1. How to tell these are "internal" files? 2. They are mentioned in https://github.com/maziggy/bambuddy/blob/dev/CONTRIBUTING.md#testing to be used for testing; the date and time format tests failed on my system as I have locale settings leading to the times times being output using `.` instead of `:`, which lead to test failures in `frontend/src/__tests__/utils/date.test.ts` Tests should not fail depending on system specific defaults, the tests must be system config agnostic. To fix this, we could: 1. set LC_ALL in the helper scripts, the version you rejected 2. adjust the options in `frontend/src/utils/date.ts` to globally set other options (didn't check the implications in other parts of the code) 3. be more explicit about the wanted format in the test file itself when calling formatTimeOnly – but then we don't catch potential problems in paths of the code that don't set them. 4. adjust the regex (with the risk that other locales use further, uncovered separators): ```diff - expect(result).toMatch(/2:30|02:30/); + expect(result).toMatch(/0?2[:\.]30/) ; ``` Opened this case to discuss the best option prior to changing anything. ### Expected Behavior Tests should pass independently of the systems locales. ### Steps to Reproduce Run the tests with LC_ALL="en_DK.UTF-8": ``` ❯ npm test -- src/__tests__/utils/date.test.ts > frontend@0.0.0 test > vitest src/__tests__/utils/date.test.ts DEV v3.2.4 /home/ma/git/bambuddy/frontend (node:643799) Warning: `--localstorage-file` was provided without a valid path (Use `node --trace-warnings ...` to show where the warning was created) ❯ src/__tests__/utils/date.test.ts (69 tests | 2 failed) 24ms ✓ getDatePlaceholder > returns MM/DD/YYYY for us format 1ms ✓ getDatePlaceholder > returns DD/MM/YYYY for eu format 0ms ✓ getDatePlaceholder > returns YYYY-MM-DD for iso format 0ms ✓ getDatePlaceholder > returns a placeholder for system format 7ms ✓ getTimePlaceholder > returns HH:MM AM/PM for 12h format 0ms ✓ getTimePlaceholder > returns HH:MM for 24h format 0ms ✓ getTimePlaceholder > returns a placeholder for system format 3ms ✓ formatDateInput > formats as MM/DD/YYYY for us format 0ms ✓ formatDateInput > formats as DD/MM/YYYY for eu format 0ms ✓ formatDateInput > formats as YYYY-MM-DD for iso format 0ms ✓ formatDateInput > uses toLocaleDateString for system format 0ms ✓ formatTimeInput > formats as 12h with AM 0ms ✓ formatTimeInput > formats as 12h with PM 0ms ✓ formatTimeInput > formats 12:00 as 12:00 PM 0ms ✓ formatTimeInput > formats 00:00 as 12:00 AM 0ms ✓ formatTimeInput > formats as 24h 0ms ✓ formatTimeInput > pads hours in 24h format 0ms ✓ parseDateInput > parses us format MM/DD/YYYY 0ms ✓ parseDateInput > parses eu format DD/MM/YYYY 0ms ✓ parseDateInput > parses iso format YYYY-MM-DD 0ms ✓ parseDateInput > accepts different separators 0ms ✓ parseDateInput > returns null for invalid input 0ms ✓ parseDateInput > returns null for invalid month 0ms ✓ parseDateInput > returns null for invalid day 0ms ✓ parseTimeInput > parses 24h format 1ms ✓ parseTimeInput > parses 12h format with AM 0ms ✓ parseTimeInput > parses 12h format with PM 0ms ✓ parseTimeInput > is case insensitive for AM/PM 0ms ✓ parseTimeInput > returns null for invalid input 0ms ✓ toDateTimeLocalValue > formats date to datetime-local value 0ms ✓ toDateTimeLocalValue > pads single digit values 0ms ✓ applyTimeFormat > sets hour12 true for 12h format 0ms ✓ applyTimeFormat > sets hour12 false for 24h format 0ms ✓ applyTimeFormat > leaves hour12 undefined for system format 0ms ✓ applyTimeFormat > returns the modified options object 0ms ✓ parseUTCDate > returns null for null/undefined input 0ms ✓ parseUTCDate > parses ISO string with Z suffix as-is 0ms ✓ parseUTCDate > parses ISO string with timezone offset as-is 0ms ✓ parseUTCDate > appends Z to strings without timezone indicator 0ms ✓ formatDate > returns empty string for null input 0ms ✓ formatDate > formats a valid date string 0ms ✓ formatDate > accepts custom options 0ms ✓ formatDateOnly > returns empty string for null input 0ms ✓ formatDateOnly > formats date without time 0ms ✓ formatDateTime > returns empty string for null input 0ms ✓ formatDateTime > formats with 12h time format 0ms ✓ formatDateTime > formats with 24h time format 0ms × formatTimeOnly > formats time with 12h format 2ms → expected '02.30 pm' to match /2:30|02:30/ × formatTimeOnly > formats time with 24h format 1ms → expected '14.30' to contain '14:30' ✓ formatETA > returns time only for same day 1ms ✓ formatETA > includes "Tomorrow" for next day 0ms ✓ formatETA > uses translation function for tomorrow 0ms ✓ formatETA > shows weekday for dates beyond tomorrow 0ms ✓ formatDuration > returns "--" for null/undefined 0ms ✓ formatDuration > returns "--" for negative values 0ms ✓ formatDuration > formats minutes only when under 1 hour 0ms ✓ formatDuration > formats hours and minutes 0ms ✓ formatRelativeTime > returns "-" for null input 0ms ✓ formatRelativeTime > returns translated unknown for null with translation 0ms ✓ formatRelativeTime > returns "Just now" for times less than 1 minute ago 0ms ✓ formatRelativeTime > returns "Now" for times less than 1 minute in future 0ms ✓ formatRelativeTime > returns minutes ago for times under 1 hour ago 0ms ✓ formatRelativeTime > returns "in Xm" for times under 1 hour in future 0ms ✓ formatRelativeTime > returns hours ago for times under 1 day ago 0ms ✓ formatRelativeTime > returns "in Xh" for times under 1 day in future 0ms ✓ formatRelativeTime > returns days ago for times under 7 days ago 0ms ✓ formatRelativeTime > returns "in Xd" for times under 7 days in future 0ms ✓ formatRelativeTime > returns formatted date for times older than 7 days 0ms ✓ formatRelativeTime > uses translation function when provided 0ms ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ FAIL src/__tests__/utils/date.test.ts > formatTimeOnly > formats time with 12h format AssertionError: expected '02.30 pm' to match /2:30|02:30/ - Expected: /2:30|02:30/ + Received: "02.30 pm" ❯ src/__tests__/utils/date.test.ts:299:20 297| const date = new Date(2025, 5, 15, 14, 30); 298| const result = formatTimeOnly(date, '12h'); 299| expect(result).toMatch(/2:30|02:30/); | ^ 300| expect(result.toUpperCase()).toContain('PM'); 301| }); ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯ FAIL src/__tests__/utils/date.test.ts > formatTimeOnly > formats time with 24h format AssertionError: expected '14.30' to contain '14:30' Expected: "14:30" Received: "14.30" ❯ src/__tests__/utils/date.test.ts:306:20 304| const date = new Date(2025, 5, 15, 14, 30); 305| const result = formatTimeOnly(date, '24h'); 306| expect(result).toContain('14:30'); | ^ 307| }); 308| }); ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ Test Files 1 failed (1) Tests 2 failed | 67 passed (69) Start at 10:42:16 Duration 971ms (transform 392ms, setup 561ms, collect 16ms, tests 24ms, environment 211ms, prepare 45ms) ``` ### Bambuddy Version dev ### Installation Method Manual (git clone) ### Operating System Linux (Arch) ### Checklist - [x] I have searched existing issues to ensure this bug hasn't already been reported - [x] I am using the latest version of Bambuddy - [x] My printer is set to LAN Only mode - [x] My printer has Developer Mode enabled
BreizhHardware 2026-05-07 00:14:40 +02:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@maziggy commented on GitHub (May 5, 2026):

You're right — option 4 is the right direction, and the answer to (1) is "these aren't internal files."

test_frontend.sh and test_backend.sh are the contributor-facing test runners documented in CONTRIBUTING.md (Testing section). I do keep some local tweaks in mine and reacted too sharply on #1205 — sorry about that.
The right fix is on my side (keeping personal modifications uncommitted), not asking contributors to avoid touching documented files. I'll add a note to CONTRIBUTING.md if there's anything that should genuinely be hands-off.

For the actual bug: option 4 with one tweak is the cleanest. Use \D+ (any non-digit, one or more) instead of [:.] so the regex covers any locale separator — en_DK.UTF-8 uses ".", some en_* locales use a narrow no-break space (U+202F), most use ":". Tests the actual contract ("hours and minutes, separated somehow") rather than coupling to a specific separator.

Patch:

expect(result).toMatch(/\b0?2\D+30\b/);   // 12h
expect(result).toMatch(/\b14\D+30\b/);    // 24h

I verified this passes under en_DK.UTF-8, en_US.UTF-8, and de_DE.UTF-8.

Thanks for opening the issue; appreciated.

Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you.


If you find Bambuddy useful, please consider giving it a on GitHub — it helps others discover the project!

<!-- gh-comment-id:4379091649 --> @maziggy commented on GitHub (May 5, 2026): You're right — option 4 is the right direction, and the answer to (1) is "these aren't internal files." test_frontend.sh and test_backend.sh are the contributor-facing test runners documented in CONTRIBUTING.md (Testing section). I do keep some local tweaks in mine and reacted too sharply on #1205 — sorry about that. The right fix is on my side (keeping personal modifications uncommitted), not asking contributors to avoid touching documented files. I'll add a note to CONTRIBUTING.md if there's anything that should genuinely be hands-off. For the actual bug: option 4 with one tweak is the cleanest. Use \D+ (any non-digit, one or more) instead of [:\.] so the regex covers any locale separator — en_DK.UTF-8 uses ".", some en_* locales use a narrow no-break space (U+202F), most use ":". Tests the actual contract ("hours and minutes, separated somehow") rather than coupling to a specific separator. Patch: expect(result).toMatch(/\b0?2\D+30\b/); // 12h expect(result).toMatch(/\b14\D+30\b/); // 24h I verified this passes under en_DK.UTF-8, en_US.UTF-8, and de_DE.UTF-8. Thanks for opening the issue; appreciated. Available/Fixed in branch dev and available with the next release or daily build. Please let me know if it works for you. ----- If you find Bambuddy useful, please consider giving it a ⭐ on [GitHub](https://github.com/maziggy/bambuddy) — it helps others discover the project!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy-maziggy-1#882
No description provided.