Skip to content

Commit

Permalink
Added Takes objects and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
coretl committed Jul 28, 2016
1 parent 4cfc005 commit 2d3314a
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 0 deletions.
28 changes: 28 additions & 0 deletions malcolm/core/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
import importlib

from malcolm.core.serializable import Serializable


def register_package(package_name):
"""Prepare a package namespace by importing all subclasses following PEP8
rules, and registering any @takes decorated functions"""
class_dict = {}
malcolm_path = os.path.join(os.path.dirname(__file__), "..")
# this is the path to the package
package_path = os.path.join(malcolm_path, package_name)
for f in os.listdir(package_path):
if f.endswith(".py") and f != "__init__.py":
# import it and see what it produces
module_name = f[:-3]
module = importlib.import_module(
"malcolm.%s.%s" % (package_name, module_name))
for n in dir(module):
if n.lower() == module_name:
cls = getattr(module, n)
if hasattr(cls, "Method"):
# we have something!
class_dict[cls.__name__] = cls
register_name = "%s.%s" % (package_name, cls.__name__)
Serializable.register_subclass(register_name)(cls)
return class_dict
8 changes: 8 additions & 0 deletions malcolm/takes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from malcolm.core.package import register_package

class_dict = register_package("takes")

globals().update(class_dict)
__all__ = list(class_dict)

del class_dict
18 changes: 18 additions & 0 deletions malcolm/takes/stringtakes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from malcolm.takes.takes import Takes, name_and_description
from malcolm.metas import StringMeta
from malcolm.core.method import takes, OPTIONAL
from malcolm.compat import base_string


@takes(*name_and_description + [
StringMeta("default", "Default string value for parameter. If not " +
"specified, parameter is required"), OPTIONAL
])
class StringTakes(Takes):
def set_default(self, default):
assert isinstance(default, base_string), \
"Expected string, got %s" % (default,)
self.default = default

def make_meta(self):
return StringMeta(self.name, self.description)
45 changes: 45 additions & 0 deletions malcolm/takes/takes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from malcolm.core.serializable import Serializable
from malcolm.core.method import REQUIRED
from malcolm.compat import base_string
from malcolm.metas import StringMeta


# Don't decorate with @takes because we shouldn't be able to deserialize this...
name_and_description = [
StringMeta("name", "Specify that this class will take a parameter name"),
REQUIRED,
StringMeta("description", "Description of this parameter"),
REQUIRED,
]


class Takes(Serializable):

@property
def endpoints(self):
# default should only be there if someone as called set_default
endpoints = ["name", "description"]
if self.default is not REQUIRED:
endpoints.append("default")
return endpoints

def __init__(self, name="", description=""):
self.set_name(name)
self.set_description(description)
self.default = REQUIRED

def set_name(self, name):
assert isinstance(name, base_string), \
"Needed string, got %r" (name,)
self.name = name

def set_description(self, description):
assert isinstance(description, base_string), \
"Needed string, got %r" (description,)
self.description = description

def set_default(self, default):
raise NotImplementedError()

def make_meta(self):
raise NotImplementedError()
Empty file added tests/test_takes/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions tests/test_takes/test_stringtakes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import setup_malcolm_paths

from collections import OrderedDict

import unittest

from malcolm.takes import StringTakes
from malcolm.metas import StringMeta
from malcolm.core.method import REQUIRED


class TestSetters(unittest.TestCase):

def test_set_default(self):
t = StringTakes()
t.set_default("foo")
self.assertEqual(t.default, "foo")

def test_make_meta(self):
t = StringTakes()
t.set_name("me")
t.set_description("desc")
meta = t.make_meta()
self.assertEqual(meta.name, "me")
self.assertEqual(meta.description, "desc")
self.assertIsInstance(meta, StringMeta)


class TestSerialization(unittest.TestCase):

def setUp(self):
self.s = OrderedDict(typeid="takes.StringTakes")
self.s["name"] = "param"
self.s["description"] = "description"

def test_from_dict(self):
t = StringTakes.from_dict("param", self.s)
self.assertIsInstance(t, StringTakes)
self.assertEqual(t.name, "param")
self.assertEqual(t.description, "description")
self.assertEqual(t.default, REQUIRED)
self.s["default"] = "something"
t = StringTakes.from_dict("param", self.s)
self.assertEqual(t.default, "something")

def test_do_dict(self):
t = StringTakes()
t.set_name("param")
t.set_description("description")
self.assertEqual(t.to_dict(), self.s)

if __name__ == "__main__":
unittest.main(verbosity=2)
43 changes: 43 additions & 0 deletions tests/test_takes/test_takes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import setup_malcolm_paths

from collections import OrderedDict

import unittest
from mock import Mock, patch, call, MagicMock

from malcolm.takes.takes import Takes


class TestSetters(unittest.TestCase):

def test_set_name(self):
t = Takes()
self.assertEqual(t.name, "")
t.set_name("foo")
self.assertEqual(t.name, "foo")

def test_set_description(self):
t = Takes()
self.assertEqual(t.description, "")
t.set_description("bar")
self.assertEqual(t.description, "bar")

def test_set_default_raises(self):
t = Takes()
self.assertRaises(NotImplementedError, t.set_default, "bat")

def test_make_meta_raises(self):
t = Takes()
self.assertRaises(NotImplementedError, t.make_meta)

def test_endpoints(self):
t = Takes()
self.assertEqual(t.endpoints, ["name", "description"])
t.default = "something"
self.assertEqual(t.endpoints, ["name", "description", "default"])

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

0 comments on commit 2d3314a

Please sign in to comment.