Merge pull request #2570 from dotCooCoo/fix/zoom-hint-test-language-race

Tests: a language one ui-egui test sets no longer translates the tests running beside it
This commit is contained in:
BFlat
2026-10-17 13:36:59 +07:00
committed by GitHub
2 changed files with 28 additions and 6 deletions
+18 -4
View File
@@ -457,19 +457,33 @@ fn detect_system_lang() -> Lang {
Lang::EN
}
/// Index into [`LANGUAGES`] of the language the UI is drawn in this frame.
static CURRENT: AtomicUsize = AtomicUsize::new(0);
/// Index into [`LANGUAGES`] of the language the UI is drawn in this frame. The app keeps one
/// index for the whole process. Unit tests keep one per thread, as `ui_mirror!` keeps the
/// shortcut and workspace mirrors, so a language one test sets does not change the language of
/// the tests running beside it on other threads.
fn current_index() -> &'static AtomicUsize {
#[cfg(not(test))]
{
static CURRENT: AtomicUsize = AtomicUsize::new(0);
&CURRENT
}
#[cfg(test)]
{
thread_local!(static CURRENT: &'static AtomicUsize = Box::leak(Box::default()));
CURRENT.with(|c| *c)
}
}
/// Set the UI language for drawing (the shell calls this once per frame from the preference), so
/// widgets can translate without every call site carrying a language around.
pub fn set_current(lang: Lang) {
let i = LANGUAGES.iter().position(|l| l.code == lang.code()).unwrap_or(0);
CURRENT.store(i, Ordering::Relaxed);
current_index().store(i, Ordering::Relaxed);
}
/// The language the UI is drawn in.
pub fn current() -> Lang {
Lang(LANGUAGES.get(CURRENT.load(Ordering::Relaxed)).unwrap_or(&LANGUAGES[0]))
Lang(LANGUAGES.get(current_index().load(Ordering::Relaxed)).unwrap_or(&LANGUAGES[0]))
}
/// Does `lang` have a catalog entry for this plain string? (English never does: it is the source.)
+10 -2
View File
@@ -100,6 +100,15 @@ fn current_language_is_a_frame_setting() {
assert_eq!(t("Layers"), "Layers");
}
/// Unit tests run on parallel threads, and each one draws in its own language: a language set on
/// another thread (by a test running beside this one) leaves this thread's text in English.
#[test]
fn a_language_set_by_another_test_leaves_this_one_in_english() {
std::thread::spawn(|| set_current(ZH())).join().unwrap();
assert_eq!(current(), Lang::EN);
assert_eq!(t("Layers"), "Layers");
}
#[test]
fn lookups_fall_back_to_english() {
assert_eq!(tr(Lang::EN, "Layers"), "Layers");
@@ -197,8 +206,7 @@ fn partial_catalogs_only_translate_strings_the_ui_shows() {
}
/// The engine learns the language the UI is drawn in each frame: new type takes the Japanese
/// defaults while it is Japanese (#432). The frames stay in English: the drawing language is
/// process-wide, and a Japanese frame would translate the tests running beside this one.
/// defaults while it is Japanese (#432). The frames stay in English.
#[test]
fn the_engine_follows_the_interface_language() {
let mut app = crate::VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default());