blob: a0c079dc043ed1211de85557f3d37580843f69d2 [file] [log] [blame]
# 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))