0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-29 08:58:01 -04:00
denoland-deno/tools/integration_tests.py
Bartek Iwańczuk 43c6c1a9f5 Refactor test infrastructure (#2432)
* use subclass of unittest.TestCase for all test cases

* allow to run single test file (eg. python tools/integration_tests.py)

* test filtering (via --pattern/-p CLI flag)

* use common CLI parser for all tests:
  usage: test.py [-h] [--failfast] [--verbose] [--executable EXECUTABLE]
               [--release] [--pattern PATTERN] [--build-dir BUILD_DIR]

  optional arguments:
  -h, --help            show this help message and exit
  --failfast, -f        Stop on first failure
  --verbose, -v         Verbose output
  --executable EXECUTABLE
                        Use external executable of Deno
  --release             Test against release executable
  --pattern PATTERN, -p PATTERN
                        Run tests that match provided pattern
  --build-dir BUILD_DIR
                        Deno build directory

* respect NO_COLOR variable
2019-06-03 12:35:55 -04:00

109 lines
3.6 KiB
Python
Executable file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
# Given a deno executable, this script executes several integration tests with
# it. The tests are stored in /tests/ and each is specified in a .yaml file
# where a description, command line, and output are specified. Optionally an
# exit code can be specified.
#
# Usage: integration_tests.py [path to deno executable]
import os
import re
import subprocess
import http_server
from test_util import DenoTestCase, run_tests
from util import root_path, tests_path, pattern_match, rmtree
def strip_ansi_codes(s):
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
return ansi_escape.sub('', s)
def read_test(file_name):
with open(file_name, "r") as f:
test_file = f.read()
lines = test_file.splitlines()
test_dict = {}
for line in lines:
if line.strip().startswith("#"):
# skip comments
continue
key, value = re.split(r":\s+", line)
test_dict[key] = value
return test_dict
def str2bool(v):
if v == "true":
return True
elif v == "false":
return False
else:
raise ValueError("Bad boolean value")
class TestIntegrations(DenoTestCase):
@classmethod
def _test(cls, test_filename):
# Return thunk to test for js file,
# This is to 'trick' unittest so as to generate these dynamically.
return lambda self: self.generate(test_filename)
def generate(self, test_filename):
test_abs = os.path.join(tests_path, test_filename)
test = read_test(test_abs)
exit_code = int(test.get("exit_code", 0))
args = test.get("args", "").split(" ")
check_stderr = str2bool(test.get("check_stderr", "false"))
stderr = subprocess.STDOUT if check_stderr else open(os.devnull, 'w')
stdin_input = (test.get("input",
"").strip().decode("string_escape").replace(
"\r\n", "\n"))
has_stdin_input = len(stdin_input) > 0
output_abs = os.path.join(root_path, test.get("output", ""))
with open(output_abs, 'r') as f:
expected_out = f.read()
cmd = [self.deno_exe] + args
actual_code = 0
try:
if has_stdin_input:
# Provided stdin
proc = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=stderr)
actual_out, _ = proc.communicate(stdin_input)
actual_out = actual_out.replace("\r\n", "\n")
else:
# No stdin sent
actual_out = subprocess.check_output(
cmd, universal_newlines=True, stderr=stderr)
except subprocess.CalledProcessError as e:
actual_code = e.returncode
actual_out = e.output
self.assertEqual(exit_code, actual_code)
actual_out = strip_ansi_codes(actual_out)
if not pattern_match(expected_out, actual_out):
# This will always throw since pattern_match failed.
self.assertEqual(expected_out, actual_out)
# Add a methods for each test file in tests_path.
for fn in sorted(
filename for filename in os.listdir(tests_path)
if filename.endswith(".test")):
t = TestIntegrations._test(fn)
tn = t.__name__ = "test_" + fn.split(".")[0]
setattr(TestIntegrations, tn, t)
if __name__ == "__main__":
with http_server.spawn():
run_tests()