diff options
author | Matthias Baumgartner <dev@igsor.net> | 2022-12-24 10:27:09 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2022-12-24 10:27:09 +0100 |
commit | 266c2c9a072bf3289fd7f2d75278b7d59528378c (patch) | |
tree | 60760e0fec84d5cd7b3f3efef11e3892df5cc85a /test | |
parent | ed2074ae88f2db6cb6b38716b43b35e29eb2e16c (diff) | |
download | bsie-266c2c9a072bf3289fd7f2d75278b7d59528378c.tar.gz bsie-266c2c9a072bf3289fd7f2d75278b7d59528378c.tar.bz2 bsie-266c2c9a072bf3289fd7f2d75278b7d59528378c.zip |
package restructuring: base
* Reader and Extractor to respective reader/extractor modules
* ReaderBuilder to reader module
* ExtractorBuilder to extractor module
* Loading module in utils (safe_load, unpack_name)
* Pipeline and PipelineBuilder to lib module
* errors to utils
* documentation: "standard import" and "external import"
Diffstat (limited to 'test')
-rw-r--r-- | test/base/__init__.py | 0 | ||||
-rw-r--r-- | test/extractor/generic/test_path.py | 6 | ||||
-rw-r--r-- | test/extractor/generic/test_stat.py | 6 | ||||
-rw-r--r-- | test/extractor/test_base.py (renamed from test/base/test_extractor.py) | 8 | ||||
-rw-r--r-- | test/extractor/test_builder.py | 103 | ||||
-rw-r--r-- | test/lib/test_bsie.py | 24 | ||||
-rw-r--r-- | test/lib/test_builder.py | 107 | ||||
-rw-r--r-- | test/lib/test_pipeline.py (renamed from test/tools/test_pipeline.py) | 11 | ||||
-rw-r--r-- | test/reader/test_base.py (renamed from test/base/test_reader.py) | 6 | ||||
-rw-r--r-- | test/reader/test_builder.py | 54 | ||||
-rw-r--r-- | test/reader/test_stat.py | 4 | ||||
-rw-r--r-- | test/tools/__init__.py | 0 | ||||
-rw-r--r-- | test/tools/test_builder.py | 246 | ||||
-rw-r--r-- | test/tools/testfile.t | 1 | ||||
-rw-r--r-- | test/utils/filematcher/test_parser.py | 6 | ||||
-rw-r--r-- | test/utils/test_loading.py | 48 |
16 files changed, 348 insertions, 282 deletions
diff --git a/test/base/__init__.py b/test/base/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/test/base/__init__.py +++ /dev/null diff --git a/test/extractor/generic/test_path.py b/test/extractor/generic/test_path.py index 820f402..778ac5a 100644 --- a/test/extractor/generic/test_path.py +++ b/test/extractor/generic/test_path.py @@ -4,11 +4,11 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import unittest # bsie imports -from bsie.base import extractor +from bsie.extractor import base from bsie.utils import bsfs, node as _node, ns # objects to test @@ -29,7 +29,7 @@ class TestPath(unittest.TestCase): def test_schema(self): self.assertEqual(Path().schema, - bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + bsfs.schema.Schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:string ; diff --git a/test/extractor/generic/test_stat.py b/test/extractor/generic/test_stat.py index 3441438..ff74085 100644 --- a/test/extractor/generic/test_stat.py +++ b/test/extractor/generic/test_stat.py @@ -4,12 +4,12 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import os import unittest # bsie imports -from bsie.base import extractor +from bsie.extractor import base from bsie.utils import bsfs, node as _node, ns # objects to test @@ -30,7 +30,7 @@ class TestStat(unittest.TestCase): def test_schema(self): self.assertEqual(Stat().schema, - bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + bsfs.schema.Schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:filesize rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:integer ; diff --git a/test/base/test_extractor.py b/test/extractor/test_base.py index 30974ef..6a63c59 100644 --- a/test/base/test_extractor.py +++ b/test/extractor/test_base.py @@ -4,21 +4,21 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import unittest # bsie imports from bsie.utils import bsfs, ns # objects to test -from bsie.base import extractor +from bsie.extractor import base ## code ## -class StubExtractor(extractor.Extractor): +class StubExtractor(base.Extractor): def __init__(self): - super().__init__(bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + super().__init__(bsfs.schema.Schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:author rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range xsd:string ; diff --git a/test/extractor/test_builder.py b/test/extractor/test_builder.py new file mode 100644 index 0000000..039ea53 --- /dev/null +++ b/test/extractor/test_builder.py @@ -0,0 +1,103 @@ +""" + +Part of the bsie test suite. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import unittest + +# bsie imports +from bsie.utils import errors + +# objects to test +from bsie.extractor import ExtractorBuilder + + +## code ## + +class TestExtractorBuilder(unittest.TestCase): + def test_iter(self): + # no specifications + self.assertListEqual(list(ExtractorBuilder([])), []) + # some specifications + builder = ExtractorBuilder([ + {'bsie.extractor.generic.path.Path': {}}, + {'bsie.extractor.generic.stat.Stat': {}}, + {'bsie.extractor.generic.path.Path': {}}, + ]) + self.assertListEqual(list(builder), [0, 1, 2]) + + def test_build(self): + # simple and repeated extractors + builder = ExtractorBuilder([ + {'bsie.extractor.generic.path.Path': {}}, + {'bsie.extractor.generic.stat.Stat': {}}, + {'bsie.extractor.generic.path.Path': {}}, + ]) + ext = [builder.build(0), builder.build(1), builder.build(2)] + import bsie.extractor.generic.path + import bsie.extractor.generic.stat + self.assertListEqual(ext, [ + bsie.extractor.generic.path.Path(), + bsie.extractor.generic.stat.Stat(), + bsie.extractor.generic.path.Path(), + ]) + # out-of-bounds raises KeyError + self.assertRaises(IndexError, builder.build, 3) + + # building with args + builder = ExtractorBuilder([ + {'bsie.extractor.generic.constant.Constant': { + 'schema': ''' + bse:author rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "true"^^xsd:boolean . + bse:rating rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + ''', + 'tuples': [ + ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), + ('http://bsfs.ai/schema/Entity#rating', 123), + ], + }}]) + obj = builder.build(0) + import bsie.extractor.generic.constant + self.assertEqual(obj, bsie.extractor.generic.constant.Constant(''' + bse:author rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "true"^^xsd:boolean . + bse:rating rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + ''', [ + ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), + ('http://bsfs.ai/schema/Entity#rating', 123), + ])) + + # building with invalid args + self.assertRaises(errors.BuilderError, ExtractorBuilder( + [{'bsie.extractor.generic.path.Path': {'foo': 123}}]).build, 0) + # non-dict build specification + self.assertRaises(TypeError, ExtractorBuilder( + [('bsie.extractor.generic.path.Path', {})]).build, 0) + # multiple keys per build specification + self.assertRaises(TypeError, ExtractorBuilder( + [{'bsie.extractor.generic.path.Path': {}, + 'bsie.extractor.generic.stat.Stat': {}}]).build, 0) + # non-dict value for kwargs + self.assertRaises(TypeError, ExtractorBuilder( + [{'bsie.extractor.generic.path.Path': 123}]).build, 0) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/lib/test_bsie.py b/test/lib/test_bsie.py index 771a0c2..52f1d44 100644 --- a/test/lib/test_bsie.py +++ b/test/lib/test_bsie.py @@ -4,13 +4,15 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import os import unittest # bsie imports -from bsie.base import extractor -from bsie.tools import builder +from bsie.extractor import ExtractorBuilder +from bsie.extractor.base import SCHEMA_PREAMBLE +from bsie.lib import PipelineBuilder +from bsie.reader import ReaderBuilder from bsie.utils import bsfs, node, ns # objects to test @@ -22,9 +24,9 @@ from bsie.lib.bsie import BSIE class TestBSIE(unittest.TestCase): def setUp(self): # reader builder - rbuild = builder.ReaderBuilder({}) + rbuild = ReaderBuilder({}) # extractor builder - ebuild = builder.ExtractorBuilder([ + ebuild = ExtractorBuilder([ {'bsie.extractor.generic.path.Path': {}}, {'bsie.extractor.generic.stat.Stat': {}}, {'bsie.extractor.generic.constant.Constant': dict( @@ -39,7 +41,7 @@ class TestBSIE(unittest.TestCase): ]) # build pipeline self.prefix = bsfs.Namespace('http://example.com/local/') - pbuild = builder.PipelineBuilder(self.prefix, rbuild, ebuild) + pbuild = PipelineBuilder(self.prefix, rbuild, ebuild) self.pipeline = pbuild.build() def test_construction(self): @@ -50,7 +52,7 @@ class TestBSIE(unittest.TestCase): ns.bse.filesize, ns.bse.author, }) - self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(SCHEMA_PREAMBLE + ''' bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:string ; @@ -77,7 +79,7 @@ class TestBSIE(unittest.TestCase): ns.bse.filesize, ns.bse.author, }) - self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(SCHEMA_PREAMBLE + ''' bse:filesize rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:integer; @@ -95,7 +97,7 @@ class TestBSIE(unittest.TestCase): ns.bse.filesize, ns.bse.author, }) - self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(SCHEMA_PREAMBLE + ''' bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:string ; @@ -122,7 +124,7 @@ class TestBSIE(unittest.TestCase): self.assertSetEqual(set(lib.principals), { ns.bse.author, }) - self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(SCHEMA_PREAMBLE + ''' bse:author rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range xsd:string ; @@ -137,7 +139,7 @@ class TestBSIE(unittest.TestCase): self.assertSetEqual(set(lib.principals), { ns.bse.filesize, }) - self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + ''' + self.assertEqual(lib.schema, bsfs.schema.Schema.from_string(SCHEMA_PREAMBLE + ''' bse:filesize rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:File ; rdfs:range xsd:integer; diff --git a/test/lib/test_builder.py b/test/lib/test_builder.py new file mode 100644 index 0000000..273d620 --- /dev/null +++ b/test/lib/test_builder.py @@ -0,0 +1,107 @@ +""" + +Part of the bsie test suite. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import logging +import unittest + +# bsie imports +from bsie.extractor import ExtractorBuilder +from bsie.reader import ReaderBuilder +from bsie.utils import bsfs + +# objects to test +from bsie.lib import PipelineBuilder + + +## code ## + +class TestPipelineBuilder(unittest.TestCase): + def test_build(self): + prefix = bsfs.URI('http://example.com/local/file#') + c_schema = ''' + bse:author rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "true"^^xsd:boolean . + ''' + c_tuples = [('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I')] + # prepare builders + rbuild = ReaderBuilder({}) + ebuild = ExtractorBuilder([ + {'bsie.extractor.generic.path.Path': {}}, + {'bsie.extractor.generic.stat.Stat': {}}, + {'bsie.extractor.generic.constant.Constant': dict( + schema=c_schema, + tuples=c_tuples, + )}, + ]) + # build pipeline + builder = PipelineBuilder(prefix, rbuild, ebuild) + pipeline = builder.build() + # delayed import + import bsie.reader.path + import bsie.reader.stat + import bsie.extractor.generic.path + import bsie.extractor.generic.stat + import bsie.extractor.generic.constant + # check pipeline + self.assertDictEqual(pipeline._ext2rdr, { + bsie.extractor.generic.path.Path(): bsie.reader.path.Path(), + bsie.extractor.generic.stat.Stat(): bsie.reader.stat.Stat(), + bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, + }) + + # fail to load extractor + ebuild_err = ExtractorBuilder([ + {'bsie.extractor.generic.foo.Foo': {}}, + {'bsie.extractor.generic.path.Path': {}}, + ]) + with self.assertLogs(logging.getLogger('bsie.lib.builder'), logging.ERROR): + pipeline = PipelineBuilder(prefix, rbuild, ebuild_err).build() + self.assertDictEqual(pipeline._ext2rdr, { + bsie.extractor.generic.path.Path(): bsie.reader.path.Path()}) + + # fail to build extractor + ebuild_err = ExtractorBuilder([ + {'bsie.extractor.generic.path.Path': {'foo': 123}}, + {'bsie.extractor.generic.path.Path': {}}, + ]) + with self.assertLogs(logging.getLogger('bsie.lib.builder'), logging.ERROR): + pipeline = PipelineBuilder(prefix, rbuild, ebuild_err).build() + self.assertDictEqual(pipeline._ext2rdr, { + bsie.extractor.generic.path.Path(): bsie.reader.path.Path()}) + + # fail to load reader + with self.assertLogs(logging.getLogger('bsie.lib.builder'), logging.ERROR): + # switch reader of an extractor + old_reader = bsie.extractor.generic.path.Path.CONTENT_READER + bsie.extractor.generic.path.Path.CONTENT_READER = 'bsie.reader.foo.Foo' + # build pipeline with invalid reader reference + pipeline = PipelineBuilder(prefix, rbuild, ebuild).build() + self.assertDictEqual(pipeline._ext2rdr, { + bsie.extractor.generic.stat.Stat(): bsie.reader.stat.Stat(), + bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, + }) + # switch back + bsie.extractor.generic.path.Path.CONTENT_READER = old_reader + + # fail to build reader + rbuild_err = ReaderBuilder({'bsie.reader.stat.Stat': dict(foo=123)}) + with self.assertLogs(logging.getLogger('bsie.lib.builder'), logging.ERROR): + pipeline = PipelineBuilder(prefix, rbuild_err, ebuild).build() + self.assertDictEqual(pipeline._ext2rdr, { + bsie.extractor.generic.path.Path(): bsie.reader.path.Path(), + bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, + }) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/tools/test_pipeline.py b/test/lib/test_pipeline.py index a116a30..c6f7aba 100644 --- a/test/tools/test_pipeline.py +++ b/test/lib/test_pipeline.py @@ -4,14 +4,13 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import logging import os import unittest # bsie imports -from bsie.base import errors -from bsie.utils import bsfs, node, ns +from bsie.utils import bsfs, errors, node, ns import bsie.extractor.generic.constant import bsie.extractor.generic.path import bsie.extractor.generic.stat @@ -19,7 +18,7 @@ import bsie.reader.path import bsie.reader.stat # objects to test -from bsie.tools.pipeline import Pipeline +from bsie.lib.pipeline import Pipeline ## code ## @@ -140,7 +139,7 @@ class TestPipeline(unittest.TestCase): raise errors.ReaderError('reader error') pipeline = Pipeline(self.prefix, {bsie.extractor.generic.path.Path(): FaultyReader()}) - with self.assertLogs(logging.getLogger('bsie.tools.pipeline'), logging.ERROR): + with self.assertLogs(logging.getLogger('bsie.lib.pipeline'), logging.ERROR): testfile = os.path.join(os.path.dirname(__file__), 'testfile.t') p_filename = pipeline.schema.predicate(ns.bse.filename) self.assertSetEqual(set(pipeline(testfile, {p_filename})), set()) @@ -151,7 +150,7 @@ class TestPipeline(unittest.TestCase): raise errors.ExtractorError('extractor error') pipeline = Pipeline(self.prefix, {FaultyExtractor(): bsie.reader.path.Path()}) - with self.assertLogs(logging.getLogger('bsie.tools.pipeline'), logging.ERROR): + with self.assertLogs(logging.getLogger('bsie.lib.pipeline'), logging.ERROR): testfile = os.path.join(os.path.dirname(__file__), 'testfile.t') p_filename = pipeline.schema.predicate(ns.bse.filename) self.assertSetEqual(set(pipeline(testfile, {p_filename})), set()) diff --git a/test/base/test_reader.py b/test/reader/test_base.py index a907eb9..41f4c29 100644 --- a/test/base/test_reader.py +++ b/test/reader/test_base.py @@ -4,16 +4,16 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import unittest # objects to test -from bsie import base +from bsie.reader import Reader ## code ## -class StubReader(base.Reader): +class StubReader(Reader): def __call__(self, path): raise NotImplementedError() diff --git a/test/reader/test_builder.py b/test/reader/test_builder.py new file mode 100644 index 0000000..92e9edc --- /dev/null +++ b/test/reader/test_builder.py @@ -0,0 +1,54 @@ +""" + +Part of the bsie test suite. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import unittest + +# bsie imports +from bsie.utils import errors + +# objects to test +from bsie.reader import ReaderBuilder + + +## code ## + +class TestReaderBuilder(unittest.TestCase): + def test_build(self): + builder = ReaderBuilder({'bsie.reader.path.Path': {}}) + # build configured reader + cls = builder.build('bsie.reader.path.Path') + import bsie.reader.path + self.assertIsInstance(cls, bsie.reader.path.Path) + # build unconfigured reader + cls = builder.build('bsie.reader.stat.Stat') + import bsie.reader.stat + self.assertIsInstance(cls, bsie.reader.stat.Stat) + # re-build previous reader (test cache) + self.assertEqual(cls, builder.build('bsie.reader.stat.Stat')) + # test invalid + self.assertRaises(TypeError, builder.build, 123) + self.assertRaises(TypeError, builder.build, None) + self.assertRaises(ValueError, builder.build, '') + self.assertRaises(ValueError, builder.build, 'Path') + self.assertRaises(errors.BuilderError, builder.build, 'path.Path') + # invalid config + builder = ReaderBuilder({'bsie.reader.stat.Stat': dict(foo=123)}) + self.assertRaises(errors.BuilderError, builder.build, 'bsie.reader.stat.Stat') + builder = ReaderBuilder({'bsie.reader.stat.Stat': 123}) + self.assertRaises(TypeError, builder.build, 'bsie.reader.stat.Stat') + # no instructions + builder = ReaderBuilder({}) + cls = builder.build('bsie.reader.stat.Stat') + self.assertIsInstance(cls, bsie.reader.stat.Stat) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/reader/test_stat.py b/test/reader/test_stat.py index d12ad9c..fd9fdcd 100644 --- a/test/reader/test_stat.py +++ b/test/reader/test_stat.py @@ -4,12 +4,12 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import os import unittest # bsie imports -from bsie.base import errors +from bsie.utils import errors # objects to test from bsie.reader.stat import Stat diff --git a/test/tools/__init__.py b/test/tools/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/test/tools/__init__.py +++ /dev/null diff --git a/test/tools/test_builder.py b/test/tools/test_builder.py deleted file mode 100644 index 62c637c..0000000 --- a/test/tools/test_builder.py +++ /dev/null @@ -1,246 +0,0 @@ -""" - -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" -# imports -import logging -import unittest - -# bsie imports -from bsie import base -from bsie.utils import bsfs - -# objects to test -from bsie.tools.builder import ExtractorBuilder -from bsie.tools.builder import PipelineBuilder -from bsie.tools.builder import ReaderBuilder -from bsie.tools.builder import _safe_load -from bsie.tools.builder import _unpack_name - - -## code ## - -class TestUtils(unittest.TestCase): - def test_safe_load(self): - # invalid module - self.assertRaises(base.errors.LoaderError, _safe_load, 'dBGHMSAYOoKeKMpywDoKZQycENFPvN', 'foobar') - self.assertRaises(base.errors.LoaderError, _safe_load, 'dBGHMSAYOoKeKMpywDoKZQycENFPvN.bar', 'foobar') - # partially valid module - self.assertRaises(base.errors.LoaderError, _safe_load, 'os.foo', 'foobar') - # invalid class - self.assertRaises(base.errors.LoaderError, _safe_load, 'os.path', 'foo') - # valid module and class - cls = _safe_load('collections.abc', 'Container') - import collections.abc - self.assertEqual(cls, collections.abc.Container) - - def test_unpack_name(self): - self.assertRaises(TypeError, _unpack_name, 123) - self.assertRaises(TypeError, _unpack_name, None) - self.assertRaises(ValueError, _unpack_name, '') - self.assertRaises(ValueError, _unpack_name, 'path') - self.assertRaises(ValueError, _unpack_name, '.Path') - self.assertEqual(_unpack_name('path.Path'), ('path', 'Path')) - self.assertEqual(_unpack_name('path.foo.bar.Path'), ('path.foo.bar', 'Path')) - - -class TestReaderBuilder(unittest.TestCase): - def test_build(self): - builder = ReaderBuilder({'bsie.reader.path.Path': {}}) - # build configured reader - cls = builder.build('bsie.reader.path.Path') - import bsie.reader.path - self.assertIsInstance(cls, bsie.reader.path.Path) - # build unconfigured reader - cls = builder.build('bsie.reader.stat.Stat') - import bsie.reader.stat - self.assertIsInstance(cls, bsie.reader.stat.Stat) - # re-build previous reader (test cache) - self.assertEqual(cls, builder.build('bsie.reader.stat.Stat')) - # test invalid - self.assertRaises(TypeError, builder.build, 123) - self.assertRaises(TypeError, builder.build, None) - self.assertRaises(ValueError, builder.build, '') - self.assertRaises(ValueError, builder.build, 'Path') - self.assertRaises(base.errors.BuilderError, builder.build, 'path.Path') - # invalid config - builder = ReaderBuilder({'bsie.reader.stat.Stat': dict(foo=123)}) - self.assertRaises(base.errors.BuilderError, builder.build, 'bsie.reader.stat.Stat') - builder = ReaderBuilder({'bsie.reader.stat.Stat': 123}) - self.assertRaises(TypeError, builder.build, 'bsie.reader.stat.Stat') - # no instructions - builder = ReaderBuilder({}) - cls = builder.build('bsie.reader.stat.Stat') - self.assertIsInstance(cls, bsie.reader.stat.Stat) - - - -class TestExtractorBuilder(unittest.TestCase): - def test_iter(self): - # no specifications - self.assertListEqual(list(ExtractorBuilder([])), []) - # some specifications - builder = ExtractorBuilder([ - {'bsie.extractor.generic.path.Path': {}}, - {'bsie.extractor.generic.stat.Stat': {}}, - {'bsie.extractor.generic.path.Path': {}}, - ]) - self.assertListEqual(list(builder), [0, 1, 2]) - - def test_build(self): - # simple and repeated extractors - builder = ExtractorBuilder([ - {'bsie.extractor.generic.path.Path': {}}, - {'bsie.extractor.generic.stat.Stat': {}}, - {'bsie.extractor.generic.path.Path': {}}, - ]) - ext = [builder.build(0), builder.build(1), builder.build(2)] - import bsie.extractor.generic.path - import bsie.extractor.generic.stat - self.assertListEqual(ext, [ - bsie.extractor.generic.path.Path(), - bsie.extractor.generic.stat.Stat(), - bsie.extractor.generic.path.Path(), - ]) - # out-of-bounds raises KeyError - self.assertRaises(IndexError, builder.build, 3) - - # building with args - builder = ExtractorBuilder([ - {'bsie.extractor.generic.constant.Constant': { - 'schema': ''' - bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:string ; - bsfs:unique "true"^^xsd:boolean . - bse:rating rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - ''', - 'tuples': [ - ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), - ('http://bsfs.ai/schema/Entity#rating', 123), - ], - }}]) - obj = builder.build(0) - import bsie.extractor.generic.constant - self.assertEqual(obj, bsie.extractor.generic.constant.Constant(''' - bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:string ; - bsfs:unique "true"^^xsd:boolean . - bse:rating rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - ''', [ - ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), - ('http://bsfs.ai/schema/Entity#rating', 123), - ])) - - # building with invalid args - self.assertRaises(base.errors.BuilderError, ExtractorBuilder( - [{'bsie.extractor.generic.path.Path': {'foo': 123}}]).build, 0) - # non-dict build specification - self.assertRaises(TypeError, ExtractorBuilder( - [('bsie.extractor.generic.path.Path', {})]).build, 0) - # multiple keys per build specification - self.assertRaises(TypeError, ExtractorBuilder( - [{'bsie.extractor.generic.path.Path': {}, - 'bsie.extractor.generic.stat.Stat': {}}]).build, 0) - # non-dict value for kwargs - self.assertRaises(TypeError, ExtractorBuilder( - [{'bsie.extractor.generic.path.Path': 123}]).build, 0) - - - - -class TestPipelineBuilder(unittest.TestCase): - def test_build(self): - prefix = bsfs.URI('http://example.com/local/file#') - c_schema = ''' - bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range xsd:string ; - bsfs:unique "true"^^xsd:boolean . - ''' - c_tuples = [('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I')] - # prepare builders - rbuild = ReaderBuilder({}) - ebuild = ExtractorBuilder([ - {'bsie.extractor.generic.path.Path': {}}, - {'bsie.extractor.generic.stat.Stat': {}}, - {'bsie.extractor.generic.constant.Constant': dict( - schema=c_schema, - tuples=c_tuples, - )}, - ]) - # build pipeline - builder = PipelineBuilder(prefix, rbuild, ebuild) - pipeline = builder.build() - # delayed import - import bsie.reader.path - import bsie.reader.stat - import bsie.extractor.generic.path - import bsie.extractor.generic.stat - import bsie.extractor.generic.constant - # check pipeline - self.assertDictEqual(pipeline._ext2rdr, { - bsie.extractor.generic.path.Path(): bsie.reader.path.Path(), - bsie.extractor.generic.stat.Stat(): bsie.reader.stat.Stat(), - bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, - }) - - # fail to load extractor - ebuild_err = ExtractorBuilder([ - {'bsie.extractor.generic.foo.Foo': {}}, - {'bsie.extractor.generic.path.Path': {}}, - ]) - with self.assertLogs(logging.getLogger('bsie.tools.builder'), logging.ERROR): - pipeline = PipelineBuilder(prefix, rbuild, ebuild_err).build() - self.assertDictEqual(pipeline._ext2rdr, { - bsie.extractor.generic.path.Path(): bsie.reader.path.Path()}) - - # fail to build extractor - ebuild_err = ExtractorBuilder([ - {'bsie.extractor.generic.path.Path': {'foo': 123}}, - {'bsie.extractor.generic.path.Path': {}}, - ]) - with self.assertLogs(logging.getLogger('bsie.tools.builder'), logging.ERROR): - pipeline = PipelineBuilder(prefix, rbuild, ebuild_err).build() - self.assertDictEqual(pipeline._ext2rdr, { - bsie.extractor.generic.path.Path(): bsie.reader.path.Path()}) - - # fail to load reader - with self.assertLogs(logging.getLogger('bsie.tools.builder'), logging.ERROR): - # switch reader of an extractor - old_reader = bsie.extractor.generic.path.Path.CONTENT_READER - bsie.extractor.generic.path.Path.CONTENT_READER = 'bsie.reader.foo.Foo' - # build pipeline with invalid reader reference - pipeline = PipelineBuilder(prefix, rbuild, ebuild).build() - self.assertDictEqual(pipeline._ext2rdr, { - bsie.extractor.generic.stat.Stat(): bsie.reader.stat.Stat(), - bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, - }) - # switch back - bsie.extractor.generic.path.Path.CONTENT_READER = old_reader - - # fail to build reader - rbuild_err = ReaderBuilder({'bsie.reader.stat.Stat': dict(foo=123)}) - with self.assertLogs(logging.getLogger('bsie.tools.builder'), logging.ERROR): - pipeline = PipelineBuilder(prefix, rbuild_err, ebuild).build() - self.assertDictEqual(pipeline._ext2rdr, { - bsie.extractor.generic.path.Path(): bsie.reader.path.Path(), - bsie.extractor.generic.constant.Constant(c_schema, c_tuples): None, - }) - - -## main ## - -if __name__ == '__main__': - unittest.main() - -## EOF ## diff --git a/test/tools/testfile.t b/test/tools/testfile.t deleted file mode 100644 index 3b18e51..0000000 --- a/test/tools/testfile.t +++ /dev/null @@ -1 +0,0 @@ -hello world diff --git a/test/utils/filematcher/test_parser.py b/test/utils/filematcher/test_parser.py index a81d2ed..c594747 100644 --- a/test/utils/filematcher/test_parser.py +++ b/test/utils/filematcher/test_parser.py @@ -4,11 +4,11 @@ Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ -# imports +# standard imports import unittest -# inner-module imports -from bsie.base import errors +# bsie imports +from bsie.utils import errors from bsie.utils.filematcher import matcher # objects to test diff --git a/test/utils/test_loading.py b/test/utils/test_loading.py new file mode 100644 index 0000000..58ff166 --- /dev/null +++ b/test/utils/test_loading.py @@ -0,0 +1,48 @@ +""" + +Part of the bsie test suite. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import unittest + +# bsie imports +from bsie.utils import errors + +# objects to test +from bsie.utils.loading import safe_load, unpack_qualified_name + + +## code ## + +class TestUtils(unittest.TestCase): + def test_safe_load(self): + # invalid module + self.assertRaises(errors.LoaderError, safe_load, 'dBGHMSAYOoKeKMpywDoKZQycENFPvN', 'foobar') + self.assertRaises(errors.LoaderError, safe_load, 'dBGHMSAYOoKeKMpywDoKZQycENFPvN.bar', 'foobar') + # partially valid module + self.assertRaises(errors.LoaderError, safe_load, 'os.foo', 'foobar') + # invalid class + self.assertRaises(errors.LoaderError, safe_load, 'os.path', 'foo') + # valid module and class + cls = safe_load('collections.abc', 'Container') + import collections.abc + self.assertEqual(cls, collections.abc.Container) + + def test_unpack_qualified_name(self): + self.assertRaises(TypeError, unpack_qualified_name, 123) + self.assertRaises(TypeError, unpack_qualified_name, None) + self.assertRaises(ValueError, unpack_qualified_name, '') + self.assertRaises(ValueError, unpack_qualified_name, 'path') + self.assertRaises(ValueError, unpack_qualified_name, '.Path') + self.assertEqual(unpack_qualified_name('path.Path'), ('path', 'Path')) + self.assertEqual(unpack_qualified_name('path.foo.bar.Path'), ('path.foo.bar', 'Path')) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## |