From 373f4eeb239005943701b3b8c88bf3ab7103e8e3 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Fri, 5 Apr 2024 21:12:41 +0100 Subject: [PATCH] Initial GUI test running. Test coverage: 42%. --- app/musicmuster.py | 42 +++-- tests/test_playlists.py | 360 ++++++++++++++++++++++++++++++++++++++ tests/x_test_playlists.py | 286 ------------------------------ 3 files changed, 390 insertions(+), 298 deletions(-) create mode 100644 tests/test_playlists.py delete mode 100644 tests/x_test_playlists.py diff --git a/app/musicmuster.py b/app/musicmuster.py index 84439d1..d12ae44 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -1310,19 +1310,37 @@ class Window(QMainWindow, Ui_MainWindow): with db.Session() as session: settings = Settings.all_as_dict(session) - record = settings["mainwindow_x"] - x = record.f_int or 1 - record = settings["mainwindow_y"] - y = record.f_int or 1 - record = settings["mainwindow_width"] - width = record.f_int or 1599 - record = settings["mainwindow_height"] - height = record.f_int or 981 + if "mainwindow_x" in settings: + record = settings["mainwindow_x"] + x = record.f_int or 1 + else: + x = 100 + if "mainwindow_y" in settings: + record = settings["mainwindow_y"] + y = record.f_int or 1 + else: + y = 100 + if "mainwindow_width" in settings: + record = settings["mainwindow_width"] + width = record.f_int or 1599 + else: + width = 100 + if "mainwindow_height" in settings: + record = settings["mainwindow_height"] + height = record.f_int or 981 + else: + height = 100 self.setGeometry(x, y, width, height) - record = settings["splitter_top"] - splitter_top = record.f_int or 256 - record = settings["splitter_bottom"] - splitter_bottom = record.f_int or 256 + if "splitter_top" in settings: + record = settings["splitter_top"] + splitter_top = record.f_int or 256 + else: + splitter_top = 100 + if "splitter_bottom" in settings: + record = settings["splitter_bottom"] + splitter_bottom = record.f_int or 256 + else: + splitter_bottom = 100 self.splitter.setSizes([splitter_top, splitter_bottom]) return diff --git a/tests/test_playlists.py b/tests/test_playlists.py new file mode 100644 index 0000000..1589499 --- /dev/null +++ b/tests/test_playlists.py @@ -0,0 +1,360 @@ +# Standard library imports +import datetime as dt +import os +import unittest + +# PyQt imports +from PyQt6.QtCore import Qt + +# Third party imports +import pytest +from pytestqt.plugin import QtBot # type: ignore + +# App imports +from app import helpers + +# Set up test database before importing db +# Mark subsequent lines to ignore E402, imports not at top of file +DB_FILE = "/tmp/mm.db" +if os.path.exists(DB_FILE): + os.unlink(DB_FILE) +os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE +from app.models import ( # noqa: E402 + db, + Carts, + NoteColours, + Playdates, + Playlists, + PlaylistRows, + Tracks, +) +from app import playlists +from app import musicmuster + + +# Custom fixture to adapt qtbot for use with unittest.TestCase +@pytest.fixture(scope="class") +def qtbot_adapter(qapp, request): + """Adapt qtbot fixture for usefixtures and unittest.TestCase""" + request.cls.qtbot = QtBot(request) + + +# Wrapper to handle setup/teardown operations +def with_updown(function): + def test_wrapper(self, *args, **kwargs): + if callable(getattr(self, 'up', None)): + self.up() + try: + function(self, *args, **kwargs) + finally: + if callable(getattr(self, 'down', None)): + self.down() + test_wrapper.__doc__ = function.__doc__ + return test_wrapper + + +# Apply the custom fixture to the test class +@pytest.mark.usefixtures("qtbot_adapter") +class MyTestCase(unittest.TestCase): + def up(self): + db.create_all() + self.widget = musicmuster.Window() + self.widget.show() + + def down(self): + db.drop_all() + + # @with_updown + # def test_some_property(self): + # with self.qtbot.waitSignal(self.widget.my_signal, timeout=300): + # self.widget.do_thing() + # self.assertEqual(self.widget.get_thing(), 'foo') + + @with_updown + def test_init(self): + """Just check we can create a playlist_tab""" + + with db.Session() as session: + playlist = Playlists(session, "test playlist") + # playlist_tab = playlists.PlaylistTab(self.widget, playlist.id) + + self.widget.create_playlist_tab(playlist) + with self.qtbot.waitExposed(self.widget): + # window.show() + # with self.qtbot.waitSignal(self.widget.my_signal, timeout=300): + # with qtbot.waitExposed(window): + self.widget.show() + + +# def seed2tracks(session): +# tracks = [ +# { +# "path": "testdata/isa.mp3", +# "title": "I'm so afraid", +# "artist": "Fleetwood Mac", +# "duration": 263000, +# "start_gap": 60, +# "fade_at": 236263, +# "silence_at": 260343, +# "mtime": 371900000, +# }, +# { +# "path": "testdata/mom.mp3", +# "title": "Man of Mystery", +# "artist": "The Shadows", +# "duration": 120000, +# "start_gap": 70, +# "fade_at": 115000, +# "silence_at": 118000, +# "mtime": 1642760000, +# }, +# ] + + # for track in tracks: + # db_track = models.Tracks(session=session, **track) + # session.add(db_track) + + # session.commit() + + + +# def test_save_and_restore(qtbot, session): +# """Playlist with one track, one note, save and restore""" + +# # Create playlist +# playlist = models.Playlists(session, "my playlist") +# playlist_tab = playlists.PlaylistTab(None, session, playlist.id) + +# # Insert a note +# note_text = "my note" +# note_row = 7 +# note = models.Notes(session, playlist.id, note_row, note_text) +# playlist_tab._insert_note(session, note) + +# # Add a track +# track_path = "/a/b/c" +# track = models.Tracks(session, track_path) +# # Inserting the track will also save the playlist +# playlist_tab.insert_track(session, track) + +# # We need to commit the session before re-querying +# session.commit() + +# # Retrieve playlist +# all_playlists = playlists.Playlists.get_open(session) +# assert len(all_playlists) == 1 +# retrieved_playlist = all_playlists[0] +# paths = [a.path for a in retrieved_playlist.tracks.values()] +# assert track_path in paths +# notes = [a.note for a in retrieved_playlist.notes] +# assert note_text in notes + + +# def test_meta_all_clear(qtbot, session): +# # Create playlist +# playlist = models.Playlists(session, "my playlist") +# playlist_tab = playlists.PlaylistTab(None, session, playlist.id) + +# # Add some tracks +# # Need to commit session after each one so that new row is found +# # for subsequent inserts +# track1_path = "/a/b/c" +# track1 = models.Tracks(session, track1_path) +# playlist_tab.insert_track(session, track1) +# session.commit() +# track2_path = "/d/e/f" +# track2 = models.Tracks(session, track2_path) +# playlist_tab.insert_track(session, track2) +# session.commit() +# track3_path = "/h/i/j" +# track3 = models.Tracks(session, track3_path) +# playlist_tab.insert_track(session, track3) +# session.commit() + +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [] +# assert playlist_tab._get_played_track_rows() == [] +# assert len(playlist_tab._get_unreadable_track_rows()) == 3 + + +# def test_meta(qtbot, session): +# # Create playlist +# playlist = playlists.Playlists(session, "my playlist") +# playlist_tab = playlists.PlaylistTab(None, session, playlist.id) + +# # Add some tracks +# track1_path = "/a/b/c" +# track1 = models.Tracks(session, track1_path) +# playlist_tab.insert_track(session, track1) +# session.commit() +# track2_path = "/d/e/f" +# track2 = models.Tracks(session, track2_path) +# playlist_tab.insert_track(session, track2) +# session.commit() +# track3_path = "/h/i/j" +# track3 = models.Tracks(session, track3_path) +# playlist_tab.insert_track(session, track3) +# session.commit() + +# assert len(playlist_tab._get_unreadable_track_rows()) == 3 + +# assert playlist_tab._get_played_track_rows() == [] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [] + +# playlist_tab._set_played_row(0) +# assert playlist_tab._get_played_track_rows() == [0] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [] + +# # Add a note +# note_text = "my note" +# note_row = 7 # will be added as row 3 +# note = models.Notes(session, playlist.id, note_row, note_text) +# playlist_tab._insert_note(session, note) + +# assert playlist_tab._get_played_track_rows() == [0] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [3] + +# playlist_tab._set_next_track_row(1) +# assert playlist_tab._get_played_track_rows() == [0] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() == 1 +# assert playlist_tab._get_notes_rows() == [3] + +# playlist_tab._set_current_track_row(2) +# assert playlist_tab._get_played_track_rows() == [0] +# assert playlist_tab._get_current_track_row() == 2 +# assert playlist_tab._get_next_track_row() == 1 +# assert playlist_tab._get_notes_rows() == [3] + +# playlist_tab._clear_played_row_status(0) +# assert playlist_tab._get_played_track_rows() == [] +# assert playlist_tab._get_current_track_row() == 2 +# assert playlist_tab._get_next_track_row() == 1 +# assert playlist_tab._get_notes_rows() == [3] + +# playlist_tab._meta_clear_next() +# assert playlist_tab._get_played_track_rows() == [] +# assert playlist_tab._get_current_track_row() == 2 +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [3] + +# playlist_tab._clear_current_track_row() +# assert playlist_tab._get_played_track_rows() == [] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [3] + +# # Test clearing again has no effect +# playlist_tab._clear_current_track_row() +# assert playlist_tab._get_played_track_rows() == [] +# assert playlist_tab._get_current_track_row() is None +# assert playlist_tab._get_next_track_row() is None +# assert playlist_tab._get_notes_rows() == [3] + + +# def test_clear_next(qtbot, session): +# # Create playlist +# playlist = models.Playlists(session, "my playlist") +# playlist_tab = playlists.PlaylistTab(None, session, playlist.id) + +# # Add some tracks +# track1_path = "/a/b/c" +# track1 = models.Tracks(session, track1_path) +# playlist_tab.insert_track(session, track1) +# session.commit() +# track2_path = "/d/e/f" +# track2 = models.Tracks(session, track2_path) +# playlist_tab.insert_track(session, track2) +# session.commit() + +# playlist_tab._set_next_track_row(1) +# assert playlist_tab._get_next_track_row() == 1 + +# playlist_tab.clear_next(session) +# assert playlist_tab._get_next_track_row() is None + + +# def test_get_selected_row(qtbot, monkeypatch, session): +# monkeypatch.setattr(musicmuster, "Session", session) +# monkeypatch.setattr(playlists, "Session", session) + +# # Create playlist and playlist_tab +# window = musicmuster.Window() +# playlist = models.Playlists(session, "test playlist") +# playlist_tab = playlists.PlaylistTab(window, session, playlist.id) + +# # Add some tracks +# track1_path = "/a/b/c" +# track1 = models.Tracks(session, track1_path) +# playlist_tab.insert_track(session, track1) +# session.commit() +# track2_path = "/d/e/f" +# track2 = models.Tracks(session, track2_path) +# playlist_tab.insert_track(session, track2) +# session.commit() + +# qtbot.addWidget(playlist_tab) +# with qtbot.waitExposed(window): +# window.show() +# row0_item0 = playlist_tab.item(0, 0) +# assert row0_item0 is not None +# rect = playlist_tab.visualItemRect(row0_item0) +# qtbot.mouseClick(playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()) +# row_number = playlist_tab.get_selected_row() +# assert row_number == 0 + + +# def test_set_next(qtbot, monkeypatch, session): +# monkeypatch.setattr(musicmuster, "Session", session) +# monkeypatch.setattr(playlists, "Session", session) +# seed2tracks(session) + +# playlist_name = "test playlist" +# # Create testing playlist +# window = musicmuster.Window() +# playlist = models.Playlists(session, playlist_name) +# playlist_tab = playlists.PlaylistTab(window, session, playlist.id) +# idx = window.tabPlaylist.addTab(playlist_tab, playlist_name) +# window.tabPlaylist.setCurrentIndex(idx) +# qtbot.addWidget(playlist_tab) + +# # Add some tracks +# track1 = models.Tracks.get_by_filename(session, "isa.mp3") +# track1_title = track1.title +# assert track1_title + +# playlist_tab.insert_track(session, track1) +# session.commit() +# track2 = models.Tracks.get_by_filename(session, "mom.mp3") +# playlist_tab.insert_track(session, track2) + +# with qtbot.waitExposed(window): +# window.show() + +# row0_item2 = playlist_tab.item(0, 2) +# assert row0_item2 is not None +# rect = playlist_tab.visualItemRect(row0_item2) +# qtbot.mouseClick(playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()) +# selected_title = playlist_tab.get_selected_title() +# assert selected_title == track1_title + +# qtbot.keyPress(playlist_tab.viewport(), "N", modifier=Qt.ControlModifier) +# qtbot.wait(1000) + + +# def test_kae(monkeypatch, session): +# # monkeypatch.setattr(dbconfig, "Session", session) +# monkeypatch.setattr(musicmuster, "Session", session) + +# musicmuster.Window.kae() +# # monkeypatch.setattr(musicmuster, "Session", session) +# # monkeypatch.setattr(dbconfig, "Session", session) +# # monkeypatch.setattr(models, "Session", session) +# # monkeypatch.setattr(playlists, "Session", session) diff --git a/tests/x_test_playlists.py b/tests/x_test_playlists.py deleted file mode 100644 index 90ba515..0000000 --- a/tests/x_test_playlists.py +++ /dev/null @@ -1,286 +0,0 @@ -from PyQt6.QtCore import Qt - -from app import playlists -from app import models -from app import musicmuster - - -def seed2tracks(session): - tracks = [ - { - "path": "testdata/isa.mp3", - "title": "I'm so afraid", - "artist": "Fleetwood Mac", - "duration": 263000, - "start_gap": 60, - "fade_at": 236263, - "silence_at": 260343, - "mtime": 371900000, - }, - { - "path": "testdata/mom.mp3", - "title": "Man of Mystery", - "artist": "The Shadows", - "duration": 120000, - "start_gap": 70, - "fade_at": 115000, - "silence_at": 118000, - "mtime": 1642760000, - }, - ] - - for track in tracks: - db_track = models.Tracks(session=session, **track) - session.add(db_track) - - session.commit() - - -def test_init(qtbot, session): - """Just check we can create a playlist_tab""" - - playlist = models.Playlists(session, "my playlist") - playlist_tab = playlists.PlaylistTab(None, session, playlist.id) - assert playlist_tab - - -def test_save_and_restore(qtbot, session): - """Playlist with one track, one note, save and restore""" - - # Create playlist - playlist = models.Playlists(session, "my playlist") - playlist_tab = playlists.PlaylistTab(None, session, playlist.id) - - # Insert a note - note_text = "my note" - note_row = 7 - note = models.Notes(session, playlist.id, note_row, note_text) - playlist_tab._insert_note(session, note) - - # Add a track - track_path = "/a/b/c" - track = models.Tracks(session, track_path) - # Inserting the track will also save the playlist - playlist_tab.insert_track(session, track) - - # We need to commit the session before re-querying - session.commit() - - # Retrieve playlist - all_playlists = playlists.Playlists.get_open(session) - assert len(all_playlists) == 1 - retrieved_playlist = all_playlists[0] - paths = [a.path for a in retrieved_playlist.tracks.values()] - assert track_path in paths - notes = [a.note for a in retrieved_playlist.notes] - assert note_text in notes - - -def test_meta_all_clear(qtbot, session): - # Create playlist - playlist = models.Playlists(session, "my playlist") - playlist_tab = playlists.PlaylistTab(None, session, playlist.id) - - # Add some tracks - # Need to commit session after each one so that new row is found - # for subsequent inserts - track1_path = "/a/b/c" - track1 = models.Tracks(session, track1_path) - playlist_tab.insert_track(session, track1) - session.commit() - track2_path = "/d/e/f" - track2 = models.Tracks(session, track2_path) - playlist_tab.insert_track(session, track2) - session.commit() - track3_path = "/h/i/j" - track3 = models.Tracks(session, track3_path) - playlist_tab.insert_track(session, track3) - session.commit() - - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [] - assert playlist_tab._get_played_track_rows() == [] - assert len(playlist_tab._get_unreadable_track_rows()) == 3 - - -def test_meta(qtbot, session): - # Create playlist - playlist = playlists.Playlists(session, "my playlist") - playlist_tab = playlists.PlaylistTab(None, session, playlist.id) - - # Add some tracks - track1_path = "/a/b/c" - track1 = models.Tracks(session, track1_path) - playlist_tab.insert_track(session, track1) - session.commit() - track2_path = "/d/e/f" - track2 = models.Tracks(session, track2_path) - playlist_tab.insert_track(session, track2) - session.commit() - track3_path = "/h/i/j" - track3 = models.Tracks(session, track3_path) - playlist_tab.insert_track(session, track3) - session.commit() - - assert len(playlist_tab._get_unreadable_track_rows()) == 3 - - assert playlist_tab._get_played_track_rows() == [] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [] - - playlist_tab._set_played_row(0) - assert playlist_tab._get_played_track_rows() == [0] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [] - - # Add a note - note_text = "my note" - note_row = 7 # will be added as row 3 - note = models.Notes(session, playlist.id, note_row, note_text) - playlist_tab._insert_note(session, note) - - assert playlist_tab._get_played_track_rows() == [0] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [3] - - playlist_tab._set_next_track_row(1) - assert playlist_tab._get_played_track_rows() == [0] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() == 1 - assert playlist_tab._get_notes_rows() == [3] - - playlist_tab._set_current_track_row(2) - assert playlist_tab._get_played_track_rows() == [0] - assert playlist_tab._get_current_track_row() == 2 - assert playlist_tab._get_next_track_row() == 1 - assert playlist_tab._get_notes_rows() == [3] - - playlist_tab._clear_played_row_status(0) - assert playlist_tab._get_played_track_rows() == [] - assert playlist_tab._get_current_track_row() == 2 - assert playlist_tab._get_next_track_row() == 1 - assert playlist_tab._get_notes_rows() == [3] - - playlist_tab._meta_clear_next() - assert playlist_tab._get_played_track_rows() == [] - assert playlist_tab._get_current_track_row() == 2 - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [3] - - playlist_tab._clear_current_track_row() - assert playlist_tab._get_played_track_rows() == [] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [3] - - # Test clearing again has no effect - playlist_tab._clear_current_track_row() - assert playlist_tab._get_played_track_rows() == [] - assert playlist_tab._get_current_track_row() is None - assert playlist_tab._get_next_track_row() is None - assert playlist_tab._get_notes_rows() == [3] - - -def test_clear_next(qtbot, session): - # Create playlist - playlist = models.Playlists(session, "my playlist") - playlist_tab = playlists.PlaylistTab(None, session, playlist.id) - - # Add some tracks - track1_path = "/a/b/c" - track1 = models.Tracks(session, track1_path) - playlist_tab.insert_track(session, track1) - session.commit() - track2_path = "/d/e/f" - track2 = models.Tracks(session, track2_path) - playlist_tab.insert_track(session, track2) - session.commit() - - playlist_tab._set_next_track_row(1) - assert playlist_tab._get_next_track_row() == 1 - - playlist_tab.clear_next(session) - assert playlist_tab._get_next_track_row() is None - - -def test_get_selected_row(qtbot, monkeypatch, session): - monkeypatch.setattr(musicmuster, "Session", session) - monkeypatch.setattr(playlists, "Session", session) - - # Create playlist and playlist_tab - window = musicmuster.Window() - playlist = models.Playlists(session, "test playlist") - playlist_tab = playlists.PlaylistTab(window, session, playlist.id) - - # Add some tracks - track1_path = "/a/b/c" - track1 = models.Tracks(session, track1_path) - playlist_tab.insert_track(session, track1) - session.commit() - track2_path = "/d/e/f" - track2 = models.Tracks(session, track2_path) - playlist_tab.insert_track(session, track2) - session.commit() - - qtbot.addWidget(playlist_tab) - with qtbot.waitExposed(window): - window.show() - row0_item0 = playlist_tab.item(0, 0) - assert row0_item0 is not None - rect = playlist_tab.visualItemRect(row0_item0) - qtbot.mouseClick(playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()) - row_number = playlist_tab.get_selected_row() - assert row_number == 0 - - -def test_set_next(qtbot, monkeypatch, session): - monkeypatch.setattr(musicmuster, "Session", session) - monkeypatch.setattr(playlists, "Session", session) - seed2tracks(session) - - playlist_name = "test playlist" - # Create testing playlist - window = musicmuster.Window() - playlist = models.Playlists(session, playlist_name) - playlist_tab = playlists.PlaylistTab(window, session, playlist.id) - idx = window.tabPlaylist.addTab(playlist_tab, playlist_name) - window.tabPlaylist.setCurrentIndex(idx) - qtbot.addWidget(playlist_tab) - - # Add some tracks - track1 = models.Tracks.get_by_filename(session, "isa.mp3") - track1_title = track1.title - assert track1_title - - playlist_tab.insert_track(session, track1) - session.commit() - track2 = models.Tracks.get_by_filename(session, "mom.mp3") - playlist_tab.insert_track(session, track2) - - with qtbot.waitExposed(window): - window.show() - - row0_item2 = playlist_tab.item(0, 2) - assert row0_item2 is not None - rect = playlist_tab.visualItemRect(row0_item2) - qtbot.mouseClick(playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()) - selected_title = playlist_tab.get_selected_title() - assert selected_title == track1_title - - qtbot.keyPress(playlist_tab.viewport(), "N", modifier=Qt.ControlModifier) - qtbot.wait(1000) - - -def test_kae(monkeypatch, session): - # monkeypatch.setattr(dbconfig, "Session", session) - monkeypatch.setattr(musicmuster, "Session", session) - - musicmuster.Window.kae() - # monkeypatch.setattr(musicmuster, "Session", session) - # monkeypatch.setattr(dbconfig, "Session", session) - # monkeypatch.setattr(models, "Session", session) - # monkeypatch.setattr(playlists, "Session", session)