summaryrefslogtreecommitdiffstats
path: root/layout/tools/reftest/reftest/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'layout/tools/reftest/reftest/__init__.py')
-rw-r--r--layout/tools/reftest/reftest/__init__.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/layout/tools/reftest/reftest/__init__.py b/layout/tools/reftest/reftest/__init__.py
new file mode 100644
index 000000000..a0c079dc0
--- /dev/null
+++ b/layout/tools/reftest/reftest/__init__.py
@@ -0,0 +1,132 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import unicode_literals
+
+import os
+import re
+
+RE_COMMENT = re.compile(r'\s+#')
+RE_HTTP = re.compile(r'HTTP\((\.\.(\/\.\.)*)\)')
+RE_PROTOCOL = re.compile(r'^\w+:')
+FAILURE_TYPES = (
+ 'fails',
+ 'fails-if',
+ 'needs-focus',
+ 'random',
+ 'random-if',
+ 'silentfail',
+ 'silentfail-if',
+ 'skip',
+ 'skip-if',
+ 'slow',
+ 'slow-if',
+ 'fuzzy',
+ 'fuzzy-if',
+ 'require-or',
+ 'asserts',
+ 'asserts-if',
+)
+PREF_ITEMS = (
+ 'pref',
+ 'test-pref',
+ 'ref-pref',
+)
+
+class ReftestManifest(object):
+ """Represents a parsed reftest manifest.
+
+ We currently only capture file information because that is the only thing
+ tools require.
+ """
+ def __init__(self, finder=None):
+ self.path = None
+ self.dirs = set()
+ self.files = set()
+ self.manifests = set()
+ self.tests = set()
+ self.finder = finder
+
+ def load(self, path):
+ """Parse a reftest manifest file."""
+ normalized_path = os.path.normpath(os.path.abspath(path))
+ self.manifests.add(normalized_path)
+ if not self.path:
+ self.path = normalized_path
+
+ mdir = os.path.dirname(normalized_path)
+ self.dirs.add(mdir)
+
+ if self.finder:
+ lines = self.finder.get(path).read().splitlines()
+ else:
+ with open(path, 'r') as fh:
+ lines = fh.read().splitlines()
+
+ urlprefix = ''
+ for line in lines:
+ line = line.decode('utf-8')
+
+ # Entire line is a comment.
+ if line.startswith('#'):
+ continue
+
+ # Comments can begin mid line. Strip them.
+ m = RE_COMMENT.search(line)
+ if m:
+ line = line[:m.start()]
+ line = line.strip()
+ if not line:
+ continue
+
+ items = line.split()
+ tests = []
+
+ for i in range(len(items)):
+ item = items[i]
+
+ if item.startswith(FAILURE_TYPES):
+ continue
+ if item.startswith(PREF_ITEMS):
+ continue
+ if item == 'HTTP':
+ continue
+
+ m = RE_HTTP.match(item)
+ if m:
+ # Need to package the referenced directory.
+ self.dirs.add(os.path.normpath(os.path.join(
+ mdir, m.group(1))))
+ continue
+
+ if item == 'url-prefix':
+ urlprefix = items[i+1]
+ break
+
+ if item == 'default-preferences':
+ break
+
+ if item == 'include':
+ self.load(os.path.join(mdir, items[i+1]))
+ break
+
+ if item == 'load' or item == 'script':
+ tests.append(items[i+1])
+ break
+
+ if item == '==' or item == '!=':
+ tests.extend(items[i+1:i+3])
+ break
+
+ for f in tests:
+ # We can't package about: or data: URIs.
+ # Discarding data isn't correct for a parser. But retaining
+ # all data isn't currently a requirement.
+ if RE_PROTOCOL.match(f):
+ continue
+
+ test = os.path.normpath(os.path.join(mdir, urlprefix + f))
+ self.files.add(test)
+ self.dirs.add(os.path.dirname(test))
+ self.tests.add((test, normalized_path))