Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/cspell.dictionaries/jargon.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ SIGTTOU
sigttou
sigusr
strcasecmp
strtime
subcommand
subexpression
submodule
Expand Down
94 changes: 71 additions & 23 deletions src/uu/date/src/locale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,24 @@ mod tests {
cfg_langinfo! {
use super::*;

/// Helper function to expand a format string with a known test date
///
/// Uses a fixed test date: Monday, January 15, 2024, 14:30:45 UTC
/// This allows us to validate format strings by checking their expanded output
/// rather than looking for literal format codes.
fn expand_format_with_test_date(format: &str) -> String {
use jiff::civil::date;
use jiff::fmt::strtime;

// Create test timestamp: Monday, January 15, 2024, 14:30:45 UTC
let Ok(test_date) = date(2024, 1, 15).at(14, 30, 45, 0).in_tz("UTC") else {
return String::new();
};

// Expand the format string with the test date
strtime::format(format, &test_date).unwrap_or_default()
}

#[test]
fn test_locale_detection() {
// Just verify the function doesn't panic
Expand All @@ -144,10 +162,31 @@ mod tests {
#[test]
fn test_default_format_contains_valid_codes() {
let format = get_locale_default_format();
assert!(format.contains("%a")); // abbreviated weekday
assert!(format.contains("%b")); // abbreviated month
assert!(format.contains("%Y") || format.contains("%y")); // year (4-digit or 2-digit)
assert!(format.contains("%Z")); // timezone

let expanded = expand_format_with_test_date(format);

// Verify expanded output contains expected components
// Test date: Monday, January 15, 2024, 14:30:45
assert!(
expanded.contains("Mon") || expanded.contains("Monday"),
"Expanded format should contain weekday name, got: {expanded}"
);

assert!(
expanded.contains("Jan") || expanded.contains("January"),
"Expanded format should contain month name, got: {expanded}"
);

assert!(
expanded.contains("2024") || expanded.contains("24"),
"Expanded format should contain year, got: {expanded}"
);

// Keep literal %Z check - this is enforced by ensure_timezone_in_format()
assert!(
format.contains("%Z"),
"Format string must contain %Z timezone (enforced by ensure_timezone_in_format)"
);
}

#[test]
Expand All @@ -158,25 +197,34 @@ mod tests {
// The format should not be empty
assert!(!format.is_empty(), "Locale format should not be empty");

// Should contain date/time components
let has_date_component = format.contains("%a")
|| format.contains("%A")
|| format.contains("%b")
|| format.contains("%B")
|| format.contains("%d")
|| format.contains("%e");
assert!(has_date_component, "Format should contain date components");

// Should contain time component (hour)
let has_time_component = format.contains("%H")
|| format.contains("%I")
|| format.contains("%k")
|| format.contains("%l")
|| format.contains("%r")
|| format.contains("%R")
|| format.contains("%T")
|| format.contains("%X");
assert!(has_time_component, "Format should contain time components");
let expanded = expand_format_with_test_date(format);

// Verify expanded output contains date components
// Test date: Monday, January 15, 2024
let has_date_component = expanded.contains("15") // day
|| expanded.contains("Jan") // month name
|| expanded.contains("January") // full month
|| expanded.contains("Mon") // weekday
|| expanded.contains("Monday"); // full weekday

assert!(
has_date_component,
"Expanded format should contain date components, got: {expanded}"
);

// Verify expanded output contains time components
// Test time: 14:30:45
let has_time_component = expanded.contains("14") // 24-hour
|| expanded.contains("02") // 12-hour
|| expanded.contains("30") // minutes
|| expanded.contains(':') // time separator
|| expanded.contains("PM") // AM/PM indicator
|| expanded.contains("pm");

assert!(
has_time_component,
"Expanded format should contain time components, got: {expanded}"
);
}

#[test]
Expand Down
Loading