diff options
Diffstat (limited to 'ext/testlib/uid.py')
-rw-r--r-- | ext/testlib/uid.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/ext/testlib/uid.py b/ext/testlib/uid.py new file mode 100644 index 000000000..fe56252a0 --- /dev/null +++ b/ext/testlib/uid.py @@ -0,0 +1,110 @@ +# Copyright (c) 2017 Mark D. Hill and David A. Wood +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Sean Wilson + +import os +import itertools + +import config + +class UID(object): + sep = ':' + type_idx, path_idx = range(2) + + def __init__(self, path, *args): + self.path = self._shorten_path(path) + self.attributes = args + + @staticmethod + def _shorten_path(path): + return os.path.relpath(path, + os.path.commonprefix((config.constants.testing_base, + path))) + + @staticmethod + def _full_path(short_path): + return os.path.join(config.constants.testing_base, short_path) + + @classmethod + def uid_to_path(cls, uid): + split_path = str(uid).split(cls.sep)[cls.path_idx] + return cls._full_path(split_path) + + @classmethod + def uid_to_class(cls, uid): + return globals()[uid.split(cls.sep)[cls.type_idx]] + + @classmethod + def from_suite(self, suite, filepath): + return SuiteUID(filepath, suite.name) + + @classmethod + def from_test(self, test, filepath): + return TestUID(filepath, test.name, test.parent_suite.name) + + @classmethod + def from_uid(cls, uid): + args = uid.split(cls.sep) + del args[cls.type_idx] + return cls.uid_to_class(uid)(*args) + + def __str__(self): + common_opts = { + self.path_idx: self.path, + self.type_idx: self.__class__.__name__ + } + return self.sep.join(itertools.chain( + [common_opts[0], common_opts[1]], + self.attributes)) + + def __hash__(self): + return hash(str(self)) + + def __eq__(self, other): + return type(self) == type(other) and str(self) == str(other) + + +class TestUID(UID): + def __init__(self, filename, test_name, suite_name): + UID.__init__(self, filename, suite_name, test_name) + + @property + def test(self): + return self.attributes[1] + + @property + def suite(self): + return self.attributes[0] + + +class SuiteUID(UID): + def __init__(self, filename, suite_name): + UID.__init__(self, filename, suite_name) + + @property + def suite(self): + return self.attributes[0] |