From 2daefa932caff01406f1aef0c29b5056f963ac87 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sun, 26 Dec 2021 10:18:09 -0500 Subject: [PATCH] lib: Remove unused files These are no longer needed now that tagdb has been removed Implements #24 (Clean up lib/) Signed-off-by: Anna Schumaker --- lib/__init__.py | 6 +- lib/bus.py | 59 ---------- lib/counter.py | 22 ---- lib/fake.py | 24 ---- lib/metadata.py | 51 --------- lib/publisher.py | 19 ---- lib/tag.py | 146 ------------------------ lib/tagstore.py | 98 ---------------- lib/test_bus.py | 93 --------------- lib/test_counter.py | 20 ---- lib/test_metadata.py | 34 ------ lib/test_publisher.py | 30 ----- lib/test_tag.py | 256 ------------------------------------------ lib/test_tagstore.py | 167 --------------------------- lib/test_thread.py | 35 ------ lib/thread.py | 35 ------ 16 files changed, 1 insertion(+), 1094 deletions(-) delete mode 100644 lib/bus.py delete mode 100644 lib/counter.py delete mode 100644 lib/fake.py delete mode 100644 lib/metadata.py delete mode 100644 lib/publisher.py delete mode 100644 lib/tag.py delete mode 100644 lib/tagstore.py delete mode 100644 lib/test_bus.py delete mode 100644 lib/test_counter.py delete mode 100644 lib/test_metadata.py delete mode 100644 lib/test_publisher.py delete mode 100644 lib/test_tag.py delete mode 100644 lib/test_tagstore.py delete mode 100644 lib/test_thread.py delete mode 100644 lib/thread.py diff --git a/lib/__init__.py b/lib/__init__.py index d8fbe39..8c7669d 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -3,11 +3,7 @@ import gi gi.require_version("Gtk", "4.0") gi.require_version("Gst", "1.0") -from . import bus from . import data from . import filter -from . import publisher from . import settings -from . import tag -from . import tagstore -from . import thread +from . import version diff --git a/lib/bus.py b/lib/bus.py deleted file mode 100644 index cb70fd6..0000000 --- a/lib/bus.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -import threading -from gi.repository import GLib - -Start = publisher.Publisher() -RETRY = GLib.SOURCE_CONTINUE - -class Bus: - def __init__(self, milliseconds): - self.timeout = milliseconds - self.timeout_id = None - self.passengers = [ ] - self.lock = threading.Lock() - - def __do_board(self, func, *args): - with self.lock: - if (func, args) not in self.passengers: - self.passengers.append( (func, args) ) - if self.timeout_id == None: - self.timeout_id = GLib.timeout_add(self.timeout, self.run) - return True - return False - - def board(self, func, *args): - if self.__do_board(func, *args): - Start.publish(self) - - def clear(self): - with self.lock: - if self.timeout_id: - GLib.source_remove(self.timeout_id) - self.timeout_id = None - self.passengers.clear() - - def complete(self): - with self.lock: - for (func, args) in self.passengers: - func(*args) - - GLib.source_remove(self.timeout_id) - self.timeout_id = None - self.passengers.clear() - - def running(self): - with self.lock: - return self.timeout_id != None - - def run(self): - with self.lock: - (func, args) = self.passengers[0] - if func(*args) == RETRY: - return GLib.SOURCE_CONTINUE - - self.passengers.pop(0) - if len(self.passengers) == 0: - self.timeout_id = None - return GLib.SOURCE_REMOVE - return GLib.SOURCE_CONTINUE diff --git a/lib/counter.py b/lib/counter.py deleted file mode 100644 index e319468..0000000 --- a/lib/counter.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from gi.repository import Gtk - -class Counter(Gtk.Adjustment): - def __init__(self, min, max): - Gtk.Adjustment.__init__(self) - self.configure(value=min, lower=min, upper=max + 1, step_increment=1, - page_increment=1, page_size=1) - - def __change_value__(self, n): - value = self.get_value() - self.set_value(value + n) - - if self.get_value() == value: - return None - return self.get_value() - - def increment(self): - return self.__change_value__(1) - - def decrement(self): - return self.__change_value__(-1) diff --git a/lib/fake.py b/lib/fake.py deleted file mode 100644 index fc02af9..0000000 --- a/lib/fake.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from gi.repository import GObject - -tracks = { } - -class FakeTrack(GObject.GObject): - def __init__(self, n, tag=None): - GObject.GObject.__init__(self) - self.trackid = n - self.length = n - self.tag = tag - - def __int__(self): - return self.trackid - - def add_to_playlist(self, name): - self.tag.add_track(self) - - def remove_from_playlist(self, name): - self.tag.remove_track(self) - - -def Track(n, tag=None): - return tracks.setdefault((n,tag), FakeTrack(n, tag=tag)) diff --git a/lib/metadata.py b/lib/metadata.py deleted file mode 100644 index d30051c..0000000 --- a/lib/metadata.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -import mutagen -import re - -class Metadata: - def __init__(self, filepath): - self.path = filepath - self.file = None - - def __enter__(self): - self.file = mutagen.File(self.path) - return self - - def __exit__(self, exp_type, exp_value, traceback): - self.file = None - return exp_type == None - - def album(self): - return self.file.get("album", [ "Unknown Album" ])[0] - - def artist(self): - artist = self.file.get("artist", [ "Unknown Artist" ]) - return self.file.get("albumartist", artist)[0] - - def artistsort(self): - sort = self.file.get("artistsort", [ None ]) - return self.file.get("albumartistsort", sort)[0] - - def decade(self): - return (self.year() // 10) * 10 - - def discnumber(self): - return int(self.file.get("discnumber", [ 1 ])[0]) - - def genres(self): - genre = self.file.get("genre", [ "" ])[0] - return [ g.strip() for g in re.split(",|;|/|:", genre) ] - - def length(self): - return int(self.file.info.length) - - def title(self): - return self.file.get("title", [ "" ])[0] - - def tracknumber(self): - return int(self.file.get("tracknumber", [ 0 ])[0]) - - def year(self): - year = self.file.get("date", [ "0" ]) - year = self.file.get("originalyear", year)[0] - return int(re.match("\d+", year).group(0)) diff --git a/lib/publisher.py b/lib/publisher.py deleted file mode 100644 index 2516223..0000000 --- a/lib/publisher.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2020 (c) Anna Schumaker. - -class Publisher: - def __init__(self): - self.subscribers = set() - - def publish(self, *args): - funcs = self.subscribers.copy() - for func in funcs: - func(*args) - - def register(self, func): - self.subscribers.add(func) - - def reset(self): - self.subscribers.clear() - - def unregister(self, func): - self.subscribers.discard(func) diff --git a/lib/tag.py b/lib/tag.py deleted file mode 100644 index 0d28be2..0000000 --- a/lib/tag.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -import random -import threading - -class Tag: - def __init__(self, name, sort=None): - self.name = name - self.sort = sort.lower() if sort else str(name).lower() - self.current = -1 - self.runtime = 0 - self.loop = False - self.random = False - self.tracks = [ ] - self.widgets = None - self.lock = threading.Lock() - self.TrackAdded = publisher.Publisher() - self.TrackRemoved = publisher.Publisher() - - def __getitem__(self, n): - with self.lock: - if n < len(self.tracks): - return self.tracks[n] - return None - - def __getstate__(self): - with self.lock: - return { "name" : self.name, - "sort" : self.sort, - "current" : self.current, - "loop" : self.loop, - "random" : self.random, - "tracks" : [ t.trackid for t in self.tracks ] } - - def __len__(self): - with self.lock: - return len(self.tracks) - - def __lt__(self, rhs): - if not isinstance(rhs, SuperTag): - return self.sort < rhs.sort - if self == rhs.parent: - return True - return self.sort < rhs.parent.sort - - def __next_track__(self): - if self.loop == True and self.current >= len(self.tracks): - return 0 - return self.current + 1 - - def __random_track__(self): - i = 1 - length = len(self.tracks) - if len(self.tracks) >= 3: - i = random.randint(1, length - 1) - return (self.current + i) % (1 if length == 0 else length) - - def __setstate__(self, state): - self.name = state["name"] - self.sort = state["sort"] - self.current = state["current"] - self.loop = state["loop"] - self.random = state["random"] - self.tracks = state["tracks"] - self.runtime = 0 - self.widgets = None - self.lock = threading.Lock() - self.TrackAdded = publisher.Publisher() - self.TrackRemoved = publisher.Publisher() - - def __str__(self): - return self.name - - def add_track(self, track): - with self.lock: - if track in self.tracks: - return - pos = len(self.tracks) - self.tracks.append(track) - self.runtime += track.length - self.TrackAdded.publish(self, track, pos) - - def can_loop(self): return True - def can_random(self): return True - - def get_header(self): - return self.sort[0].upper() if len(self.sort) > 0 else "" - - def init_track(self, track): - with self.lock: - try: - i = self.tracks.index(track.trackid) - self.tracks[i] = track - self.runtime += track.length - except Exception as e: - pass - - def next(self): - with self.lock: - if self.random == True: - self.current = self.__random_track__() - else: - self.current = self.__next_track__() - - if self.current < len(self.tracks): - return self.tracks[self.current] - return None - - def remove_track(self, track): - with self.lock: - pos = self.tracks.index(track) - self.tracks.remove(track) - self.runtime -= track.length - self.TrackRemoved.publish(self, track, pos) - - def stacked(self): - with self.lock: - if self.current >= len(self.tracks): - self.current = -1 - - def track_selected(self, track): - with self.lock: - self.current = self.tracks.index(track) - track.add_to_playlist("Previous") - - -class SuperTag(Tag): - def __init__(self, parent, name, sort=None): - Tag.__init__(self, name, sort) - self.parent = parent - - def __getstate__(self): - state = Tag.__getstate__(self) - state["parent"] = self.parent - return state - - def __lt__(self, rhs): - if not isinstance(rhs, SuperTag): - return self.parent.sort < rhs.sort - if self.parent != rhs.parent: - return self.parent < rhs.parent - return self.sort < rhs.sort - - def __setstate__(self, state): - Tag.__setstate__(self, state) - self.parent = state["parent"] diff --git a/lib/tagstore.py b/lib/tagstore.py deleted file mode 100644 index bc6f8ce..0000000 --- a/lib/tagstore.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -from . import tag -import threading - -class TagStore: - def __init__(self): - self.store = dict() - self.lock = threading.Lock() - self.Added = publisher.Publisher() - self.Removed = publisher.Publisher() - - def __add_tag__(self, name, sort, track): - t = self.__get_tag__(name, sort) - if track: - t.add_track(track) - return t - - def __alloc_tag__(self, name, sort): - return tag.Tag(name, sort) - - def __getitem__(self, name): - with self.lock: - return self.store.get(name) - - def __getstate__(self): - with self.lock: - return { "store" : self.store } - - def __get_tag__(self, name, sort): - with self.lock: - if (t := self.store.get(name)) != None: - return t - t = self.__alloc_tag__(name, sort) - self.store[name] = t - self.Added.publish(t) - return t - - def __len__(self): - with self.lock: - return len(self.store) - - def __pop_tag__(self, t): - self.store.pop(t.name) - - def __setstate__(self, state): - self.store = state["store"] - self.lock = threading.Lock() - self.Added = publisher.Publisher() - self.Removed = publisher.Publisher() - - def add(self, name, track=None, sort=None): - return self.__add_tag__(name.strip(), sort, track) - - def init_track(self, name, track): - with self.lock: - if (t := self.store.get(name)) != None: - t.init_track(track) - return t - - def remove(self, t, track=None): - if track: - t.remove_track(track) - if (track == None or len(t) == 0) and t in self.store.values(): - with self.lock: - self.__pop_tag__(t) - self.Removed.publish(t) - - def reset(self): - with self.lock: - self.store.clear() - self.Added.reset() - self.Removed.reset() - - def tags(self): - with self.lock: - for (name, tag) in self.store.items(): - yield tag - - -class TagSuperStore(TagStore): - def __alloc_tag__(self, key, sort): - return tag.SuperTag(key[0], key[1], sort) - - def __pop_tag__(self, t): - self.store.pop((t.parent, t.name)) - - def add(self, parent, name, track, sort=None): - return super().__add_tag__((parent, name.strip()), sort, track) - - def init_track(self, parent, name, track): - return super().init_track((parent, name), track) - - def tags(self, parent=None): - with self.lock: - for (name, tag) in self.store.items(): - if parent == None or tag.parent == parent: - yield tag diff --git a/lib/test_bus.py b/lib/test_bus.py deleted file mode 100644 index 1588896..0000000 --- a/lib/test_bus.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import bus -from . import publisher -from gi.repository import GLib -import threading -import time -import unittest - -main_context = GLib.main_context_default() - -class TestBus(unittest.TestCase): - def setUp(self): - self.count = 0 - self.start = 0 - self.retry = False - bus.Start.register(self.cb_start) - - def tearDown(self): - bus.Start.unregister(self.cb_start) - - def cb_start(self, bus): - self.start += 1 - - def cb_one(self): - self.count += 1 - - def cb_two(self, arg): - self.count = arg - - def cb_retry(self, arg): - self.count = arg - return bus.RETRY if self.retry == True else None - - def test_bus_init(self): - self.assertEqual(bus.RETRY, GLib.SOURCE_CONTINUE) - - b = bus.Bus(100) - self.assertEqual(b.timeout, 100) - self.assertEqual(b.passengers, [ ]) - self.assertIsNone(b.timeout_id) - self.assertIsInstance(b.lock, type(threading.Lock())) - - self.assertIsInstance(bus.Start, publisher.Publisher) - - def test_bus_board(self): - b = bus.Bus(100) - b.board(self.cb_one) - b.board(self.cb_one) - - self.assertEqual(b.passengers, [ (self.cb_one,()) ]) - self.assertIsNotNone(b.timeout_id) - self.assertTrue(b.running()) - self.assertEqual(self.start, 1) - - time.sleep(0.1) - while main_context.iteration(may_block=False): pass - - self.assertEqual(self.count, 1) - self.assertIsNone(b.timeout_id) - self.assertFalse(b.running()) - - def test_bus_clear(self): - b = bus.Bus(100) - b.clear() - - for i in range(100): - b.board(self.cb_one) - - b.clear() - self.assertEqual(b.passengers, [ ]) - self.assertIsNone(b.timeout_id) - - def test_bus_complete(self): - b = bus.Bus(100) - for i in range(100): - b.board(self.cb_two, i) - - b.complete() - self.assertEqual(b.passengers, [ ]) - self.assertEqual(self.count, i) - self.assertIsNone(b.timeout_id) - - def test_bus_retry(self): - b = bus.Bus(10) - b.board(self.cb_retry, 1) - b.board(self.cb_retry, 2) - - self.retry = True - b.run() - self.assertEqual(b.passengers, [ (self.cb_retry, (1,)), (self.cb_retry, (2,)) ]) - - b.complete() - self.assertEqual(b.passengers, [ ]) diff --git a/lib/test_counter.py b/lib/test_counter.py deleted file mode 100644 index a3e35a5..0000000 --- a/lib/test_counter.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import counter -from gi.repository import Gtk -import unittest - -class TestCounter(unittest.TestCase): - def test_counter(self): - c = counter.Counter(1, 10) - - self.assertIsInstance(c, Gtk.Adjustment) - - self.assertEqual(c.get_lower(), 1) - self.assertEqual(c.get_upper(), 11) - self.assertEqual(c.get_value(), 1) - - for i in [ 2, 3, 4, 5, 6, 7, 8, 9, 10, None ]: - self.assertEqual(c.increment(), i) - - for i in [ 9, 8, 7, 6, 5, 4, 3, 2, 1, None ]: - self.assertEqual(c.decrement(), i) diff --git a/lib/test_metadata.py b/lib/test_metadata.py deleted file mode 100644 index 52d050b..0000000 --- a/lib/test_metadata.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import metadata -import pathlib -import unittest - -test_tracks = pathlib.Path("./data/Test Album") -track_01 = test_tracks / "01 - Test Track.ogg" -track_02 = test_tracks / "02 - Test {Disc 2}.ogg" - -class TestMetadata(unittest.TestCase): - def test_metadata_init(self): - mdf = metadata.Metadata(track_01) - self.assertEqual(mdf.path, track_01) - self.assertIsNone(mdf.file) - - def test_metadata_track_01(self): - with metadata.Metadata(track_01) as mdf: - self.assertEqual(mdf.album(), "Test Album") - self.assertEqual(mdf.artist(), "Test Artist") - self.assertEqual(mdf.artistsort(), "Artist, Test") - self.assertEqual(mdf.decade(), 2010) - self.assertEqual(mdf.discnumber(), 1) - self.assertEqual(mdf.genres(), [ "Test" ]) - self.assertEqual(mdf.length(), 10) - self.assertEqual(mdf.title(), "Test Track") - self.assertEqual(mdf.tracknumber(), 1) - self.assertEqual(mdf.year(), 2019) - - def test_metadata_track_02(self): - with metadata.Metadata(track_02) as mdf: - self.assertEqual(mdf.artist(), "Test Album Artist") - self.assertEqual(mdf.artistsort(), "Album Artist, Test") - self.assertEqual(mdf.genres(), [ "Test", "Genre", "List" ]) - self.assertEqual(mdf.year(), 2019) diff --git a/lib/test_publisher.py b/lib/test_publisher.py deleted file mode 100644 index 9b14983..0000000 --- a/lib/test_publisher.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2020 (c) Anna Schumaker. -from . import publisher -import unittest - -class TestPublisher(unittest.TestCase): - def on_test(self, text): - self.test_arg = text - - def test_publisher_init(self): - pub = publisher.Publisher() - self.assertIsInstance(pub.subscribers, set) - self.assertEqual(pub.subscribers, set()) - - def test_publisher_register(self): - pub = publisher.Publisher() - pub.register(self.on_test) - self.assertEqual(pub.subscribers, { self.on_test }) - - pub.unregister(self.on_test) - self.assertEqual(pub.subscribers, set()) - - pub.subscribers = set([ 1, 2, 3 ]) - pub.reset() - self.assertEqual(pub.subscribers, set()) - - def test_publisher_publish(self): - pub = publisher.Publisher() - pub.register(self.on_test) - pub.publish("Test Arg") - self.assertEqual(self.test_arg, "Test Arg") diff --git a/lib/test_tag.py b/lib/test_tag.py deleted file mode 100644 index 133649b..0000000 --- a/lib/test_tag.py +++ /dev/null @@ -1,256 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -from . import tag -from . import fake -import random -import threading -import unittest - - -class TestTag(unittest.TestCase): - def setUp(self): - self.changed = None - - def callback_func(self, tag, track, pos): - self.changed = (tag, track, pos) - - def test_tag_init(self): - t = tag.Tag("test") - self.assertEqual(t.name, "test") - self.assertEqual(t.sort, "test") - self.assertEqual(t.current, -1) - self.assertEqual(t.runtime, 0) - self.assertEqual(t.tracks, [ ]) - self.assertFalse(t.loop) - self.assertFalse(t.random) - self.assertTrue( t.can_loop()) - self.assertTrue( t.can_random()) - self.assertIsNone(t.widgets) - self.assertIsInstance(t.lock, type(threading.Lock())) - self.assertIsInstance(t.TrackAdded, publisher.Publisher) - self.assertIsInstance(t.TrackRemoved, publisher.Publisher) - - self.assertEqual(str(t), "test") - - def test_tag_len(self): - t = tag.Tag("Test") - self.assertEqual(len(t), 0) - t.tracks = [ fake.Track(i) for i in range(5) ] - self.assertEqual(len(t), 5) - - def test_tag_lt(self): - a = tag.Tag("A") - b = tag.Tag("B") - c = tag.Tag("C") - - self.assertTrue( a < b) - self.assertFalse(b < a) - self.assertFalse(a < a) - - a2 = tag.SuperTag(b, "A") - self.assertTrue(a < a2) - self.assertTrue(b < a2) - self.assertTrue(a2 < c) - - def test_tag_header(self): - self.assertEqual(tag.Tag("Test").get_header(), "T") - self.assertEqual(tag.Tag("Test", "sort").get_header(), "S") - self.assertEqual(tag.Tag("").get_header(), "") - - def test_tag_state(self): - t = tag.Tag("test") - tracks = [ fake.Track(i) for i in range(5) ] - t.tracks = tracks - - state = t.__getstate__() - self.assertEqual(set(state.keys()), - set([ "name", "sort", "current", "loop", "random", "tracks" ])) - self.assertEqual(state["name"], "test") - self.assertEqual(state["sort"], "test") - self.assertEqual(state["current"], -1) - self.assertEqual(state["tracks"], [ 0, 1, 2, 3, 4 ]) - self.assertFalse(state["loop"]) - self.assertFalse(state["random"]) - - state["sort"] = "sort" - state["current"] = 42 - - t.__dict__.clear() - t.__setstate__(state) - self.assertEqual(t.name, "test") - self.assertEqual(t.sort, "sort") - self.assertEqual(t.current, 42) - self.assertEqual(t.runtime, 0) - self.assertEqual(t.tracks, [ 0, 1, 2, 3, 4 ]) - self.assertEqual(t.widgets, None) - self.assertFalse(t.loop) - self.assertFalse(t.random) - self.assertIsInstance(t.lock, type(threading.Lock())) - self.assertIsInstance(t.TrackAdded, publisher.Publisher) - self.assertIsInstance(t.TrackRemoved, publisher.Publisher) - - for track in tracks: - t.init_track(track) - self.assertEqual(t.tracks, tracks) - self.assertEqual(t.runtime, 10) - - def test_tag_add_track(self): - t = tag.Tag("test") - t.TrackAdded.register(self.callback_func) - - self.assertIsNone(t[0]) - t.add_track(fake.Track(1)) - self.assertEqual(t[0], fake.Track(1)) - self.assertEqual(t.tracks, [ fake.Track(1) ]) - self.assertEqual(self.changed, (t, fake.Track(1), 0)) - self.assertEqual(t.runtime, 1) - - t.add_track(fake.Track(2)) - self.assertEqual(t[1], fake.Track(2)) - self.assertEqual(t.tracks, [ fake.Track(1), fake.Track(2) ]) - self.assertEqual(self.changed, (t, fake.Track(2), 1)) - self.assertEqual(t.runtime, 3) - - t.add_track(fake.Track(1)) - self.assertEqual(t.tracks, [ fake.Track(1), fake.Track(2) ]) - self.assertEqual(self.changed, (t, fake.Track(2), 1)) - self.assertEqual(t.runtime, 3) - - def test_tag_remove_track(self): - t = tag.Tag("test") - t.add_track(fake.Track(1)) - t.add_track(fake.Track(2)) - t.TrackRemoved.register(self.callback_func) - - t.remove_track(fake.Track(1)) - self.assertEqual(t.tracks, [ fake.Track(2) ]) - self.assertEqual(self.changed, (t, fake.Track(1), 0)) - self.assertEqual(t.runtime, 2) - - t.remove_track(fake.Track(2)) - self.assertEqual(t.tracks, [ ]) - self.assertEqual(self.changed, (t, fake.Track(2), 0)) - self.assertEqual(t.runtime, 0) - - def test_tag_next(self): - t = tag.Tag("test") - t.tracks = [ 1, 2, 3 ] - - self.assertEqual(t.next(), 1) - self.assertEqual(t.current, 0) - - self.assertEqual(t.next(), 2) - self.assertEqual(t.current, 1) - - self.assertEqual(t.next(), 3) - self.assertEqual(t.current, 2) - - self.assertIsNone(t.next()) - self.assertEqual(t.current, 3) - - t.loop = True - self.assertEqual(t.next(), 1) - self.assertEqual(t.current, 0) - - def test_tag_random_next(self): - t = tag.Tag("test") - t.tracks = [ 0, 1, 2, 3, 4, 5 ] - t.random = True - - # Expected randint(): 5, 3, 2, 5, 5, 5 - random.seed(20210318) - self.assertEqual(t.next(), 4) # -1 + 5 - self.assertEqual(t.next(), 1) # (4 + 3) % 6 = 7 % 6 - self.assertEqual(t.next(), 3) # 1 + 2 - self.assertEqual(t.next(), 2) # (3 + 5) % 6 = 8 % 6 - self.assertEqual(t.next(), 1) # (2 + 5) % 6 = 7 % 6 - self.assertEqual(t.next(), 0) # (1 + 5) % 6 = 0 - - t.tracks = [ ] - self.assertIsNone(t.next()) - - t.tracks = [ 0 ] - self.assertEqual(t.next(), 0) - self.assertEqual(t.next(), 0) - - t.tracks = [ 0, 1 ] - t.current = -1 - self.assertEqual(t.next(), 0) - self.assertEqual(t.next(), 1) - self.assertEqual(t.next(), 0) - self.assertEqual(t.next(), 1) - - def test_tag_track_selected(self): - t = tag.Tag("test") - p = tag.Tag("Previous") - t.tracks = [ fake.Track(0, p), fake.Track(1, p), fake.Track(2, p) ] - - t.track_selected(fake.Track(2, p)) - self.assertEqual(t.current, 2) - self.assertIn(fake.Track(2, p), p.tracks) - - t.track_selected(fake.Track(1, p)) - self.assertEqual(t.current, 1) - self.assertIn(fake.Track(1, p), p.tracks) - - t.track_selected(fake.Track(0, p)) - self.assertEqual(t.current, 0) - self.assertIn(fake.Track(0, p), p.tracks) - - def test_tag_stacked(self): - t = tag.Tag("test") - t.tracks = [ 0, 1, 2 ] - - t.current = 3 - t.stacked() - self.assertEqual(t.current, -1) - - t.current = 1 - t.stacked() - self.assertEqual(t.current, 1) - - -class TestSuperTag(unittest.TestCase): - def test_super_tag(self): - parent = tag.Tag("parent") - st = tag.SuperTag(parent, "test", "sort") - st.tracks = [ fake.Track(i) for i in range(5) ] - - self.assertIsInstance(st, tag.Tag) - self.assertEqual(st.parent, parent) - - state = st.__getstate__() - self.assertEqual(state["name"], "test") - self.assertEqual(state["sort"], "sort") - self.assertEqual(state["current"], -1) - self.assertEqual(state["tracks"], [ 0, 1, 2, 3, 4 ]) - self.assertEqual(state["parent"], parent) - - st.__dict__.clear() - st.__setstate__(state) - self.assertEqual(st.name, "test") - self.assertEqual(st.sort, "sort") - self.assertEqual(st.tracks, [ 0, 1, 2, 3, 4 ]) - self.assertEqual(st.widgets, None) - self.assertEqual(st.parent, parent) - self.assertIsInstance(st.lock, type(threading.Lock())) - - def test_super_tag_lt(self): - A = tag.Tag("A") - B = tag.Tag("B") - C = tag.Tag("C") - - aa = tag.SuperTag(A, "A") - ba = tag.SuperTag(B, "A") - bb = tag.SuperTag(B, "B") - ca = tag.SuperTag(C, "A") - - lst = [ A, aa, B, ba, bb, C, ca ] - for i, t in enumerate(lst): - for u in lst[i+1:]: - self.assertTrue(t < u) - - lst = [ ca, C, bb, ba, B, aa, A ] - for i, t in enumerate(lst): - for u in lst[i+1:]: - self.assertFalse(t < u) diff --git a/lib/test_tagstore.py b/lib/test_tagstore.py deleted file mode 100644 index 135986d..0000000 --- a/lib/test_tagstore.py +++ /dev/null @@ -1,167 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import fake -from . import publisher -from . import tag -from . import tagstore -import threading -import unittest - -class TestTagStore(unittest.TestCase): - def setUp(self): - self.added = None - self.removed = None - - def on_store_added(self, tag): - self.added = tag - - def on_store_removed(self, tag): - self.removed = tag - - def test_tag_store(self): - store = tagstore.TagStore() - self.assertEqual(store.store, { }) - self.assertIsInstance(store.lock, type(threading.Lock())) - self.assertIsInstance(store.Added, publisher.Publisher) - self.assertIsInstance(store.Removed, publisher.Publisher) - - def test_tag_store_add_remove(self): - store = tagstore.TagStore() - store.Added.register(self.on_store_added) - store.Removed.register(self.on_store_removed) - - tag = store.add("test", fake.Track(1)) - self.assertEqual(self.added, tag) - self.assertEqual(tag.tracks, [ fake.Track(1) ]) - - self.added = None - self.assertEqual(store.add("test ", fake.Track(2)), tag) - self.assertEqual(tag.tracks, [ fake.Track(1), fake.Track(2) ]) - self.assertIsNone(self.added) - - store.remove(tag, fake.Track(1)) - self.assertEqual(tag.tracks, [ fake.Track(2) ]) - self.assertIn("test", store.store.keys()) - self.assertIsNone(self.removed) - - store.remove(tag, fake.Track(2)) - self.assertEqual(tag.tracks, [ ]) - self.assertNotIn("test", store.store.keys()) - self.assertEqual(self.removed, tag) - - def test_tag_store_add_remove_none(self): - store = tagstore.TagStore() - tag = store.add("test") - self.assertEqual(tag.tracks, [ ]) - - tag.add_track(fake.Track(1)) - tag.add_track(fake.Track(2)) - - store.remove(tag) - self.assertNotIn("test", store.store.keys()) - - def test_tag_store_add_remove_sort(self): - store = tagstore.TagStore() - tag = store.add("test", sort="sort") - self.assertEqual(tag.sort, "sort") - - def test_tag_store_items(self): - store = tagstore.TagStore() - self.assertEqual(len(store), 0) - - tag1 = store.add("test1", fake.Track(1)) - tag2 = store.add("test2", fake.Track(2)) - tag3 = store.add("test3", fake.Track(3)) - - self.assertEqual(len(store), 3) - self.assertEqual( store["test1"], tag1) - self.assertEqual( store["test2"], tag2) - self.assertEqual( store["test3"], tag3) - self.assertIsNone(store["test4"]) - - result = [ tag for tag in store.tags() ] - self.assertEqual(len(result), 3) - self.assertIn(tag1, result) - self.assertIn(tag2, result) - self.assertIn(tag3, result) - - def test_tag_store_reset(self): - store = tagstore.TagStore() - tag = store.add("test", fake.Track(1)) - store.Added.register(self.on_store_added) - store.Removed.register(self.on_store_removed) - - store.reset() - self.assertNotIn(tag.name, store.store.keys()) - self.assertEqual(store.Added.subscribers, set()) - self.assertEqual(store.Removed.subscribers, set()) - - def test_tag_store_state(self): - store = tagstore.TagStore() - track = fake.Track(1) - tag = store.add("test", track) - - state = store.__getstate__() - self.assertEqual(set(state.keys()), set([ "store" ])) - - store.__dict__.clear() - store.__setstate__(state) - self.assertEqual(store.store, { "test" : tag }) - self.assertIsInstance(store.lock, type(threading.Lock())) - self.assertIsInstance(store.Added, publisher.Publisher) - self.assertIsInstance(store.Removed, publisher.Publisher) - - self.assertEqual(store.init_track("test", track), tag) - self.assertEqual(tag.tracks, [ track ]) - - -class TestTagSuperStore(unittest.TestCase): - def test_tag_superstore(self): - store = tagstore.TagStore() - superstore = tagstore.TagSuperStore() - self.assertIsInstance(superstore, tagstore.TagStore) - - parent = store.add("parent", fake.Track(1)) - supertag = superstore.add(parent, "test ", fake.Track(1)) - self.assertIsInstance(supertag, tag.SuperTag) - self.assertEqual(supertag.name, "test") - self.assertEqual(supertag.tracks, [ fake.Track(1) ]) - self.assertEqual(supertag.parent, parent) - - superstore.remove(supertag, fake.Track(1)) - self.assertEqual(supertag.tracks, [ ]) - self.assertNotIn("test", superstore.store.keys()) - - def test_tag_superstore_items(self): - store = tagstore.TagStore() - superstore = tagstore.TagSuperStore() - - parent1 = store.add("parent1", fake.Track(1)) - parent2 = store.add("parent2", fake.Track(2)) - tag1 = superstore.add(parent1, "test1", fake.Track(1)) - tag2 = superstore.add(parent1, "test2", fake.Track(2)) - tag3 = superstore.add(parent2, "test3", fake.Track(3)) - - self.assertEqual(len(superstore), 3) - self.assertEqual( superstore[parent1, "test1"], tag1) - self.assertEqual( superstore[parent1, "test2"], tag2) - self.assertEqual( superstore[parent2, "test3"], tag3) - self.assertIsNone(superstore[parent2, "test2"]) - - result = [ tag for tag in superstore.tags(parent1) ] - self.assertEqual(result, [ tag1, tag2 ]) - result = [ tag for tag in superstore.tags(parent2) ] - self.assertEqual(result, [ tag3 ]) - result = [ tag for tag in superstore.tags() ] - self.assertEqual(result, [ tag1, tag2, tag3 ]) - - def test_tag_superstore_init_track(self): - store = tagstore.TagStore() - superstore = tagstore.TagSuperStore() - - track = fake.Track(1) - parent = store.add("test") - tag = superstore.add(parent, "test", track) - tag.tracks = [ 1 ] - - self.assertEqual(superstore.init_track(parent, "test", track), tag) - self.assertEqual(tag.tracks, [ track ]) diff --git a/lib/test_thread.py b/lib/test_thread.py deleted file mode 100644 index 9f99b82..0000000 --- a/lib/test_thread.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -from . import thread -import threading -import unittest - -class TestThread(unittest.TestCase): - def setUp(self): - self.started = None - self.called = False - self.thread = thread.Thread(self.thread_func) - - def thread_func(self): - self.assertIsNotNone(self.thread.thread) - self.called = True - - def on_thread_start(self, thread): - self.started = thread - - def test_thread(self): - self.assertIsInstance(thread.Start, publisher.Publisher) - thread.Start.register(self.on_thread_start) - - self.assertIsInstance(self.thread.lock, type(threading.Lock())) - self.assertEqual(self.thread.func, self.thread_func) - self.assertIsNone(self.thread.thread) - self.assertFalse(self.thread.running()) - - self.assertEqual(self.thread(), self.thread) - self.thread.join() - - self.assertTrue(self.called) - self.assertFalse(self.thread.running()) - self.assertEqual(self.started, self.thread) - self.assertIsNone(self.thread.thread) diff --git a/lib/thread.py b/lib/thread.py deleted file mode 100644 index 44e79bd..0000000 --- a/lib/thread.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2021 (c) Anna Schumaker. -from . import publisher -import threading - -Start = publisher.Publisher() - -class Thread: - def __init__(self, func): - self.func = func - self.thread = None - self.lock = threading.Lock() - - def __call__(self): - with self.lock: - if self.thread: - return None - self.thread = threading.Thread(target = self.__func__) - self.thread.start() - Start.publish(self) - return self - - def __func__(self): - self.func() - with self.lock: - self.thread = None - - def join(self): - if self.thread: - self.thread.join() - - def running(self): - with self.lock: - if self.thread: - return self.thread.is_alive() - return False