blob: e9f2f0e13edabfae1497463a8ec73d90942f3528 [file] [log] [blame]
import os
import mock
import hypothesis as h
import hypothesis.strategies as hs
import pytest
from .. import manifest, sourcefile, item, utils
MYPY = False
if MYPY:
# MYPY is set to True when run under Mypy.
from typing import Any
from typing import Type
def SourceFileWithTest(path, hash, cls, **kwargs):
# type: (str, str, Type[item.ManifestItem], **Any) -> sourcefile.SourceFile
s = mock.Mock(rel_path=path, hash=hash)
if cls == item.SupportFile:
test = cls("/foobar", path)
else:
assert issubclass(cls, item.URLManifestItem)
test = cls("/foobar", path, "/", utils.from_os_path(path), **kwargs)
s.manifest_items = mock.Mock(return_value=(cls.item_type, [test]))
return s # type: ignore
def SourceFileWithTests(path, hash, cls, variants):
# type: (str, str, Type[item.URLManifestItem], **Any) -> sourcefile.SourceFile
s = mock.Mock(rel_path=path, hash=hash)
tests = [cls("/foobar", path, "/", item[0], **item[1]) for item in variants]
s.manifest_items = mock.Mock(return_value=(cls.item_type, tests))
return s # type: ignore
@hs.composite
def rel_dir_file_path(draw):
length = draw(hs.integers(min_value=1, max_value=20))
if length == 1:
return "a"
else:
remaining = length - 2
alphabet = "a" + os.path.sep
mid = draw(hs.text(alphabet=alphabet, min_size=remaining, max_size=remaining))
return os.path.normcase("a" + mid + "a")
@hs.composite
def sourcefile_strategy(draw):
item_classes = [item.TestharnessTest, item.RefTest,
item.ManualTest, item.WebDriverSpecTest,
item.ConformanceCheckerTest, item.SupportFile]
cls = draw(hs.sampled_from(item_classes))
path = draw(rel_dir_file_path())
hash = draw(hs.text(alphabet="0123456789abcdef", min_size=40, max_size=40))
s = mock.Mock(rel_path=path, hash=hash)
if cls is item.RefTest:
ref_path = draw(rel_dir_file_path())
h.assume(path != ref_path)
ref_eq = draw(hs.sampled_from(["==", "!="]))
test = cls("/foobar", path, "/", utils.from_os_path(path), references=[(utils.from_os_path(ref_path), ref_eq)])
elif cls is item.SupportFile:
test = cls("/foobar", path)
else:
test = cls("/foobar", path, "/", utils.from_os_path(path))
s.manifest_items = mock.Mock(return_value=(cls.item_type, [test]))
return s
@h.given(hs.lists(sourcefile_strategy(),
min_size=1, max_size=1000, unique_by=lambda x: x.rel_path))
@h.example([SourceFileWithTest("a", "0"*40, item.ConformanceCheckerTest)])
def test_manifest_to_json(s):
m = manifest.Manifest()
assert m.update((item, True) for item in s) is True
json_str = m.to_json()
loaded = manifest.Manifest.from_json("/", json_str)
assert list(loaded) == list(m)
assert loaded.to_json() == json_str
@h.given(hs.lists(sourcefile_strategy(),
min_size=1, unique_by=lambda x: x.rel_path))
@h.example([SourceFileWithTest("a", "0"*40, item.TestharnessTest)])
@h.example([SourceFileWithTest("a", "0"*40, item.RefTest, references=[("/aa", "==")])])
def test_manifest_idempotent(s):
m = manifest.Manifest()
assert m.update((item, True) for item in s) is True
m1 = list(m)
assert m.update((item, True) for item in s) is False
assert list(m) == m1
def test_manifest_to_json_forwardslash():
m = manifest.Manifest()
s = SourceFileWithTest("a/b", "0"*40, item.TestharnessTest)
assert m.update([(s, True)]) is True
assert m.to_json() == {
'paths': {
'a/b': ('0000000000000000000000000000000000000000', 'testharness')
},
'version': 7,
'url_base': '/',
'items': {
'testharness': {
'a/b': [('a/b', {})]
}
}
}
@pytest.mark.skipif(os.sep != "\\", reason="backslash path")
def test_manifest_to_json_backslash():
m = manifest.Manifest()
s = SourceFileWithTest("a\\b", "0"*40, item.TestharnessTest)
assert m.update([(s, True)]) is True
assert m.to_json() == {
'paths': {
'a/b': ('0000000000000000000000000000000000000000', 'testharness')
},
'version': 7,
'url_base': '/',
'items': {
'testharness': {
'a/b': [('a/b', {})]
}
}
}
def test_manifest_from_json_backslash():
json_obj = {
'paths': {
'a\\b': ('0000000000000000000000000000000000000000', 'testharness')
},
'version': 7,
'url_base': '/',
'items': {
'testharness': {
'a\\b': [['a/b', {}]]
}
}
}
with pytest.raises(ValueError):
manifest.Manifest.from_json("/", json_obj)
def test_reftest_computation_chain():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, references=[("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTest, references=[("/test3", "==")])
m.update([(s1, True), (s2, True)])
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
assert list(m) == [("reftest", test1.path, {test1}),
("reftest", test2.path, {test2})]
def test_iterpath():
m = manifest.Manifest()
sources = [SourceFileWithTest("test1", "0"*40, item.RefTest, references=[("/test1-ref", "==")]),
SourceFileWithTests("test2", "1"*40, item.TestharnessTest, [("test2-1.html", {}),
("test2-2.html", {})]),
SourceFileWithTest("test3", "0"*40, item.TestharnessTest)]
m.update([(s, True) for s in sources])
assert {item.url for item in m.iterpath("test2")} == {"/test2-1.html",
"/test2-2.html"}
assert set(m.iterpath("missing")) == set()
def test_no_update():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.TestharnessTest)
s2 = SourceFileWithTest("test2", "0"*40, item.TestharnessTest)
m.update([(s1, True), (s2, True)])
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
assert list(m) == [("testharness", test1.path, {test1}),
("testharness", test2.path, {test2})]
s1_1 = SourceFileWithTest("test1", "1"*40, item.ManualTest)
m.update([(s1_1, True), (s2.rel_path, False)])
test1_1 = s1_1.manifest_items()[1][0]
assert list(m) == [("manual", test1_1.path, {test1_1}),
("testharness", test2.path, {test2})]
def test_no_update_delete():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.TestharnessTest)
s2 = SourceFileWithTest("test2", "0"*40, item.TestharnessTest)
m.update([(s1, True), (s2, True)])
test1 = s1.manifest_items()[1][0]
s1_1 = SourceFileWithTest("test1", "1"*40, item.ManualTest)
m.update([(s1_1.rel_path, False)])
assert list(m) == [("testharness", test1.path, {test1})]
def test_update_from_json():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.TestharnessTest)
s2 = SourceFileWithTest("test2", "0"*40, item.TestharnessTest)
m.update([(s1, True), (s2, True)])
json_str = m.to_json()
m = manifest.Manifest.from_json("/", json_str)
m.update([(s1, True)])
test1 = s1.manifest_items()[1][0]
assert list(m) == [("testharness", test1.path, {test1})]
def test_update_from_json_modified():
# Create the original manifest
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.TestharnessTest)
m.update([(s1, True)])
json_str = m.to_json()
# Reload it from JSON
m = manifest.Manifest.from_json("/", json_str)
# Update it with timeout="long"
s2 = SourceFileWithTest("test1", "1"*40, item.TestharnessTest, timeout="long")
m.update([(s2, True)])
json_str = m.to_json()
assert json_str == {
'items': {'testharness': {'test1': [('test1', {"timeout": "long"})]}},
'paths': {'test1': ('1111111111111111111111111111111111111111',
'testharness')},
'url_base': '/',
'version': 7
}