Refactor gauge trait to match description of it
This commit is contained in:
parent
7c12e4d362
commit
5571ef8a7d
2 changed files with 146 additions and 52 deletions
|
|
@ -514,7 +514,7 @@ class TestTraitCounter(_TraitHandlerBase):
|
||||||
self.assertEqual(self.trait1.min, None)
|
self.assertEqual(self.trait1.min, None)
|
||||||
|
|
||||||
|
|
||||||
class TestTraitGauge(TestTraitCounter):
|
class TestTraitGauge(_TraitHandlerBase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
@ -522,66 +522,137 @@ class TestTraitGauge(TestTraitCounter):
|
||||||
"test2",
|
"test2",
|
||||||
name="Test1",
|
name="Test1",
|
||||||
trait_type='gauge',
|
trait_type='gauge',
|
||||||
base=1,
|
base=8, # max = base + mod
|
||||||
mod=2,
|
mod=2,
|
||||||
min=-10,
|
|
||||||
max=10,
|
|
||||||
extra_val1="xvalue1",
|
extra_val1="xvalue1",
|
||||||
extra_val2="xvalue2"
|
extra_val2="xvalue2"
|
||||||
)
|
)
|
||||||
self.trait1 = self.traithandler.get("test2")
|
self.trait1 = self.traithandler.get("test2")
|
||||||
|
|
||||||
def test_boundaries__change_boundaries(self):
|
def _get_values(self):
|
||||||
"""Change boundaries after base/mod change"""
|
return (self.trait1.base, self.trait1.mod, self.trait1.actual,
|
||||||
self.trait1.base = 5
|
self.trait1.min, self.trait1.max)
|
||||||
self.trait1.mod = -100
|
|
||||||
|
def test_init(self):
|
||||||
|
self.assertEqual(
|
||||||
|
self._get_dbstore("test1"),
|
||||||
|
{"name": "Test1",
|
||||||
|
"trait_type": 'counter',
|
||||||
|
"base": 8,
|
||||||
|
"mod": 2,
|
||||||
|
"extra_val1": "xvalue1",
|
||||||
|
"extra_val2": "xvalue2"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_actual(self):
|
||||||
|
"""Actual is current, where current defaults to base + mod"""
|
||||||
|
# current unset - follows base + mod
|
||||||
|
self.assertEqual(self._get_values(), (8, 2, 10, 0, 10))
|
||||||
|
self.trait1.base += 4
|
||||||
|
self.assertEqual(self._get_values(), (12, 2, 14, 0, 14))
|
||||||
|
self.trait1.mod -= 1
|
||||||
|
self.assertEqual(self._get_values(), (12, 1, 13, 0, 13))
|
||||||
|
# set current, decouple from base + mod
|
||||||
|
self.trait1.current = 5
|
||||||
|
self.assertEqual(self._get_values(), (12, 1, 5, 0, 13))
|
||||||
|
self.trait1.mod += 1
|
||||||
|
self.trait1.base -= 4
|
||||||
|
self.assertEqual(self._get_values(), (8, 2, 5, 0, 10))
|
||||||
|
self.trait1.min = -100
|
||||||
|
self.trait.base = -20
|
||||||
|
self.assertEqual(self._get_values(), (-20, 2, -18, -100, 10))
|
||||||
|
|
||||||
|
def test_boundaries__minmax(self):
|
||||||
|
"""Test range"""
|
||||||
|
# current unset - tied to base + mod
|
||||||
|
self.trait1.base += 20
|
||||||
|
self.assertEqual(self._get_values(), (28, 2, 30, 0, 30))
|
||||||
|
# set current - decouple from base + mod
|
||||||
|
self.trait1.current = 19
|
||||||
|
self.assertEqual(self._get_values(), (28, 2, 19, 0, 30))
|
||||||
|
# test upper bound
|
||||||
|
self.trait1.current = 100
|
||||||
|
self.assertEqual(self._get_values(), (28, 2, 30, 0, 30))
|
||||||
|
# min defaults to 0
|
||||||
|
self.trait1.current = -10
|
||||||
|
self.assertEqual(self._get_values(), (28, 2, 0, 0, 30))
|
||||||
self.trait1.min = -20
|
self.trait1.min = -20
|
||||||
# from pudb import debugger;debugger.Debugger().set_trace()
|
self.assertEqual(self._get_values(), (28, 2, 0, -20, 30))
|
||||||
self.assertEqual(self._get_values(), (5, -100, -20))
|
self.trait1.current = -10
|
||||||
|
self.assertEqual(self._get_values(), (28, 2, -10, -20, 30))
|
||||||
|
|
||||||
|
def test_boundaries__bigmod(self):
|
||||||
|
"""add a big mod"""
|
||||||
|
self.trait1.base = 5
|
||||||
self.trait1.mod = 100
|
self.trait1.mod = 100
|
||||||
self.trait1.max = 20
|
self.assertEqual(self._get_values(), (5, 100, 105, 0, 105))
|
||||||
self.assertEqual(self._get_values(), (5, 100, 20))
|
# restricted by min
|
||||||
|
self.trait1.mod = -100
|
||||||
|
self.assertEqual(self._get_values(), (5, -5, 0, 0, 0))
|
||||||
|
self.trait1.min = -200
|
||||||
|
self.assertEqual(self._get_values(), (5, -5, 0, -200, 0))
|
||||||
|
|
||||||
|
def test_boundaries__change_boundaries(self):
|
||||||
|
"""Change boundaries after current change"""
|
||||||
|
self.trait1.current = 20
|
||||||
|
self.assertEqual(self._get_values(), (8, 2, 10, 0, 10))
|
||||||
|
self.trait1.mod = 102
|
||||||
|
self.assertEqual(self._get_values(), (8, 102, 10, 0, 110))
|
||||||
|
# raising min past current value will force it upwards
|
||||||
|
self.trait1.min = 20
|
||||||
|
self.assertEqual(self._get_values(), (8, 102, 20, 20, 110))
|
||||||
|
|
||||||
def test_boundaries__disable(self):
|
def test_boundaries__disable(self):
|
||||||
"""Disable and re-enable boundaries"""
|
"""Disable and re-enable boundary"""
|
||||||
self.trait1.base = 5
|
self.trait1.base = 5
|
||||||
self.trait1.mod = 100
|
self.trait1.min = 1
|
||||||
del self.trait1.max
|
self.assertEqual(self._get_values(), (5, 2, 7, 1, 7))
|
||||||
self.assertEqual(self.trait1.max, None)
|
|
||||||
del self.trait1.min
|
del self.trait1.min
|
||||||
self.assertEqual(self.trait1.min, None)
|
self.assertEqual(self._get_values(), (5, 2, 7, 0, 7))
|
||||||
self.trait1.base = 100
|
del self.trait1.base
|
||||||
# this won't change since current is not changed
|
del self.trait1.mod
|
||||||
self.assertEqual(self._get_values(), (100, 100, 10))
|
self.assertEqual(self._get_values(), (0, 0, 0, 0, 0))
|
||||||
self.trait1.current = 150
|
with self.assertRaises(traits.TraitException):
|
||||||
self.assertEqual(self._get_values(), (100, 100, 150))
|
del self.trait1.max
|
||||||
self.trait1.base = -10
|
|
||||||
self.assertEqual(self._get_values(), (-10, 100, 150))
|
|
||||||
|
|
||||||
# re-activate boundaries
|
|
||||||
self.trait1.max = 15
|
|
||||||
self.trait1.min = 10
|
|
||||||
self.assertEqual(self._get_values(), (-10, 100, 15))
|
|
||||||
|
|
||||||
def test_boundaries__inverse(self):
|
def test_boundaries__inverse(self):
|
||||||
"""Set inverse boundaries - limited by base"""
|
"""Try to set reversed boundaries"""
|
||||||
|
self.trait1.mod = 0
|
||||||
|
self.trait1.base = -10 # limited by min
|
||||||
|
self.assertEqual(self._get_values(), (0, 0, 0, 0, 0))
|
||||||
|
self.trait1.min = -10
|
||||||
|
self.assertEqual(self._get_values(), (0, 0, 0, -10, 0))
|
||||||
self.trait1.base = -10
|
self.trait1.base = -10
|
||||||
self.trait1.mod = 100
|
self.assertEqual(self._get_values(), (-10, 0, -10, -10, -10))
|
||||||
self.trait1.min = 20 # will be set to base
|
self.min = 0 # limited by base + mod
|
||||||
self.assertEqual(self.trait1.min, -10)
|
self.assertEqual(self._get_values(), (-10, 0, -10, -10, -10))
|
||||||
self.trait1.max = -20 # this is <base so ok
|
|
||||||
self.assertEqual(self.trait1.max, -20)
|
|
||||||
self.assertEqual(self._get_values(), (-10, 100, -10))
|
|
||||||
|
|
||||||
def test_current(self):
|
def test_current(self):
|
||||||
"""For a gauge, mod applies to base and not to current."""
|
"""Modifying current value"""
|
||||||
|
self.trait1.base = 10
|
||||||
self.trait1.current = 5
|
self.trait1.current = 5
|
||||||
self.assertEqual(self._get_values(), (1, 2, 5))
|
self.assertEqual(self._get_values(), (10, 2, 5, 0, 12))
|
||||||
self.trait1.current = 14
|
self.trait1.current = 10
|
||||||
self.assertEqual(self._get_values(), (1, 2, 10))
|
self.assertEqual(self._get_values(), (10, 2, 10, 0, 12))
|
||||||
self.trait1.current = -14
|
self.trait1.current = 12
|
||||||
self.assertEqual(self._get_values(), (1, 2, -10))
|
self.assertEqual(self._get_values(), (10, 2, 12, 0, 12))
|
||||||
|
self.trait1.current = 0
|
||||||
|
self.assertEqual(self._get_values(), (10, 2, 0, 0, 12))
|
||||||
|
self.trait1.current = -1
|
||||||
|
self.assertEqual(self._get_values(), (10, 2, 0, 0, 12))
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
"""Deleting resets to default."""
|
||||||
|
del self.trait1.mod
|
||||||
|
self.assertEqual(self._get_values(), (8, 0, 8, 0, 8))
|
||||||
|
self.trait1.mod = 2
|
||||||
|
del self.trait1.base
|
||||||
|
self.assertEqual(self._get_values(), (0, 2, 2, 0, 2))
|
||||||
|
del self.trait1.min
|
||||||
|
self.assertEqual(self._get_values(), (0, 2, 2, 0, 2))
|
||||||
|
self.trait1.min = -10
|
||||||
|
self.assertEqual(self._get_values(), (0, 2, 2, -10, 2))
|
||||||
|
del self.trait1.min
|
||||||
|
self.assertEqual(self._get_values(), (0, 2, 2, 0, 2))
|
||||||
|
|
||||||
|
|
||||||
class TestNumericTraitOperators(TestCase):
|
class TestNumericTraitOperators(TestCase):
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,7 @@ def _delayed_import_trait_classes():
|
||||||
|
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
|
_DA = object.__delattr__
|
||||||
|
|
||||||
# this is the default we offer in TraitHandler.add
|
# this is the default we offer in TraitHandler.add
|
||||||
DEFAULT_TRAIT_TYPE = "static"
|
DEFAULT_TRAIT_TYPE = "static"
|
||||||
|
|
@ -682,8 +683,18 @@ class Trait:
|
||||||
# set to default
|
# set to default
|
||||||
self._data[key] = self.data_keys[key]
|
self._data[key] = self.data_keys[key]
|
||||||
elif key in self._data:
|
elif key in self._data:
|
||||||
# an extra property. Delete as normal.
|
try:
|
||||||
del self._data[key]
|
# check if we have a custom deleter
|
||||||
|
_DA(self, key)
|
||||||
|
except AttributeHandler:
|
||||||
|
# delete normally
|
||||||
|
del self._data[key]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# check if we have custom deleter, otherwise ignore
|
||||||
|
_DA(self, key)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Debug-friendly representation of this Trait."""
|
"""Debug-friendly representation of this Trait."""
|
||||||
|
|
@ -1049,7 +1060,7 @@ class GaugeTrait(CounterTrait):
|
||||||
data_keys = {
|
data_keys = {
|
||||||
"base": 0,
|
"base": 0,
|
||||||
"mod": 0,
|
"mod": 0,
|
||||||
"min": None,
|
"min": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _mod_base(self):
|
def _mod_base(self):
|
||||||
|
|
@ -1076,28 +1087,36 @@ class GaugeTrait(CounterTrait):
|
||||||
|
|
||||||
@base.setter
|
@base.setter
|
||||||
def base(self, value):
|
def base(self, value):
|
||||||
|
"""Limit so base+mod can never go below min."""
|
||||||
if type(value) in (int, float):
|
if type(value) in (int, float):
|
||||||
self._data["base"] = self._enforce_bounds(value)
|
if value + self.mod < self.min:
|
||||||
|
value = self.min - self.mod
|
||||||
|
self._data["base"] = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mod(self):
|
def mod(self):
|
||||||
return self._data["mod"]
|
return self._data["mod"]
|
||||||
|
|
||||||
@mod.setter
|
@mod.setter
|
||||||
def mod(self, amount):
|
def mod(self, value):
|
||||||
if type(amount) in (int, float):
|
"""Limit so base+mod can never go below min."""
|
||||||
self._data["mod"] = amount
|
if type(value) in (int, float):
|
||||||
|
if value + self.base < self.min:
|
||||||
|
value = self.min - self.base
|
||||||
|
self._data["mod"] = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min(self):
|
def min(self):
|
||||||
return self._data["min"]
|
val = self._data["min"]
|
||||||
|
return self.data_keys["min"] if val is None else val
|
||||||
|
|
||||||
@min.setter
|
@min.setter
|
||||||
def min(self, value):
|
def min(self, value):
|
||||||
|
"""Limit so min can never be greater than base+mod."""
|
||||||
if value is None:
|
if value is None:
|
||||||
self._data["min"] = self.data_keys['min']
|
self._data["min"] = self.data_keys['min']
|
||||||
elif type(value) in (int, float):
|
elif type(value) in (int, float):
|
||||||
self._data["min"] = min(self.value, self.base + self.mod)
|
self._data["min"] = min(value, self.base + self.mod)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max(self):
|
def max(self):
|
||||||
|
|
@ -1108,6 +1127,10 @@ class GaugeTrait(CounterTrait):
|
||||||
def max(self, value):
|
def max(self, value):
|
||||||
raise TraitException("The .max property is not settable "
|
raise TraitException("The .max property is not settable "
|
||||||
"on GaugeTraits. Set .base instead.")
|
"on GaugeTraits. Set .base instead.")
|
||||||
|
@max.deleter
|
||||||
|
def max(self):
|
||||||
|
raise TraitException("The .max property cannot be reset "
|
||||||
|
"on GaugeTraits. Reset .mod and .base instead.")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current(self):
|
def current(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue