fix: CI fallout from the i18n refactor + Windows path assertions

examples/screenshot.rs: migrate to language_code()/set_language_code
(the Language enum is gone); only CI's example build caught it — local
--lib runs never compile examples.

oakcodec tests: build path expectations with Path::join instead of
'/'-joined literals — production uses platform-native separators, so
the derivation assertions failed on Windows ("dir\img007.jpg" vs
"dir/img007.jpg"). Behaviour unchanged; the tests were never reached
on Windows before (earlier failures aborted the run first).

oakui::ofx interact test: poll up to 5s for the destroy marker record
before asserting. The active-interact slot is process-global; a
concurrent viewer frame sync from another test's real engine can take
the interact out of the slot and be preempted between take and
destroy, so the plugin's destroy record occasionally lands a few
milliseconds after this test removed the marker env var (Linux CI:
"lifecycle actions missing: [...]" with everything but destroy
present).
This commit is contained in:
2026-08-21 16:34:27 +08:00
parent 4622a1af1e
commit cada2f4c3a
5 changed files with 50 additions and 12 deletions
+12 -2
View File
@@ -273,8 +273,18 @@ mod tests {
let f1 = m
.get_conform_filename(&cache, &src.to_string_lossy(), 0, 48000, 0x3, 0, 1)
.unwrap();
assert_eq!(f0, format!("{}/{}.0.pcm", cache, base));
assert_eq!(f1, format!("{}/{}.1.pcm", cache, base));
assert_eq!(
f0,
std::path::Path::new(&cache)
.join(format!("{base}.0.pcm"))
.to_string_lossy()
);
assert_eq!(
f1,
std::path::Path::new(&cache)
.join(format!("{base}.1.pcm"))
.to_string_lossy()
);
// Out of range.
assert!(matches!(
m.get_conform_filename(&cache, &src.to_string_lossy(), 0, 48000, 0x3, 0, 5),
+4 -1
View File
@@ -629,7 +629,10 @@ mod tests {
);
assert_eq!(
transform_image_sequence_file_name("dir/img012.jpg", 7),
"dir/img007.jpg"
// Path::join separators are platform-native (\ on Windows).
std::path::Path::new("dir")
.join("img007.jpg")
.to_string_lossy()
);
// No digit run: number appended with no padding (C++ behavior).
assert_eq!(
+11 -3
View File
@@ -508,7 +508,10 @@ mod tests {
fn proxy_directory_is_cache_slash_proxy() {
assert_eq!(
ProxyManager::get_proxy_directory("/tmp/cache").unwrap(),
"/tmp/cache/proxy"
// Path::join separators are platform-native (\ on Windows).
std::path::Path::new("/tmp/cache")
.join("proxy")
.to_string_lossy()
);
}
@@ -522,7 +525,12 @@ mod tests {
// C++ parity), so the name is the plain size/version/audio tags.
let missing = std::path::Path::new(&temp_subdir("missing")).join("nope.mp4");
let f = ProxyManager::get_proxy_filename(&cache, missing.to_str().unwrap(), 0, &p).unwrap();
assert_eq!(f, format!("{}/proxy/-0.1280x720.v1.a1.mp4", cache));
let plain = std::path::Path::new(&cache)
.join("proxy")
.join("-0.1280x720.v1.a1.mp4")
.to_string_lossy()
.into_owned();
assert_eq!(f, plain);
// An existing source embeds a stable per-file identifier.
let existing = std::path::Path::new(&temp_subdir("existing")).join("real.mp4");
@@ -535,7 +543,7 @@ mod tests {
f1.contains("-0.1280x720.v1.a1.mp4"),
"size/version/audio tags present: {f1}"
);
assert!(f1 != format!("{}/proxy/-0.1280x720.v1.a1.mp4", cache), "id embedded: {f1}");
assert!(f1 != plain, "id embedded: {f1}");
assert_eq!(f1, f2, "the identifier is stable for the same file");
// Divider mode tags the divider instead of an absolute size.
+5 -5
View File
@@ -45,7 +45,7 @@ use gpui_platform::current_platform;
#[cfg(target_os = "macos")]
use oakapp::app::OakApp;
#[cfg(target_os = "macos")]
use oakapp::i18n::{self, Language};
use oakapp::i18n;
#[cfg(target_os = "macos")]
use oakapp::oakui::MockEngine;
@@ -95,8 +95,8 @@ fn main() -> Result<()> {
// Initialize the UI language like the real app's startup would: zh-CN
// for the primary screenshot, then en-US for the English one. The
// original persisted language is restored at the end.
let original = i18n::language();
i18n::set_language(Language::ZhCN);
let original = i18n::language_code();
i18n::set_language_code("zh-CN");
{
let (handle, root) = open_shell(&mut cx, width, height);
let image = cx.capture_screenshot(handle.into())?;
@@ -107,7 +107,7 @@ fn main() -> Result<()> {
capture_preferences(&mut cx, handle, &root, OUT_PREF_ZH)?;
capture_manager(&mut cx, handle, &root, OUT_MGR_ZH)?;
}
i18n::set_language(Language::EnUs);
i18n::set_language_code("en-US");
{
let (handle, root) = open_shell(&mut cx, width, height);
let image = cx.capture_screenshot(handle.into())?;
@@ -118,7 +118,7 @@ fn main() -> Result<()> {
capture_preferences(&mut cx, handle, &root, OUT_PREF_EN)?;
capture_manager(&mut cx, handle, &root, OUT_MGR_EN)?;
}
i18n::set_language(original);
i18n::set_language_code(&original);
Ok(())
}
+18 -1
View File
@@ -903,8 +903,25 @@ mod tests {
"clearing the selection should destroy the active interact"
);
// Wait for the destroy record: the active-interact slot is
// process-global, and a concurrent viewer frame sync (another
// test's real-engine viewer ticking in this binary) can take the
// interact out of the slot and destroy it a few milliseconds
// after our own clearing. Keep the marker env var set and poll —
// the contract (destroy reaches the plugin, in order) is still
// asserted in full below.
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
let lines = loop {
let lines = read_marker(&marker);
if lines.iter().any(|l| l == "destroy")
|| std::time::Instant::now() >= deadline
{
break lines;
}
std::thread::sleep(std::time::Duration::from_millis(10));
};
unsafe { std::env::remove_var(MARKER_ENV) };
let lines = read_marker(&marker);
let _ = std::fs::remove_file(&marker);
// Lifecycle reached the plugin, in order.