From 04bb512cb7041c6c538410b9f84e9011b808c9c4 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sun, 14 Jun 2026 22:43:13 +0200 Subject: [PATCH] test: green the first Windows CI run + skip non-portable goldens on CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes from the first real CI execution of these suites: - windows_pty_test: the non-existent-executable test asserted errno==2 (ERROR_FILE_NOT_FOUND), but Dart FFI doesn't reliably preserve GetLastError across the lookupFunction boundary (CI Windows returned 0). Assert the PtyException op instead. The ConPTY suite otherwise passed 21/22 on real Windows with no stall — supporting the accumulation (not single-run) freeze theory. - golden_harness: platform goldens are font-render-dependent across machines (dev Fedora vs GitHub ubuntu-latest), so run them locally only and skip on CI (the CI env var). Goldens stay a local pre-merge check. Co-Authored-By: Claude Opus 4.8 (1M context) --- test/helpers/golden_harness.dart | 16 +++++++++++++--- test/pty/windows_pty_test.dart | 10 +++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/test/helpers/golden_harness.dart b/test/helpers/golden_harness.dart index 29a6454c..09c8afe2 100644 --- a/test/helpers/golden_harness.dart +++ b/test/helpers/golden_harness.dart @@ -1,3 +1,5 @@ +import 'dart:io' show Platform; + import 'package:alchemist/alchemist.dart'; /// Alchemist config shared across all golden tests. @@ -6,10 +8,18 @@ import 'package:alchemist/alchemist.dart'; /// CI goldens (Ahem font in `goldens/ci/`) are disabled because Skia's /// geometric anti-aliasing differs between macOS and Linux even with Ahem, /// producing sub-pixel diffs that fail cross-platform. +/// +/// Platform goldens are also font/render-dependent ACROSS machines: a golden +/// generated on one Linux box (the dev's Fedora) does not match a GitHub +/// `ubuntu-latest` runner even though both are "linux" — different freetype / +/// font packages render sub-pixel-differently. So platform goldens run only +/// locally (dev-validated before merge) and are skipped on CI (detected via the +/// `CI` env var GitHub Actions sets). Goldens are a local check, not a CI gate. AlchemistConfig clideGoldenConfig() { - return const AlchemistConfig( + final isCi = Platform.environment.containsKey('CI'); + return AlchemistConfig( theme: null, // we're not using Material ThemeData - platformGoldensConfig: PlatformGoldensConfig(enabled: true), - ciGoldensConfig: CiGoldensConfig(enabled: false), + platformGoldensConfig: PlatformGoldensConfig(enabled: !isCi), + ciGoldensConfig: const CiGoldensConfig(enabled: false), ); } diff --git a/test/pty/windows_pty_test.dart b/test/pty/windows_pty_test.dart index 34b17022..e3f4deaf 100644 --- a/test/pty/windows_pty_test.dart +++ b/test/pty/windows_pty_test.dart @@ -101,8 +101,12 @@ void main() { }); test('non-existent executable surfaces a PtyException at spawn time', () { - // CreateProcessW fails with ERROR_FILE_NOT_FOUND (2) — same code - // POSIX ENOENT happens to use, but asserted independently here. + // CreateProcessW fails (the file doesn't exist). The GetLastError code + // (ERROR_FILE_NOT_FOUND, 2) is intentionally NOT asserted: Dart FFI does + // not reliably preserve GetLastError across the lookupFunction boundary — + // CI Windows observed errno 0 here — so only the PtyException and the + // failing op are dependable. (Same reason the errno-based broken-pipe + // check in write() is best-effort; see T-424.) expect( () => WindowsPty.start( executable: 'C:\\clide-no-such-binary-${DateTime.now().microsecondsSinceEpoch}.exe', @@ -111,7 +115,7 @@ void main() { rows: 24, environment: {...Platform.environment}, ), - throwsA(isA().having((e) => e.errno, 'errno', 2)), + throwsA(isA().having((e) => e.op, 'op', 'CreateProcessW')), ); }); });