1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import os.path
import re
import subprocess
import sys
import tempfile
import unittest
from src.test.skylark import testenv
class SkylarkTest(unittest.TestCase):
"""Tests for Skylark.
In a test file, chunks are separated by "---". Each chunk is evaluated
separately. Use "###" to specify the expected error. If there is no "###",
the test will succeed iff there is no error.
"""
CHUNK_SEP = "---"
ERR_SEP = "###"
seen_error = False
def chunks(self, path):
code = []
expected_errors = []
with open(path, mode="rb") as f:
for line in f:
line = line.decode("utf-8")
if line.strip() == self.CHUNK_SEP:
yield code, expected_errors
expected_errors = []
code = []
else:
code.append(line)
i = line.find(self.ERR_SEP)
if i >= 0:
expected_errors.append(line[i + len(self.ERR_SEP):].strip())
yield code, expected_errors
def evaluate(self, f):
"""Execute Skylark file, return stderr."""
proc = subprocess.Popen(
[testenv.SKYLARK_BINARY_PATH, f], stderr=subprocess.PIPE)
_, stderr = proc.communicate()
return stderr
def check_output(self, output, expected):
if expected and not output:
self.seen_error = True
print("Expected error:", expected)
if output and not expected:
self.seen_error = True
print("Unexpected error:", output)
for exp in expected:
# Try both substring and regex matching.
if exp not in output and not re.search(exp, output):
self.seen_error = True
print("Error `{}` not found, got: `{}`".format(exp, output))
PRELUDE = """
def assert_eq(x, y):
if x != y:
fail("%r != %r" % (x, y))
def assert_(cond, msg="assertion failed"):
if not cond:
fail(msg)
"""
def testFile(self):
t = test_file
print("===", t, "===")
f = os.path.join(testenv.SKYLARK_TESTDATA_PATH, t)
for chunk, expected in self.chunks(f):
with tempfile.NamedTemporaryFile(
mode="wb", suffix=".sky", delete=False) as tmp:
lines = [line.encode("utf-8") for line in
[self.PRELUDE] + chunk]
tmp.writelines(lines)
output = self.evaluate(tmp.name).decode("utf-8")
os.unlink(tmp.name)
self.check_output(output, expected)
if self.seen_error:
raise Exception("Test failed")
if __name__ == "__main__":
# Test filename is the last argument on the command-line.
test_file = sys.argv[-1]
unittest.main(argv=sys.argv[1:])
|