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
5 changes: 5 additions & 0 deletions docs/memories/gf_routing_and_carriers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
23 changes: 11 additions & 12 deletions src/flight_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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) ──
Expand Down Expand Up @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_carrier_legend_docs.py
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions tests/test_gf_carrier_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
7 changes: 7 additions & 0 deletions tests/test_matrix_search_carrier_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Loading