diff --git a/owrx/property/__init__.py b/owrx/property/__init__.py index d0d92d1..9586cb7 100644 --- a/owrx/property/__init__.py +++ b/owrx/property/__init__.py @@ -345,9 +345,13 @@ class PropertyStack(PropertyManager): class PropertyCarousel(PropertyDelegator): def __init__(self): # start with an empty dummy layer - super().__init__(PropertyLayer()) + self.emptyLayer = PropertyLayer().readonly() + super().__init__(self.emptyLayer) self.layers = {} + def _getDefaultLayer(self): + return self.emptyLayer + def addLayer(self, key, value): self.layers[key] = value @@ -355,12 +359,14 @@ class PropertyCarousel(PropertyDelegator): return key in self.layers def removeLayer(self, key): + if key in self.layers and self.layers[key] is self.pm: + self.switch() del self.layers[key] - def switch(self, key): + def switch(self, key=None): before = self.pm self.subscription.cancel() - self.pm = self.layers[key] + self.pm = self._getDefaultLayer() if key is None else self.layers[key] self.subscription = self.pm.wire(self._fireCallbacks) changes = {} for key in set(list(before.keys()) + list(self.keys())): diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py index 37a713f..97f3d1e 100644 --- a/owrx/source/__init__.py +++ b/owrx/source/__init__.py @@ -82,6 +82,12 @@ class SdrProfileCarousel(PropertyCarousel): elif not self.hasLayer(profile_id): self.addLayer(profile_id, profile) + def _getDefaultLayer(self): + # return the first available profile, or the default empty layer if we don't have any + if self.layers: + return next(iter(self.layers.values())) + return super()._getDefaultLayer() + class SdrSource(ABC): def __init__(self, id, props): diff --git a/test/property/test_property_carousel.py b/test/property/test_property_carousel.py index b6ae264..29f79ee 100644 --- a/test/property/test_property_carousel.py +++ b/test/property/test_property_carousel.py @@ -1,6 +1,6 @@ from unittest import TestCase from unittest.mock import Mock -from owrx.property import PropertyCarousel, PropertyLayer, PropertyDeleted +from owrx.property import PropertyCarousel, PropertyLayer, PropertyDeleted, PropertyWriteError class PropertyCarouselTest(TestCase): @@ -92,3 +92,28 @@ class PropertyCarouselTest(TestCase): pc.removeLayer("x") with self.assertRaises(KeyError): pc.switch("x") + + def testPropertyResetAfterRemoval(self): + pc = PropertyCarousel() + pl = PropertyLayer(testkey="testvalue") + pc.addLayer("x", pl) + pc.switch("x") + self.assertEqual(pc["testkey"], "testvalue") + pc.removeLayer("x") + with self.assertRaises(KeyError): + x = pc["testkey"] + + def testEmptySwitch(self): + pc = PropertyCarousel() + pl = PropertyLayer(testkey="testvalue") + pc.addLayer("x", pl) + pc.switch("x") + self.assertEqual(pc["testkey"], "testvalue") + pc.switch() + with self.assertRaises(KeyError): + x = pc["testkey"] + + def testErrorOnWriteOnDefaultLayer(self): + pc = PropertyCarousel() + with self.assertRaises(PropertyWriteError): + pc["testkey"] = "testvalue"