aboutsummaryrefslogtreecommitdiffstats
path: root/test/schema/test_types.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/schema/test_types.py')
-rw-r--r--test/schema/test_types.py225
1 files changed, 225 insertions, 0 deletions
diff --git a/test/schema/test_types.py b/test/schema/test_types.py
new file mode 100644
index 0000000..4a49e6e
--- /dev/null
+++ b/test/schema/test_types.py
@@ -0,0 +1,225 @@
+"""
+
+Part of the tagit test suite.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import operator
+import unittest
+
+# bsfs imports
+from bsfs.namespace import ns
+from bsfs.utils import errors
+
+# objects to test
+from bsfs.schema.types import _Type, _Vertex, Node, Literal, Predicate
+
+
+## code ##
+
+class TestType(unittest.TestCase):
+ def test_parents(self):
+ # create some types
+ fst = _Type('First')
+ snd = _Type('Second', fst)
+ trd = _Type('Third', snd)
+ frd = _Type('Fourth', trd)
+ # check parents
+ self.assertListEqual(list(fst.parents()), [])
+ self.assertListEqual(list(snd.parents()), [fst])
+ self.assertListEqual(list(trd.parents()), [snd, fst])
+ self.assertListEqual(list(frd.parents()), [trd, snd, fst])
+
+ def test_essentials(self):
+ # type w/o parent
+ self.assertEqual(str(_Type('Foo')), '_Type(Foo)')
+ self.assertEqual(repr(_Type('Foo')), '_Type(Foo, None)')
+ # type w/ parent
+ self.assertEqual(str(_Type('Foo', _Type('Bar'))), '_Type(Foo)')
+ self.assertEqual(repr(_Type('Foo', _Type('Bar'))), '_Type(Foo, _Type(Bar, None))')
+ # subtype w/o parent
+ class SubType(_Type): pass
+ self.assertEqual(str(SubType('Foo')), 'SubType(Foo)')
+ self.assertEqual(repr(SubType('Foo')), 'SubType(Foo, None)')
+ # subtype w/ parent
+ self.assertEqual(str(SubType('Foo', SubType('Bar'))), 'SubType(Foo)')
+ self.assertEqual(repr(SubType('Foo', SubType('Bar'))), 'SubType(Foo, SubType(Bar, None))')
+ # subtype and type mixed
+ self.assertEqual(str(SubType('Foo', _Type('Bar'))), 'SubType(Foo)')
+ self.assertEqual(repr(SubType('Foo', _Type('Bar'))), 'SubType(Foo, _Type(Bar, None))')
+ self.assertEqual(str(_Type('Foo', SubType('Bar'))), '_Type(Foo)')
+ self.assertEqual(repr(_Type('Foo', SubType('Bar'))), '_Type(Foo, SubType(Bar, None))')
+
+ def test_get_child(self):
+ # callee is used as parent
+ self.assertEqual(_Type('First').get_child('Second'), _Type('Second', _Type('First')))
+ # works with multiple parents
+ self.assertEqual(_Type('First').get_child('Second').get_child('Third'), _Type('Third', _Type('Second', _Type('First'))))
+ # type persists
+ class Foo(_Type): pass
+ self.assertEqual(Foo('First').get_child('Second'), Foo('Second', Foo('First')))
+
+ def test_equality(self):
+ # equality depends on uri
+ self.assertEqual(_Type('Foo'), _Type('Foo'))
+ self.assertEqual(hash(_Type('Foo')), hash(_Type('Foo')))
+ self.assertNotEqual(_Type('Foo'), _Type('Bar'))
+ self.assertNotEqual(hash(_Type('Foo')), hash(_Type('Bar')))
+ # comparison is case-sensitive
+ self.assertNotEqual(_Type('FOO'), _Type('foo'))
+ self.assertNotEqual(hash(_Type('FOO')), hash(_Type('foo')))
+ # comparison respects type
+ class Foo(_Type): pass
+ self.assertNotEqual(_Type('Foo'), Foo('Foo'))
+ self.assertNotEqual(hash(_Type('Foo')), hash(Foo('Foo')))
+ # comparison respects parent
+ self.assertNotEqual(_Type('Foo', _Type('Bar')), _Type('Foo'))
+ self.assertNotEqual(hash(_Type('Foo', _Type('Bar'))), hash(_Type('Foo')))
+
+ def test_order(self):
+ # create some types.
+ vehicle = _Type('Vehicle')
+ twowheel = _Type('Two-wheel', vehicle)
+ bike = _Type('Bike', twowheel)
+ bicycle = _Type('Bicycle', twowheel)
+ # two-wheel is equivalent to itself
+ self.assertFalse(twowheel == vehicle)
+ self.assertTrue(twowheel == twowheel)
+ self.assertFalse(twowheel == bicycle)
+ # two-wheel is a true subclass of Vehicle
+ self.assertTrue(twowheel < vehicle)
+ self.assertFalse(twowheel < twowheel)
+ self.assertFalse(twowheel < bicycle)
+ # two-wheel is a subclass of itself and Vehicle
+ self.assertTrue(twowheel <= vehicle)
+ self.assertTrue(twowheel <= twowheel)
+ self.assertFalse(twowheel <= bicycle)
+ # two-wheel is a true superclass of Bicycle
+ self.assertFalse(twowheel > vehicle)
+ self.assertFalse(twowheel > twowheel)
+ self.assertTrue(twowheel > bicycle)
+ # two-wheel is a superclass of itself and Bicycle
+ self.assertFalse(twowheel >= vehicle)
+ self.assertTrue(twowheel >= twowheel)
+ self.assertTrue(twowheel >= bicycle)
+ # analoguous to sets, this is not a total order
+ self.assertFalse(bike <= bicycle)
+ self.assertFalse(bike < bicycle)
+ self.assertFalse(bike > bicycle)
+ self.assertFalse(bike >= bicycle)
+ self.assertFalse(bike == bicycle)
+ class Foo(_Type): pass
+ foo = Foo(bike.uri, bike.parent)
+ # cannot compare different types
+ self.assertRaises(TypeError, operator.lt, foo, bike)
+ self.assertRaises(TypeError, operator.le, foo, bike)
+ self.assertRaises(TypeError, operator.gt, foo, bike)
+ self.assertRaises(TypeError, operator.ge, foo, bike)
+ # goes both ways
+ self.assertRaises(TypeError, operator.lt, bike, foo)
+ self.assertRaises(TypeError, operator.le, bike, foo)
+ self.assertRaises(TypeError, operator.gt, bike, foo)
+ self.assertRaises(TypeError, operator.ge, bike, foo)
+
+class TestPredicate(unittest.TestCase):
+ def test_construction(self):
+ # domain must be a node
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, 1234, None, True)
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, None, Literal(ns.bsfs.Foo, None), None, True)
+ # range must be None, a Literal, or a Node
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, None, Node(ns.bsfs.Node, None), 1234, True)
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, None, Node(ns.bsfs.Node, None), _Vertex(ns.bsfs.Foo, None), True)
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, None, Node(ns.bsfs.Node, None), _Type(ns.bsfs.Foo, None), True)
+ class Foo(): pass
+ self.assertRaises(TypeError, Predicate, ns.bse.foo, None, Node(ns.bsfs.Node, None), Foo(), True)
+
+ def test_equality(self):
+ n_root = Node(ns.bsfs.Node, None)
+ n_ent = Node(ns.bsfs.Entity, Node(ns.bsfs.Node, None))
+ n_tag = Node(ns.bsfs.Tag, Node(ns.bsfs.Tag, None))
+ root = Predicate(
+ uri=ns.bsfs.Predicate,
+ parent=None,
+ domain=n_root,
+ range=None,
+ unique=False,
+ )
+ # instance is equal to itself
+ self.assertEqual(root, root)
+ self.assertEqual(hash(root), hash(root))
+ # instance is equal to a clone
+ self.assertEqual(root, Predicate(ns.bsfs.Predicate, None, n_root, None, False))
+ self.assertEqual(hash(root), hash(Predicate(ns.bsfs.Predicate, None, n_root, None, False)))
+ # equality respects uri
+ self.assertNotEqual(root, Predicate(ns.bsfs.Alternative, None, n_root, None, False))
+ self.assertNotEqual(hash(root), hash(Predicate(ns.bsfs.Alternative, None, n_root, None, False)))
+ # equality respects parent
+ self.assertNotEqual(root, Predicate(ns.bsfs.Predicate, n_root, n_root, None, False))
+ self.assertNotEqual(hash(root), hash(Predicate(ns.bsfs.Predicate, n_root, n_root, None, False)))
+ # equality respects domain
+ self.assertNotEqual(root, Predicate(ns.bsfs.Predicate, None, n_ent, None, False))
+ self.assertNotEqual(hash(root), hash(Predicate(ns.bsfs.Predicate, None, n_ent, None, False)))
+ # equality respects range
+ self.assertNotEqual(root, Predicate(ns.bsfs.Predicate, None, n_root, n_root, False))
+ self.assertNotEqual(hash(root), hash(Predicate(ns.bsfs.Predicate, None, n_root, n_root, False)))
+ # equality respects unique
+ self.assertNotEqual(root, Predicate(ns.bsfs.Predicate, None, n_root, None, True))
+ self.assertNotEqual(hash(root), hash(Predicate(ns.bsfs.Predicate, None, n_root, None, True)))
+
+ def test_get_child(self):
+ n_root = Node(ns.bsfs.Node, None)
+ n_ent = Node(ns.bsfs.Entity, Node(ns.bsfs.Node, None))
+ n_tag = Node(ns.bsfs.Tag, Node(ns.bsfs.Tag, None))
+ root = Predicate(
+ uri=ns.bsfs.Predicate,
+ parent=None,
+ domain=n_root,
+ range=None,
+ unique=False,
+ )
+ tag = Predicate(
+ uri=ns.bsfs.Entity,
+ parent=root,
+ domain=n_ent,
+ range=n_tag,
+ unique=False,
+ )
+
+ # uri is respected
+ self.assertEqual(ns.bse.foo, tag.get_child(ns.bse.foo).uri)
+ # domain is respected
+ dom = Node(ns.bsfs.Image, n_ent)
+ self.assertEqual(dom, tag.get_child(ns.bse.foo, domain=dom).domain)
+ # range is respected
+ rng = Node(ns.bsfs.Group, n_tag)
+ self.assertEqual(rng, tag.get_child(ns.bse.foo, range=rng).range)
+ # cannot set range to None
+ self.assertEqual(n_tag, tag.get_child(ns.bse.foo, range=None).range)
+ # unique is respected
+ self.assertTrue(tag.get_child(ns.bse.foo, unique=True).unique)
+
+ # domain is inherited from parent
+ self.assertEqual(n_ent, tag.get_child(ns.bse.foo).domain)
+ # range is inherited from parent
+ self.assertEqual(n_tag, tag.get_child(ns.bse.foo).range)
+ # uniqueness is inherited from parent
+ self.assertFalse(tag.get_child(ns.bse.foo).unique)
+
+ # domain must be subtype of parent's domain
+ self.assertRaises(errors.ConsistencyError, tag.get_child, ns.bse.foo, domain=n_root)
+ self.assertRaises(errors.ConsistencyError, tag.get_child, ns.bse.foo, domain=Node(ns.bsfs.Image, n_root))
+ # range cannot be None
+ self.assertRaises(ValueError, root.get_child, ns.bse.foo)
+ # range must be subtype of parent's range
+ self.assertRaises(errors.ConsistencyError, tag.get_child, ns.bse.foo, range=n_root)
+ self.assertRaises(errors.ConsistencyError, tag.get_child, ns.bse.foo, range=Node(ns.bsfs.Image, n_root))
+
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##
+