Skip to content
Merged
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
3 changes: 3 additions & 0 deletions tests/test_lite.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ def test_the_foreground_is_never_asked_about_in_lite(self):
self.assertIsNone(pill.paste_target)
asked.assert_not_called()

@unittest.skipUnless(sys.platform == "win32",
"full mode resolves the foreground window through inject.py, "
"which binds user32 at import")
def test_full_mode_still_tracks_it(self):
import flow.ui as ui

Expand Down
15 changes: 15 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ def launch(self, argv) -> int:
import flow.asr
import flow.diag
import flow.profile
import flow.refine
import flow.ui

import flow.__main__ as mod
Expand Down Expand Up @@ -445,7 +446,21 @@ def launch(self, hotkeys, argv=(), platform="win32") -> tuple[int, str]:
path = self.dir / "profile.json"
path.write_text(json.dumps({"schema": 1, "hotkeys": hotkeys}), encoding="utf-8")
out = io.StringIO()
# `refine.resolve` is stubbed, and not only for speed. It calls
# `shutil.which`, and `shutil.which` reads `sys.platform` - which this
# helper has just lied about. On a real macOS runner that sends the stdlib
# down its Windows branch, where `_winapi` is None: `AttributeError:
# 'NoneType' object has no attribute 'NeedCurrentDirectoryForExePath'`,
# raised from a line no part of Flow wrote. Which agent CLI happens to be
# installed has nothing to do with what this class asserts.
#
# Stubbed at `resolve` rather than at its callers, which was the first
# attempt and was whack-a-mole: `main` reaches the same line through
# `available()` *and* `unverified()`, and patching one left the other. It is
# the single choke point - the only `shutil.which` in the module, and what
# every lookup goes through.
with mock.patch.object(sys, "platform", platform), \
mock.patch.object(flow.refine, "resolve", return_value=None), \
mock.patch.object(flow.profile, "DEFAULT_PATH", path), \
mock.patch.object(flow.diag, "Diag"), \
mock.patch.object(mod, "Session"), \
Expand Down
9 changes: 9 additions & 0 deletions tests/test_pill.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ def test_the_advance_is_the_one_the_real_font_measures(self):
root.withdraw()
ui._load_fonts()
f = tkfont.Font(root=root, font=ui.FONT_TRACE)
# `_load_fonts` registers the bundled Plex weights through GDI and returns
# early off Windows, so anywhere else Tk quietly substitutes its own
# monospace and this measures *that* - 10 px on a macOS runner against the
# 7 the real face gives. Skipped on the substitution rather than on the
# platform, because the question is whether the font resolved, and a
# Windows machine missing the file deserves the same answer.
if f.actual("family") != ui.FONT_TRACE[0]:
self.skipTest(f"{ui.FONT_TRACE[0]} not installed; "
f"Tk substituted {f.actual('family')!r}")
Comment on lines +120 to +122

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail when the bundled font stops loading on Windows

When _load_fonts() regresses on Windows—for example, a font filename or GDI registration call changes—Tk substitutes another family and this new branch marks the test skipped, so the only test covering both bundled-font resolution and the hardcoded LABEL_ADV silently disappears. Since the font files are repository assets and the product relies on their metrics, substitution should only be skipped on unsupported platforms; on Windows it should fail so a broken font-loading path cannot ship unnoticed.

Useful? React with 👍 / 👎.

self.assertEqual(f.measure("M"), ui.LABEL_ADV)
# Monospaced, which is the assumption behind one advance for every glyph —
# including the space in `NO INPUT`.
Expand Down
Loading