Read plural keys from form arguments and report all catalog gaps

This commit is contained in:
skylar taylor-barrick committed 2026-10-12 04:49:59 +02:00
1 parent 6651724db8
commit a538567a0d
1 file changed
+24 -4
+24 -4
View File
@@ -185,9 +185,14 @@ fn plural_keys(sources: &[(PathBuf, String)]) -> BTreeSet<Key> {
rest = rest.get(at + 4..).unwrap_or("");
let Some(end) = call_end(rest) else { break };
let args = rest.get(..end).unwrap_or("");
let forms = quoted_strings(args);
if forms.len() >= 2 {
keys.insert(Key { context: "@plural".into(), source: format!("{}|{}", forms[0], forms[1]) });
let args = split_arguments(args);
let literal = |arg: &&str| {
let arg = arg.trim();
let strings = quoted_strings(arg);
if arg.starts_with('"') && arg.ends_with('"') && strings.len() == 1 { strings.into_iter().next() } else { None }
};
if let Some((one, other)) = args.get(2).and_then(literal).zip(args.get(3).and_then(literal)) {
keys.insert(Key { context: "@plural".into(), source: format!("{one}|{other}") });
}
rest = rest.get(end + 1..).unwrap_or("");
}
@@ -545,6 +550,17 @@ mod tests {
assert!(plural_keys(&sources).contains(&Key { context: "@plural".into(), source: "{n} layer|{n} layers".into() }));
}
#[test]
fn plural_forms_follow_count_expressions_and_dynamic_forms_are_not_literal_keys() {
let sources = vec![(
PathBuf::from("ui.rs"),
r#"trn(lang, r["files"].as_array().map_or(0, Vec::len) as u64, "Saved {n} file", "Saved {n} files");
trn(lang, count, one, other);"#
.into(),
)];
assert_eq!(plural_keys(&sources), BTreeSet::from([Key { context: "@plural".into(), source: "Saved {n} file|Saved {n} files".into() }]));
}
#[test]
fn source_scanner_ignores_test_modules_with_lf_and_crlf() {
for newline in ["\n", "\r\n"] {
@@ -560,6 +576,7 @@ mod tests {
fn source_key_set_is_covered_by_complete_catalogs() {
let root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap_or(Path::new("."));
let keys = source_keys(root).unwrap_or_default();
let mut gaps = Vec::new();
for (code, path) in [
("ja", "ja.tsv"),
("zh-hant", "zh-hant.tsv"),
@@ -577,7 +594,10 @@ mod tests {
let text = fs::read_to_string(&catalog_path).unwrap_or_default();
let translations = parse_catalog(&catalog_path, &text).unwrap_or_default();
let missing: Vec<_> = keys.difference(&translations).collect();
assert!(missing.is_empty(), "{code}: missing source keys: {missing:#?}");
if !missing.is_empty() {
gaps.push(format!("{code}: missing source keys: {missing:#?}"));
}
}
assert!(gaps.is_empty(), "{}", gaps.join("\n"));
}
}