Skip to content

Commit

Permalink
Let Attribute represent different types, depending on given meta
Browse files Browse the repository at this point in the history
  • Loading branch information
c-mita committed Jun 29, 2016
1 parent 3ec54dd commit a0a2811
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 23 deletions.
14 changes: 13 additions & 1 deletion malcolm/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
from malcolm.core.serializable import Serializable


@Serializable.register("malcolm:core/Attribute:1.0")
@Serializable.register("epics:nt/NTScalar:1.0")
@Serializable.register("epics:nt/NTScalarArray:1.0")
@Serializable.register("malcolm:core/TableAttribute:1.0")
class Attribute(Serializable):
"""Represents a value with type information that may be backed elsewhere"""

Expand All @@ -13,6 +15,15 @@ def __init__(self, meta):
self.meta = meta
self.value = None
self.put_func = None
if self.meta.attribute_type() == AttributeMeta.SCALAR:
self.typeid = "epics:nt/NTScalar:1.0"
elif self.meta.attribute_type() == AttributeMeta.SCALARARRAY:
self.typeid = "epics:nt/NTScalarArray:1.0"
elif self.meta.attribute_type() == AttributeMeta.TABLE:
self.typeid = "malcolm:core/TableAttribute:1.0"
else:
raise ValueError(
"Unknown typeid %s in meta %s" % (self.meta.typeid, self.meta))

def set_put_function(self, func):
self.put_func = func
Expand All @@ -30,6 +41,7 @@ def to_dict(self):
d = OrderedDict()
d["value"] = self.value
d["meta"] = self.meta.to_dict()
d["typeid"] = self.typeid
# TODO: add timeStamp and alarm
return d

Expand Down
62 changes: 40 additions & 22 deletions tests/test_core/test_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,27 @@

class TestAttribute(unittest.TestCase):

def setUp(self):
self.meta = Mock()
self.meta.name = "test"
self.meta.attribute_type.return_value = AttributeMeta.TABLE

def test_init(self):
meta = Mock()
meta.name = "test"
a = Attribute(meta)
a = Attribute(self.meta)
self.assertEquals("test", a.name)
self.assertIs(meta, a.meta)
self.assertIs(self.meta, a.meta)
self.assertIsNone(a.value)
self.assertEqual("malcolm:core/Attribute:1.0", a.typeid)
self.assertEquals("malcolm:core/TableAttribute:1.0", a.typeid)

def test_set_put_function(self):
func = Mock()
meta = Mock()
meta.name = "test"
a = Attribute(meta)
a = Attribute(self.meta)
a.set_put_function(func)
self.assertIs(func, a.put_func)

def test_set_value(self):
value = "test_value"
meta = Mock()
meta.name = "test"
a = Attribute(meta)
a = Attribute(self.meta)
a.on_changed = Mock(a.on_changed)
a.set_value(value)
self.assertEquals("test_value", a.value)
Expand All @@ -44,34 +43,53 @@ def test_set_value(self):
def test_put(self):
func = Mock()
value = "test_value"
meta = Mock()
meta.name = "test"
a = Attribute(meta)
a = Attribute(self.meta)
a.set_put_function(func)
a.put(value)
func.assert_called_once_with(value)

def test_to_dict(self):
meta = Mock()
meta.name = "test"
meta.to_dict = Mock(return_value = {"test_meta":"dict"})
self.meta.to_dict = Mock(return_value = {"test_meta":"dict"})
expected = OrderedDict()
expected["value"] = "test_value"
expected["meta"] = {"test_meta":"dict"}
a = Attribute(meta)
expected["typeid"] = "malcolm:core/TableAttribute:1.0"
a = Attribute(self.meta)
a.set_value("test_value")
self.assertEquals(expected, a.to_dict())

@patch.object(AttributeMeta, "from_dict")
def test_from_dict(self, am_from_dict):
meta = Mock()
meta.name = "test"
am_from_dict.return_value = meta
am_from_dict.return_value = self.meta
d = {"value":"test_value", "meta":{"meta":"dict"}}
a = Attribute.from_dict("test", d)
self.assertEquals("test", a.name)
self.assertEquals("test_value", a.value)
self.assertIs(meta, a.meta)
self.assertIs(self.meta, a.meta)

def test_meta_types(self):
meta = Mock()
meta.name = "test"

meta.attribute_type.return_value = AttributeMeta.SCALAR
a = Attribute(meta)
self.assertEqual("epics:nt/NTScalar:1.0", a.typeid)

meta.attribute_type.return_value = AttributeMeta.SCALARARRAY
a = Attribute(meta)
self.assertEqual("epics:nt/NTScalarArray:1.0", a.typeid)

meta.attribute_type.return_value = AttributeMeta.TABLE
a = Attribute(meta)
self.assertEqual(
"malcolm:core/TableAttribute:1.0", a.typeid)

def test_invalid_meta_type_raises(self):
meta = Mock()
meta.name = "test"
meta.attribute_type.return_value = "NOT_A_REAL_TYPE"
with self.assertRaises(ValueError):
a = Attribute(meta)

if __name__ == "__main__":
unittest.main(verbosity=2)

0 comments on commit a0a2811

Please sign in to comment.