From 5cf77daf5d92d75ce2db95b4e10f080cb322e9d1 Mon Sep 17 00:00:00 2001 From: ak2k <19240940+ak2k@users.noreply.github.com> Date: Fri, 23 Oct 2026 00:03:48 -0400 Subject: [PATCH 1/2] flight-cli: test that a carrier name with a line break keeps one legend line Unit: work-bjun7 --- tests/test_carrier_legend_docs.py | 16 ++++++++++++++++ tests/test_gf_carrier_legend.py | 8 ++++++++ tests/test_matrix_search_carrier_legend.py | 7 +++++++ 3 files changed, 31 insertions(+) create mode 100644 tests/test_carrier_legend_docs.py diff --git a/tests/test_carrier_legend_docs.py b/tests/test_carrier_legend_docs.py new file mode 100644 index 00000000..27c4f0e0 --- /dev/null +++ b/tests/test_carrier_legend_docs.py @@ -0,0 +1,16 @@ +"""The routing memory says how the carrier legend keeps to one line.""" + +from __future__ import annotations + +from pathlib import Path + +_ROOT = Path(__file__).resolve().parent.parent + + +def test_memo_says_a_legend_name_cannot_break_the_line() -> None: + text = (_ROOT / "docs/memories/gf_routing_and_carriers.md").read_text() + memo = " ".join(text.split()) + assert ( + "collapses the whitespace runs of an entry, a newline and a tab included, to one " + "space, so a name cannot break the legend over two lines" + ) in memo diff --git a/tests/test_gf_carrier_legend.py b/tests/test_gf_carrier_legend.py index 0ebbc318..c55b598e 100644 --- a/tests/test_gf_carrier_legend.py +++ b/tests/test_gf_carrier_legend.py @@ -207,3 +207,11 @@ def test_a_search_prints_the_legend_under_its_table(gf_session: Callable[..., An legend = _legend(result.stdout.splitlines()) assert len(legend) == 1 assert "DL Delta Air Lines" in legend[0] + + +def test_a_name_google_sent_with_a_line_break_stays_on_the_legend_line( + monkeypatch: pytest.MonkeyPatch, +) -> None: + metal = LegAmenities(operating_carrier="EN", operating_carrier_name="Air\n\tDolomiti") + row = _row(("EN", "8858"), amenities={0: metal}) + assert _legend(_printed(monkeypatch, [row])) == ["Carriers: EN Air Dolomiti"] diff --git a/tests/test_matrix_search_carrier_legend.py b/tests/test_matrix_search_carrier_legend.py index 8c701422..5cee5f70 100644 --- a/tests/test_matrix_search_carrier_legend.py +++ b/tests/test_matrix_search_carrier_legend.py @@ -142,3 +142,10 @@ def test_codes_that_print_alike_are_one_legend_entry(monkeypatch: pytest.MonkeyP monkeypatch, [_solution(("DL", "Delta")), _solution(("D\u200bL", "Delta Air Lines"))] ) assert _legend(lines) == ["Carriers: DL Delta"] + + +def test_a_short_name_with_a_line_break_stays_on_the_legend_line( + monkeypatch: pytest.MonkeyPatch, +) -> None: + lines = _printed(monkeypatch, [_solution(("DL", "Delta\n\tAir Lines"), ("AA", "American"))]) + assert _legend(lines) == ["Carriers: DL Delta Air Lines · AA American"] From a00efe8f1863a3915357e4fb492a82f45ff86f9a Mon Sep 17 00:00:00 2001 From: ak2k <19240940+ak2k@users.noreply.github.com> Date: Fri, 23 Oct 2026 00:09:09 -0400 Subject: [PATCH 2/2] flight-cli: a carrier name with a line break keeps the legend on one line The Matrix and Google tables print their Carriers legend through one printer, which collapses each entry's whitespace runs, a newline and a tab included, to one space. Unit: work-bjun7 --- docs/memories/gf_routing_and_carriers.md | 5 +++++ src/flight_cli/cli.py | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/memories/gf_routing_and_carriers.md b/docs/memories/gf_routing_and_carriers.md index 663f0296..da5b78c1 100644 --- a/docs/memories/gf_routing_and_carriers.md +++ b/docs/memories/gf_routing_and_carriers.md @@ -320,3 +320,8 @@ shows, in the order the rows first show it. A code takes its full name from never used for a code sold for another operator (EN flies the LH flight, and LH is not "Air Dolomiti"). Under a codeshare relabel both codes on screen are named. Add a code to the map when a table shows one with no name. +The Matrix table prints the same line through `_print_matrix_carrier_legend`, +naming each code by Matrix's `shortName`. Both go through +`_print_carrier_legend_line`, which collapses the whitespace runs of an entry, a +newline and a tab included, to one space, so a name cannot break the legend over +two lines. diff --git a/src/flight_cli/cli.py b/src/flight_cli/cli.py index e48d7f47..4dfea2a3 100644 --- a/src/flight_cli/cli.py +++ b/src/flight_cli/cli.py @@ -5030,6 +5030,15 @@ def _render_search( _print_matrix_carrier_legend(shown) +def _print_carrier_legend_line(named: Mapping[str, str | None]) -> None: + """The one `Carriers:` line both tables print, each named code once. An entry's + whitespace runs, a newline and a tab included, collapse to one space so a name + cannot break the legend over two lines; a table with no named code prints none.""" + if any(named.values()): + entries = (" ".join(f"{code} {name}".split()) for code, name in named.items() if name) + console.print("[dim]Carriers: " + _safe_text(" · ".join(entries)) + "[/]") + + def _print_matrix_carrier_legend(shown: Sequence[Itinerary]) -> None: """The line under the itinerary table that names each carrier code its carriers column shows, in the order the rows first show them, as Matrix's `shortName` @@ -5045,12 +5054,7 @@ def _print_matrix_carrier_legend(shown: Sequence[Itinerary]) -> None: if code and named.get(code) is None: name = (carrier.short_name or "").translate(_CTRL).strip() named[code] = name or None - if any(named.values()): - console.print( - "[dim]Carriers: " - + _safe_text(" · ".join(f"{code} {name}" for code, name in named.items() if name)) - + "[/]" - ) + _print_carrier_legend_line(named) # ───────────────── legroom formatters (gflight-populated; Matrix slices noop) ── @@ -10866,12 +10870,7 @@ def _print_carrier_legend(members: list[Any], match_carriers: frozenset[str]) -> for shown in (raw_code,) if mf is None else (mf[:2].upper(), raw_code): if named.get(shown) is None: named[shown] = _carrier_name(shown, amenity) - if any(named.values()): - console.print( - "[dim]Carriers: " - + _safe_text(" · ".join(f"{code} {name}" for code, name in named.items() if name)) - + "[/]" - ) + _print_carrier_legend_line(named) def _gflight_route(legs: Any) -> str: