Fix TUI widgets color bleedthru
This commit is contained in:
@@ -23,6 +23,21 @@ class StaticConfig:
|
||||
return self._data
|
||||
|
||||
|
||||
class FakeTagTable:
|
||||
def __init__(self):
|
||||
self.rows = {}
|
||||
self._next_index = 0
|
||||
|
||||
def clear(self):
|
||||
self.rows.clear()
|
||||
|
||||
def add_row(self, *values):
|
||||
row_key = f"row-{self._next_index}"
|
||||
self._next_index += 1
|
||||
self.rows[row_key] = tuple(values)
|
||||
return row_key
|
||||
|
||||
|
||||
class ScreenSupportTests(unittest.TestCase):
|
||||
def make_context(self):
|
||||
return {
|
||||
@@ -81,6 +96,32 @@ class ScreenSupportTests(unittest.TestCase):
|
||||
controllers,
|
||||
)
|
||||
|
||||
def test_populate_tag_table_keeps_raw_values_outside_display_labels(self):
|
||||
table = FakeTagTable()
|
||||
|
||||
row_data = screen_support.populate_tag_table(
|
||||
table,
|
||||
{"BPS": 4835, "KEEP": "plain"},
|
||||
ignore_keys=["KEEP"],
|
||||
remove_keys=["BPS"],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
"row-0": ("BPS", "4835"),
|
||||
"row-1": ("KEEP", "plain"),
|
||||
},
|
||||
row_data,
|
||||
)
|
||||
self.assertEqual(
|
||||
("[red]BPS[/red]", "[red]4835[/red]"),
|
||||
table.rows["row-0"],
|
||||
)
|
||||
self.assertEqual(
|
||||
("[blue]KEEP[/blue]", "[blue]plain[/blue]"),
|
||||
table.rows["row-1"],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
325
tests/unit/test_tag_table_screen_state.py
Normal file
325
tests/unit/test_tag_table_screen_state.py
Normal file
@@ -0,0 +1,325 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
SRC_ROOT = Path(__file__).resolve().parents[2] / "src"
|
||||
|
||||
if str(SRC_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(SRC_ROOT))
|
||||
|
||||
|
||||
from ffx.audio_layout import AudioLayout # noqa: E402
|
||||
from ffx.iso_language import IsoLanguage # noqa: E402
|
||||
from ffx.logging_utils import get_ffx_logger # noqa: E402
|
||||
from ffx.media_details_screen import MediaDetailsScreen # noqa: E402
|
||||
from ffx.pattern_details_screen import PatternDetailsScreen # noqa: E402
|
||||
from ffx.show_descriptor import ShowDescriptor # noqa: E402
|
||||
from ffx.show_details_screen import ShowDetailsScreen # noqa: E402
|
||||
from ffx.shows_screen import ShowsScreen # noqa: E402
|
||||
from ffx.track_codec import TrackCodec # noqa: E402
|
||||
from ffx.track_descriptor import TrackDescriptor # noqa: E402
|
||||
from ffx.track_details_screen import TrackDetailsScreen # noqa: E402
|
||||
from ffx.track_type import TrackType # noqa: E402
|
||||
|
||||
|
||||
class FakeTagTable:
|
||||
def __init__(self):
|
||||
self.rows = {}
|
||||
self.cursor_coordinate = (0, 0)
|
||||
self._selected_row_key = None
|
||||
self._next_index = 0
|
||||
self._row_order = []
|
||||
|
||||
def clear(self):
|
||||
self.rows.clear()
|
||||
self._selected_row_key = None
|
||||
self._row_order.clear()
|
||||
|
||||
def add_row(self, *values):
|
||||
row_key = f"row-{self._next_index}"
|
||||
self._next_index += 1
|
||||
self.rows[row_key] = tuple(values)
|
||||
self._row_order.append(row_key)
|
||||
if self._selected_row_key is None:
|
||||
self._selected_row_key = row_key
|
||||
return row_key
|
||||
|
||||
def coordinate_to_cell_key(self, _coordinate):
|
||||
return self._selected_row_key, None
|
||||
|
||||
def select_row(self, row_key):
|
||||
self._selected_row_key = row_key
|
||||
|
||||
def get_row_index(self, row_key):
|
||||
return self._row_order.index(row_key)
|
||||
|
||||
def remove_row(self, row_key):
|
||||
self.rows.pop(row_key, None)
|
||||
if row_key in self._row_order:
|
||||
self._row_order.remove(row_key)
|
||||
if self._selected_row_key == row_key:
|
||||
self._selected_row_key = self._row_order[0] if self._row_order else None
|
||||
|
||||
def update_cell(self, row_key, column_key, value):
|
||||
row = list(self.rows[row_key])
|
||||
row[int(column_key)] = value
|
||||
self.rows[row_key] = tuple(row)
|
||||
|
||||
|
||||
class FakeMediaDescriptor:
|
||||
def __init__(self, track_descriptors):
|
||||
self._track_descriptors = list(track_descriptors)
|
||||
|
||||
def getTrackDescriptors(self):
|
||||
return list(self._track_descriptors)
|
||||
|
||||
|
||||
class FakeValueWidget:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
|
||||
class FakeInputWidget:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
|
||||
class FakeSelectionListWidget:
|
||||
def __init__(self, selected):
|
||||
self.selected = selected
|
||||
|
||||
|
||||
def make_track_descriptor(index, sub_index, track_type):
|
||||
return TrackDescriptor(
|
||||
index=index,
|
||||
sub_index=sub_index,
|
||||
track_type=track_type,
|
||||
codec_name=TrackCodec.UNKNOWN,
|
||||
audio_layout=AudioLayout.LAYOUT_UNDEFINED,
|
||||
)
|
||||
|
||||
|
||||
def make_show_descriptor(show_id, name="Show", year=2000):
|
||||
return ShowDescriptor(
|
||||
id=show_id,
|
||||
name=name,
|
||||
year=year,
|
||||
)
|
||||
|
||||
|
||||
class TagTableScreenStateTests(unittest.TestCase):
|
||||
def test_track_details_screen_reads_selected_tag_from_raw_row_mapping(self):
|
||||
screen = object.__new__(TrackDetailsScreen)
|
||||
screen.trackTagsTable = FakeTagTable()
|
||||
screen._TrackDetailsScreen__draftTrackTags = {
|
||||
"BPS": "4835",
|
||||
"KEEP_ME": "plain",
|
||||
}
|
||||
screen._TrackDetailsScreen__ignoreTrackKeys = ["KEEP_ME"]
|
||||
screen._TrackDetailsScreen__removeTrackKeys = ["BPS"]
|
||||
screen._TrackDetailsScreen__tagRowData = {}
|
||||
|
||||
screen.updateTags()
|
||||
|
||||
self.assertEqual(
|
||||
("[red]BPS[/red]", "[red]4835[/red]"),
|
||||
screen.trackTagsTable.rows["row-0"],
|
||||
)
|
||||
self.assertEqual(
|
||||
("BPS", "4835"),
|
||||
screen.getSelectedTag(),
|
||||
)
|
||||
|
||||
def test_track_details_screen_reads_select_values_from_widget_state(self):
|
||||
screen = object.__new__(TrackDetailsScreen)
|
||||
screen.context = {"logger": get_ffx_logger()}
|
||||
screen._TrackDetailsScreen__trackDescriptor = None
|
||||
screen._TrackDetailsScreen__patternId = 5
|
||||
screen._TrackDetailsScreen__index = 2
|
||||
screen._TrackDetailsScreen__subIndex = 0
|
||||
screen._TrackDetailsScreen__trackCodec = TrackCodec.UNKNOWN
|
||||
screen._TrackDetailsScreen__draftTrackTags = {"KEEP": "value"}
|
||||
|
||||
widgets = {
|
||||
"#type_select": FakeValueWidget(TrackType.AUDIO),
|
||||
"#audio_layout_select": FakeValueWidget(AudioLayout.LAYOUT_STEREO),
|
||||
"#language_select": FakeValueWidget(IsoLanguage.GERMAN),
|
||||
"#title_input": FakeInputWidget("German Audio"),
|
||||
"#dispositions_selection_list": FakeSelectionListWidget({0, 6}),
|
||||
}
|
||||
screen.query_one = lambda selector, _widget_type=None: widgets[selector]
|
||||
|
||||
descriptor = screen.getTrackDescriptorFromInput()
|
||||
|
||||
self.assertEqual(TrackType.AUDIO, descriptor.getType())
|
||||
self.assertEqual(AudioLayout.LAYOUT_STEREO, descriptor.getAudioLayout())
|
||||
self.assertEqual("deu", descriptor.getTags()["language"])
|
||||
self.assertEqual("German Audio", descriptor.getTitle())
|
||||
self.assertEqual("value", descriptor.getTags()["KEEP"])
|
||||
|
||||
def test_pattern_details_screen_reads_selected_track_from_row_mapping(self):
|
||||
first_track = make_track_descriptor(0, 0, TrackType.VIDEO)
|
||||
second_track = make_track_descriptor(1, 0, TrackType.SUBTITLE)
|
||||
|
||||
screen = object.__new__(PatternDetailsScreen)
|
||||
screen.tracksTable = FakeTagTable()
|
||||
screen._PatternDetailsScreen__draftTracks = [first_track, second_track]
|
||||
screen._PatternDetailsScreen__pattern = None
|
||||
screen._PatternDetailsScreen__trackRowData = {}
|
||||
|
||||
screen.updateTracks()
|
||||
screen.tracksTable.select_row("row-1")
|
||||
|
||||
self.assertIs(second_track, screen.getSelectedTrackDescriptor())
|
||||
|
||||
def test_pattern_details_screen_reads_selected_tag_from_raw_row_mapping(self):
|
||||
screen = object.__new__(PatternDetailsScreen)
|
||||
screen.tagsTable = FakeTagTable()
|
||||
screen._PatternDetailsScreen__pattern = None
|
||||
screen._PatternDetailsScreen__draftTags = {
|
||||
"BPS": "4835",
|
||||
"TITLE": "Deutsch [FN]",
|
||||
}
|
||||
screen._PatternDetailsScreen__ignoreGlobalKeys = ["TITLE"]
|
||||
screen._PatternDetailsScreen__removeGlobalKeys = ["BPS"]
|
||||
screen._PatternDetailsScreen__tagRowData = {}
|
||||
|
||||
screen.updateTags()
|
||||
|
||||
self.assertEqual(
|
||||
("[red]BPS[/red]", "[red]4835[/red]"),
|
||||
screen.tagsTable.rows["row-0"],
|
||||
)
|
||||
self.assertEqual(
|
||||
("BPS", "4835"),
|
||||
screen.getSelectedTag(),
|
||||
)
|
||||
|
||||
def test_media_details_screen_reads_selected_track_from_row_mapping(self):
|
||||
first_track = make_track_descriptor(0, 0, TrackType.VIDEO)
|
||||
second_track = make_track_descriptor(1, 0, TrackType.SUBTITLE)
|
||||
|
||||
screen = object.__new__(MediaDetailsScreen)
|
||||
screen.tracksTable = FakeTagTable()
|
||||
screen._MediaDetailsScreen__sourceMediaDescriptor = FakeMediaDescriptor(
|
||||
[first_track, second_track]
|
||||
)
|
||||
screen._MediaDetailsScreen__trackRowData = {}
|
||||
|
||||
screen.updateTracks()
|
||||
screen.tracksTable.select_row("row-1")
|
||||
|
||||
self.assertIs(second_track, screen.getSelectedTrackDescriptor())
|
||||
|
||||
def test_pattern_details_screen_reads_selected_shifted_season_from_row_mapping(self):
|
||||
screen = object.__new__(PatternDetailsScreen)
|
||||
screen.shiftedSeasonsTable = FakeTagTable()
|
||||
screen._PatternDetailsScreen__pattern = object()
|
||||
screen._PatternDetailsScreen__shiftedSeasonRowData = {}
|
||||
|
||||
row_key = screen.shiftedSeasonsTable.add_row("9", "1", "3", "1", "0")
|
||||
screen._PatternDetailsScreen__shiftedSeasonRowData[row_key] = {
|
||||
"id": 44,
|
||||
"original_season": 9,
|
||||
"first_episode": 1,
|
||||
"last_episode": 3,
|
||||
"season_offset": 1,
|
||||
"episode_offset": 0,
|
||||
}
|
||||
screen.shiftedSeasonsTable.rows[row_key] = ("broken", "ui", "values", "!", "?")
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
"id": 44,
|
||||
"original_season": 9,
|
||||
"first_episode": 1,
|
||||
"last_episode": 3,
|
||||
"season_offset": 1,
|
||||
"episode_offset": 0,
|
||||
},
|
||||
screen.getSelectedShiftedSeasonObjFromInput(),
|
||||
)
|
||||
|
||||
def test_show_details_screen_reads_selected_pattern_from_row_mapping(self):
|
||||
screen = object.__new__(ShowDetailsScreen)
|
||||
screen.patternTable = FakeTagTable()
|
||||
screen._ShowDetailsScreen__showDescriptor = make_show_descriptor(7, "Demo", 1999)
|
||||
screen._ShowDetailsScreen__patternRowData = {}
|
||||
|
||||
row_key = screen._add_pattern_row(pattern_id=11, pattern_text=r"^demo_(s[0-9]+e[0-9]+)\.mkv$")
|
||||
screen.patternTable.rows[row_key] = ("display text changed",)
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
"id": 11,
|
||||
"show_id": 7,
|
||||
"pattern": r"^demo_(s[0-9]+e[0-9]+)\.mkv$",
|
||||
},
|
||||
screen.getSelectedPatternDescriptor(),
|
||||
)
|
||||
|
||||
def test_show_details_screen_reads_selected_shifted_season_from_row_mapping(self):
|
||||
screen = object.__new__(ShowDetailsScreen)
|
||||
screen.shiftedSeasonsTable = FakeTagTable()
|
||||
screen._ShowDetailsScreen__shiftedSeasonRowData = {}
|
||||
|
||||
row_key = screen.shiftedSeasonsTable.add_row("1", "", "", "0", "0")
|
||||
screen._ShowDetailsScreen__shiftedSeasonRowData[row_key] = {
|
||||
"id": 3,
|
||||
"original_season": 1,
|
||||
"first_episode": -1,
|
||||
"last_episode": -1,
|
||||
"season_offset": 0,
|
||||
"episode_offset": 0,
|
||||
}
|
||||
screen.shiftedSeasonsTable.rows[row_key] = ("bad", "visible", "data", "x", "y")
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
"id": 3,
|
||||
"original_season": 1,
|
||||
"first_episode": -1,
|
||||
"last_episode": -1,
|
||||
"season_offset": 0,
|
||||
"episode_offset": 0,
|
||||
},
|
||||
screen.getSelectedShiftedSeasonObjFromInput(),
|
||||
)
|
||||
|
||||
def test_shows_screen_reads_selected_show_id_from_row_mapping(self):
|
||||
screen = object.__new__(ShowsScreen)
|
||||
screen.table = FakeTagTable()
|
||||
screen._ShowsScreen__showRowData = {}
|
||||
|
||||
row_key = screen._add_show_row(make_show_descriptor(4, "Mapped", 2011))
|
||||
screen.table.rows[row_key] = ("999", "Visible", "2099")
|
||||
|
||||
self.assertEqual(4, screen.getSelectedShowId())
|
||||
|
||||
def test_media_details_screen_reads_selected_show_from_row_mapping(self):
|
||||
screen = object.__new__(MediaDetailsScreen)
|
||||
screen.showsTable = FakeTagTable()
|
||||
screen._MediaDetailsScreen__showRowData = {}
|
||||
|
||||
placeholder_key = screen._add_show_row(None)
|
||||
show_key = screen._add_show_row(make_show_descriptor(8, "Real Show", 2020))
|
||||
screen.showsTable.select_row(show_key)
|
||||
screen.showsTable.rows[show_key] = ("oops", "display", "changed")
|
||||
|
||||
selected_show = screen.getSelectedShowDescriptor()
|
||||
|
||||
self.assertIsInstance(selected_show, ShowDescriptor)
|
||||
self.assertEqual(8, selected_show.getId())
|
||||
self.assertEqual(0, screen.getRowIndexFromShowId(-1))
|
||||
self.assertEqual(1, screen.getRowIndexFromShowId(8))
|
||||
|
||||
screen.removeShow(-1)
|
||||
self.assertNotIn(placeholder_key, screen._MediaDetailsScreen__showRowData)
|
||||
self.assertEqual(0, screen.getRowIndexFromShowId(8))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user