Add python tap runner to the tree
[babeltrace.git] / tests / utils / python / tap / rules.py
diff --git a/tests/utils/python/tap/rules.py b/tests/utils/python/tap/rules.py
new file mode 100644 (file)
index 0000000..8e00329
--- /dev/null
@@ -0,0 +1,98 @@
+# Copyright (c) 2016, Matt Layman
+
+from tap.adapter import Adapter
+from tap.directive import Directive
+from tap.i18n import _
+from tap.line import Result
+
+
+class Rules(object):
+
+    def __init__(self, filename, suite):
+        self._filename = filename
+        self._suite = suite
+        self._lines_seen = {'plan': [], 'test': 0, 'version': []}
+
+    def check(self, final_line_count):
+        """Check the status of all provided data and update the suite."""
+        if self._lines_seen['version']:
+            self._process_version_lines()
+        self._process_plan_lines(final_line_count)
+
+    def _process_version_lines(self):
+        """Process version line rules."""
+        if len(self._lines_seen['version']) > 1:
+            self._add_error(_('Multiple version lines appeared.'))
+        elif self._lines_seen['version'][0] != 1:
+            self._add_error(_('The version must be on the first line.'))
+
+    def _process_plan_lines(self, final_line_count):
+        """Process plan line rules."""
+        if not self._lines_seen['plan']:
+            self._add_error(_('Missing a plan.'))
+            return
+
+        if len(self._lines_seen['plan']) > 1:
+            self._add_error(_('Only one plan line is permitted per file.'))
+            return
+
+        plan, at_line = self._lines_seen['plan'][0]
+        if not self._plan_on_valid_line(at_line, final_line_count):
+            self._add_error(
+                _('A plan must appear at the beginning or end of the file.'))
+            return
+
+        if plan.expected_tests != self._lines_seen['test']:
+            self._add_error(_(
+                'Expected {expected_count} tests '
+                'but only {seen_count} ran.').format(
+                    expected_count=plan.expected_tests,
+                    seen_count=self._lines_seen['test']))
+
+    def _plan_on_valid_line(self, at_line, final_line_count):
+        """Check if a plan is on a valid line."""
+        # Put the common cases first.
+        if at_line == 1 or at_line == final_line_count:
+            return True
+
+        # The plan may only appear on line 2 if the version is at line 1.
+        after_version = (
+            self._lines_seen['version'] and
+            self._lines_seen['version'][0] == 1 and
+            at_line == 2)
+        if after_version:
+            return True
+
+        return False
+
+    def handle_bail(self, bail):
+        """Handle a bail line."""
+        self._add_error(_('Bailed: {reason}').format(reason=bail.reason))
+
+    def handle_file_does_not_exist(self):
+        """Handle a test file that does not exist."""
+        self._add_error(_('{filename} does not exist.').format(
+            filename=self._filename))
+
+    def handle_skipping_plan(self, skip_plan):
+        """Handle a plan that contains a SKIP directive."""
+        skip_line = Result(
+            True, None, skip_plan.directive.text, Directive('SKIP'))
+        self._suite.addTest(Adapter(self._filename, skip_line))
+
+    def saw_plan(self, plan, at_line):
+        """Record when a plan line was seen."""
+        self._lines_seen['plan'].append((plan, at_line))
+
+    def saw_test(self):
+        """Record when a test line was seen."""
+        self._lines_seen['test'] += 1
+
+    def saw_version_at(self, line_counter):
+        """Record when a version line was seen."""
+        self._lines_seen['version'].append(line_counter)
+
+    def _add_error(self, message):
+        """Add an error test to the suite."""
+        error_line = Result(False, None, message, Directive(''))
+        self._suite.addTest(Adapter(self._filename, error_line))
This page took 0.024142 seconds and 4 git commands to generate.