diff --git a/.github/workflows/es-actions.yml b/.github/workflows/es-actions.yml index 3fa379920..c3aadf8ea 100644 --- a/.github/workflows/es-actions.yml +++ b/.github/workflows/es-actions.yml @@ -43,45 +43,6 @@ jobs: ninja -Cout/mac/x64 ./tools/run-tests.py --engine="./out/mac/x64/escargot" new-es - build-on-windows: - runs-on: windows-2022 - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - uses: lukka/get-cmake@latest - - uses: GuillaumeFalourd/setup-windows10-sdk-action@v1.11 - with: - sdk-version: 20348 - - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: x86 - sdk: "10.0.20348.0" - - name: Install msvc redist package - run: | - (new-object System.Net.WebClient).DownloadFile('https://github.com/abbodi1406/vcredist/releases/download/v0.73.0/VisualCppRedist_AIO_x86_x64.exe','VisualCppRedist_AIO_x86_x64.exe') - .\VisualCppRedist_AIO_x86_x64.exe /y - - name: Copy octane - run: | - copy test\octane\*.js - dir - - name: Build Win32 Release - run: | - CMake -G "Visual Studio 16 2019" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=x86 -DESCARGOT_ARCH=x86 -DESCARGOT_MODE=release -Bout/win32_release_ninja/ -DESCARGOT_HOST=windows -DESCARGOT_OUTPUT=shell -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_LIBICU_SUPPORT_WITH_DLOPEN=OFF -DESCARGOT_TEST=ON -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release - CMake --build out/win32_release_ninja/ --config Release - .\out\win32_release_ninja\escargot.exe run.js - - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: x64 - sdk: "10.0.20348.0" - - name: Build Win64 Release - run: | - CMake -G "Visual Studio 16 2019" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=x64 -DESCARGOT_ARCH=x64 -DESCARGOT_MODE=release -Bout/win64_release_ninja/ -DESCARGOT_HOST=windows -DESCARGOT_OUTPUT=shell -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_LIBICU_SUPPORT_WITH_DLOPEN=OFF -DESCARGOT_TEST=ON -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release - CMake --build out/win64_release_ninja/ --config Release - .\out\win64_release_ninja\escargot.exe run.js - - if: ${{ failure() }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 15 build-test-on-android: runs-on: macos-12 strategy: @@ -455,3 +416,53 @@ jobs: run: $RUNNER --arch=x86 --engine="$GITHUB_WORKSPACE/out/wasm/x86/escargot" wasm-js - name: Run x64 test run: $RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/wasm/x64/escargot" wasm-js + + test-on-windows: + runs-on: windows-2022 + strategy: + matrix: + arch: [x86, x64] + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - uses: szenius/set-timezone@v1.2 + with: + timezoneWindows: "Pacific Standard Time" + - uses: lukka/get-cmake@latest + - uses: GuillaumeFalourd/setup-windows10-sdk-action@v1.11 + with: + sdk-version: 20348 + - name: Copy octane + run: | + copy test\octane\*.js + dir + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install msvc redist package + run: | + (new-object System.Net.WebClient).DownloadFile('https://github.com/abbodi1406/vcredist/releases/download/v0.73.0/VisualCppRedist_AIO_x86_x64.exe','VisualCppRedist_AIO_x86_x64.exe') + .\VisualCppRedist_AIO_x86_x64.exe /y + - uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + sdk: "10.0.20348.0" + - name: Build ${{ matrix.arch }} Release + run: | + CMake -G "Visual Studio 16 2019" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -DESCARGOT_ARCH=${{ matrix.arch }} -DESCARGOT_MODE=release -Bout/ -DESCARGOT_HOST=windows -DESCARGOT_OUTPUT=shell -DESCARGOT_LIBICU_SUPPORT=ON -DESCARGOT_LIBICU_SUPPORT_WITH_DLOPEN=OFF -DESCARGOT_THREADING=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release + CMake --build out/ --config Release + - name: Run test262 + run: | + set GC_FREE_SPACE_DIVISOR=1 + pip install chardet + python tools\run-tests.py --engine=%cd%\out\escargot.exe test262-without-intl402 + shell: cmd + - name: Run octane + run: | + dir + .\out\escargot.exe run.js + - if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 + timeout-minutes: 15 \ No newline at end of file diff --git a/src/runtime/DateObject.cpp b/src/runtime/DateObject.cpp index ce73c53a6..1446a7df9 100644 --- a/src/runtime/DateObject.cpp +++ b/src/runtime/DateObject.cpp @@ -1317,6 +1317,7 @@ String* DateObject::toTimeString(ExecutionState& state) snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%s%04d", getHours(state), getMinutes(state), getSeconds(state), (tzOffsetAsMin < 0) ? "-" : "+", std::abs(tzOffsetHour + tzOffsetMin)); StringBuilder sb; sb.appendString(buffer); + sb.appendChar(' '); sb.appendChar('('); sb.appendString(String::fromUTF8(timeZoneName.data(), timeZoneName.length())); sb.appendChar(')'); diff --git a/src/util/SpinLock.h b/src/util/SpinLock.h index d2daf73c5..1a8df3d90 100644 --- a/src/util/SpinLock.h +++ b/src/util/SpinLock.h @@ -31,8 +31,9 @@ class SpinLock { public: SpinLock() - : m_locked(ATOMIC_FLAG_INIT) + : m_locked() { + m_locked.clear(); } void lock() diff --git a/third_party/GCutil b/third_party/GCutil index 0d6fe0e6d..c4804a317 160000 --- a/third_party/GCutil +++ b/third_party/GCutil @@ -1 +1 @@ -Subproject commit 0d6fe0e6da3ef58b60554d425bf141f63997bc03 +Subproject commit c4804a317fa3cc481279f1724ede5c53439b06dc diff --git a/tools/run-tests.py b/tools/run-tests.py index 8c732241c..8987150f5 100755 --- a/tools/run-tests.py +++ b/tools/run-tests.py @@ -169,9 +169,7 @@ def run_internal_test(engine, arch): run(['python', 'driver.py', engine, 'internal-test-cases.txt'], cwd=INTERNAL_DIR) - -@runner('test262', default=True) -def run_test262(engine, arch): +def copy_test262_files(): TEST262_OVERRIDE_DIR = join(PROJECT_SOURCE_DIR, 'tools', 'test', 'test262') TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') @@ -182,7 +180,11 @@ def run_test262(engine, arch): copy(join(TEST262_OVERRIDE_DIR, 'parseTestRecord.py'), join(TEST262_DIR, 'tools', 'packaging', 'parseTestRecord.py')) copy(join(TEST262_OVERRIDE_DIR, 'test262.py'), join(TEST262_DIR, 'tools', 'packaging', 'test262.py')) # for parallel running (we should re-implement this for es6 suite) - stdout = run(['pypy', join('tools', 'packaging', 'test262.py'), +@runner('test262', default=True) +def run_test262(engine, arch): + copy_test262_files() + TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') + stdout = run(['python3', join('tools', 'packaging', 'test262.py'), '--command', engine, '--summary'], cwd=TEST262_DIR, @@ -193,18 +195,31 @@ def run_test262(engine, arch): if summary.find('- All tests succeeded') < 0: raise Exception('test262 failed') print('test262: All tests passed') - -@runner('test262-strict', default=True) -def run_test262_strict(engine, arch): - TEST262_OVERRIDE_DIR = join(PROJECT_SOURCE_DIR, 'tools', 'test', 'test262') + +@runner('test262-without-intl402', default=False) +def run_test262_without_intl402(engine, arch): + copy_test262_files() TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') + stdout = run(['python3', join('tools', 'packaging', 'test262.py'), + '--skip', 'Temporal', '--skip', 'intl402', + '--command', engine, + '--summary'], + cwd=TEST262_DIR, + env={'TZ': 'US/Pacific'}, + stdout=PIPE) - copy(join(TEST262_OVERRIDE_DIR, 'excludelist.orig.xml'), join(TEST262_DIR, 'excludelist.xml')) - copy(join(TEST262_OVERRIDE_DIR, 'test262.py'), join(TEST262_DIR, 'tools', 'packaging', 'test262.py')) # for parallel running (we should re-implement this for es6 suite) + summary = stdout.decode("utf-8").split('=== Test262 Summary ===')[1] + if summary.find('- All tests succeeded') < 0: + raise Exception('test262 failed') + print('test262: All tests passed') +@runner('test262-strict', default=False) +def run_test262_strict(engine, arch): + copy_test262_files() + TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') out = open('test262-strict_out', 'w') - run(['pypy', join('tools', 'packaging', 'test262.py'), + run(['python3', join('tools', 'packaging', 'test262.py'), '--command', engine, '--full-summary', '--strict_only'], @@ -225,17 +240,13 @@ def run_test262_strict(engine, arch): print('test262-strict: All tests passed') -@runner('test262-nonstrict', default=True) +@runner('test262-nonstrict', default=False) def run_test262_nonstrict(engine, arch): - TEST262_OVERRIDE_DIR = join(PROJECT_SOURCE_DIR, 'tools', 'test', 'test262') + copy_test262_files() TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') - - copy(join(TEST262_OVERRIDE_DIR, 'excludelist.orig.xml'), join(TEST262_DIR, 'excludelist.xml')) - copy(join(TEST262_OVERRIDE_DIR, 'test262.py'), join(TEST262_DIR, 'tools', 'packaging', 'test262.py')) # for parallel running (we should re-implement this for es6 suite) - out = open('test262-nonstrict_out', 'w') - run(['pypy', join('tools', 'packaging', 'test262.py'), + run(['python3', join('tools', 'packaging', 'test262.py'), '--command', engine, '--full-summary', '--non_strict_only'], @@ -262,17 +273,10 @@ def compile_test_data_runner(): @runner('test262-dump', default=False) def run_test262_dump(engine, arch): - TEST262_OVERRIDE_DIR = join(PROJECT_SOURCE_DIR, 'tools', 'test', 'test262') + copy_test262_files() TEST262_DIR = join(PROJECT_SOURCE_DIR, 'test', 'test262') - copy(join(TEST262_OVERRIDE_DIR, 'excludelist.orig.xml'), join(TEST262_DIR, 'excludelist.xml')) - copy(join(TEST262_OVERRIDE_DIR, 'cth.js'), join(TEST262_DIR, 'harness', 'cth.js')) - copy(join(TEST262_OVERRIDE_DIR, 'testIntl.js'), join(TEST262_DIR, 'harness', 'testIntl.js')) - - copy(join(TEST262_OVERRIDE_DIR, 'parseTestRecord.py'), join(TEST262_DIR, 'tools', 'packaging', 'parseTestRecord.py')) - copy(join(TEST262_OVERRIDE_DIR, 'test262.py'), join(TEST262_DIR, 'tools', 'packaging', 'test262.py')) # for parallel running (we should re-implement this for es6 suite) - - stdout = run(['pypy', join('tools', 'packaging', 'test262.py'), + stdout = run(['python3', join('tools', 'packaging', 'test262.py'), '--command', engine, '--summary'], cwd=TEST262_DIR, diff --git a/tools/test/test262/make_excludelist.py b/tools/test/test262/make_excludelist.py index ee50d16ec..c8db62416 100755 --- a/tools/test/test262/make_excludelist.py +++ b/tools/test/test262/make_excludelist.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function + import os import re diff --git a/tools/test/test262/monkeyYaml.py b/tools/test/test262/monkeyYaml.py index 26ac194b4..7125899f6 100644 --- a/tools/test/test262/monkeyYaml.py +++ b/tools/test/test262/monkeyYaml.py @@ -14,12 +14,16 @@ mYamlMultilineList = re.compile(r"^ *- (.*)$") def load(str): + return myReadDict(str.splitlines())[1] + +def myReadDict(lines, indent=""): dict = None key = None emptyLines = 0 - - lines = str.splitlines() while lines: + if not lines[0].startswith(indent): + break + line = lines.pop(0) if myIsAllSpaces(line): emptyLines += 1 @@ -31,7 +35,7 @@ def load(str): dict = {} key = result.group(1).strip() value = result.group(2).strip() - (lines, value) = myReadValue(lines, value) + (lines, value) = myReadValue(lines, value, indent) dict[key] = value else: if dict and key and key in dict: @@ -40,17 +44,20 @@ def load(str): else: raise Exception("monkeyYaml is confused at " + line) emptyLines = 0 - return dict + return lines, dict -def myReadValue(lines, value): - if value == ">": +def myReadValue(lines, value, indent): + if value == ">" or value == "|": (lines, value) = myMultiline(lines, value) value = value + "\n" return (lines, value) - if lines and not value and myMaybeList(lines[0]): - return myMultilineList(lines, value) - else: - return lines, myReadOneLine(value) + if lines and not value: + if myMaybeList(lines[0]): + return myMultilineList(lines, value) + indentMatch = re.match("(" + indent + r"\s+)", lines[0]) + if indentMatch: + return myReadDict(lines, indentMatch.group(1)) + return lines, myReadOneLine(value) def myMaybeList(value): return mYamlMultilineList.match(value) @@ -64,7 +71,7 @@ def myMultilineList(lines, value): leading = myLeadingSpaces(line) if myIsAllSpaces(line): pass - elif leading < indent: + elif indent is not None and leading < indent: lines.insert(0, line) break; else: diff --git a/tools/test/test262/parseTestRecord.py b/tools/test/test262/parseTestRecord.py index 4fe7c9789..b33003a8d 100644 --- a/tools/test/test262/parseTestRecord.py +++ b/tools/test/test262/parseTestRecord.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2011 by Google, Inc. All rights reserved. # This code is governed by the BSD license found in the LICENSE file. @@ -81,7 +81,7 @@ def yamlAttrParser(testRecord, attrs, name): parsed = yamlLoad(body) if (parsed is None): - print "Failed to parse yaml in name %s"%(name) + print("Failed to parse yaml in name %s"%(name)) return for key in parsed: @@ -101,7 +101,7 @@ def parseTestRecord(src, name): # we need to skip hashbang before copyright comment if len(src) > 1 and (src[0] == '#' or src[0] == '\\'): src = src[src.find("// Copyright"):] - elif src[:25].rfind("#!") is not -1: + elif src[:25].rfind("#!") != -1: src = src[src.find("// Copyright"):] match = matchParts(src, name) diff --git a/tools/test/test262/test262.py b/tools/test/test262/test262.py index 1f4e5cae2..3d324ad9b 100755 --- a/tools/test/test262/test262.py +++ b/tools/test/test262/test262.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2009 the Sputnik authors. All rights reserved. # This code is governed by the BSD license found in the LICENSE file. @@ -23,24 +23,17 @@ import shutil import json import stat -import signal import xml.etree.ElementTree as xmlj import unicodedata +import chardet from collections import Counter +is_windows = sys.platform.startswith('win') from parseTestRecord import parseTestRecord, stripHeader from packagerConfig import * -class Alarm(Exception): - pass - -def alarm_handler(signum, frame): - raise Alarm - -signal.signal(signal.SIGALRM, alarm_handler) - class Test262Error(Exception): def __init__(self, message): self.message = message @@ -48,11 +41,9 @@ def __init__(self, message): def ReportError(s): raise Test262Error(s) - - if not os.path.exists(EXCLUDED_FILENAME): - print "Cannot generate (JSON) test262 tests without a file," + \ - " %s, showing which tests have been disabled!" % EXCLUDED_FILENAME + print("Cannot generate (JSON) test262 tests without a file," + \ + " %s, showing which tests have been disabled!" % EXCLUDED_FILENAME) sys.exit(1) EXCLUDE_LIST = xml.dom.minidom.parse(EXCLUDED_FILENAME) EXCLUDE_REASON = EXCLUDE_LIST.getElementsByTagName("reason") @@ -95,6 +86,7 @@ def BuildOptions(): result.add_option("--print-handle", default="print", help="Command to print from console") result.add_option("--list-includes", default=False, action="store_true", help="List includes required by tests") + result.add_option("--skip", default=[], action="append", help="skip testcase pattern") return result @@ -122,20 +114,30 @@ def __init__(self, suffix="", prefix="tmp", text=False): self.fd = None self.name = None self.is_closed = False - self.Open() + self.open() - def Open(self): + def open(self): (self.fd, self.name) = tempfile.mkstemp( suffix = self.suffix, prefix = self.prefix, text = self.text) def Write(self, str): - os.write(self.fd, str) + os.write(self.fd, str.encode("utf-8")) def Read(self): - f = file(self.name) - result = f.read() + f = open(self.name, encoding="utf-8", newline='') + try: + result = f.read() + except UnicodeDecodeError: + f.close() + t = open(self.name, "rb") + rawdata = t.read() + t.close() + result = chardet.detect(rawdata) + charenc = result['encoding'] + f = open(self.name, encoding=charenc, newline='') + result = f.read() f.close() return result @@ -148,7 +150,7 @@ def Dispose(self): try: self.Close() os.unlink(self.name) - except OSError, e: + except OSError as e: logging.error("Error disposing temp file: %s", str(e)) @@ -165,20 +167,20 @@ def ReportOutcome(self, long_format): mode = self.case.GetMode() if self.HasUnexpectedOutcome(): if self.case.IsNegative(): - print "=== %s was expected to fail in %s, but didn't ===" % (name, mode) - print "--- expected error: %s ---\n" % self.case.GetNegative() + print("=== %s was expected to fail in %s, but didn't ===" % (name, mode)) + print("--- expected error: %s ---\n" % self.case.GetNegative()) else: if long_format: - print "=== %s failed in %s ===" % (name, mode) + print("=== %s failed in %s ===" % (name, mode)) else: - print "%s in %s: " % (name, mode) + print("%s in %s: " % (name, mode)) self.WriteOutput(sys.stdout) if long_format: - print "===" + print("===") elif self.case.IsNegative(): - print "%s failed in %s as expected" % (name, mode) + print("%s failed in %s as expected" % (name, mode)) else: - print "%s passed in %s" % (name, mode) + print("%s passed in %s" % (name, mode)) def WriteOutput(self, target): out = self.stdout.strip() @@ -192,8 +194,8 @@ def WriteOutput(self, target): def SafeFormat(self, msg): try: msg = msg.encode(encoding='ascii', errors='strict') - msg = msg.replace('\u000Bx', '?') - msg = msg.replace('\u000Cx', '?') + msg = msg.replace('\\u000Bx', '?') + msg = msg.replace('\\u000Cx', '?') except: return 'Output contained invalid characters' @@ -254,7 +256,7 @@ def __init__(self, suite, index, name, full_path, strict_mode): self.name = name self.full_path = full_path self.strict_mode = strict_mode - f = open(self.full_path) + f = open(self.full_path, encoding="utf-8", newline='') self.contents = f.read() self.source = self.contents f.close() @@ -376,19 +378,19 @@ def Execute(self, command): env = my_env ) - signal.alarm(120) # raise Alarm in 2 minutes - + is_timeout_expired = False try: - code = process.wait() - signal.alarm(0) # reset the alarm - except Alarm: + code = process.wait(60 * 10) + except subprocess.TimeoutExpired: + is_timeout_expired = true process.kill() process.wait() code = -1 - # code = process.wait() out = stdout.Read() err = stderr.Read() + if is_timeout_expired: + err = err + "(TimeoutExpired)" finally: stdout.Dispose() stderr.Dispose() @@ -454,7 +456,7 @@ def Run(self, command_template): return result def Print(self): - print self.GetSource() + print(self.GetSource()) def validate(self): flags = self.testRecord.get("flags") @@ -509,7 +511,7 @@ def CaseRunner(case): class TestSuite(object): - def __init__(self, root, strict_only, non_strict_only, unmarked_default, print_handle): + def __init__(self, root, strict_only, non_strict_only, unmarked_default, print_handle, skip_patterns): # TODO: derive from packagerConfig.py self.test_root = path.join(root, 'test') if len(ESCARGOT_DUMP262DATA): @@ -523,6 +525,7 @@ def __init__(self, root, strict_only, non_strict_only, unmarked_default, print_h self.print_handle = print_handle self.include_cache = { } self.total_test_number = 0 + self.skip_patterns = skip_patterns def Validate(self): if not path.exists(self.test_root): @@ -577,12 +580,17 @@ def EnumerateTests(self, tests): basename = path.basename(full_path)[:-3] name = rel_path.split(path.sep)[:-1] + [basename] file_path = rel_path[0:rel_path.rindex('.')] + if is_windows: + file_path = file_path.replace("\\", "/") if file_path in EXCLUDE_LIST: - #print 'Excluded: ' + rel_path skip = True elif EXCLUDE_LIST.count(basename) >= 1: - #print 'Excluded: ' + basename skip = True + else: + for s in self.skip_patterns: + if s in full_path: + skip = True + break if not self.non_strict_only: strict_case = TestCase(self, len(cases), name, full_path, True) @@ -609,9 +617,9 @@ def PrintSummary(self, progress, logfile): def write(s): if logfile: self.logf.write(s + "\n") - print s + print(s) - print + print() write("=== Test262 Summary ==="); count = progress.count succeeded = progress.succeeded @@ -626,13 +634,13 @@ def write(s): positive = [c for c in progress.failed_tests if not c.case.IsNegative()] negative = [c for c in progress.failed_tests if c.case.IsNegative()] if len(positive) > 0: - print + print() write("Test262 Failed Tests") for result in positive: write(" %s in %s" % (result.case.GetName(), result.case.GetMode())) write("Failed Tests End") if len(negative) > 0: - print + print() write("Test262 Expected to fail but passed") for result in negative: write(" %s in %s" % (result.case.GetName(), result.case.GetMode())) @@ -643,9 +651,9 @@ def PrintFull(self, progress, logfile): def write(s): if logfile: self.logf.write(s + "\n") - print s + print(s) - print + print() write("=== Test262 Summary ==="); count = progress.count succeeded = progress.succeeded @@ -658,13 +666,13 @@ def write(s): positive = [c for c in progress.succeeded_tests if not c.case.IsNegative()] negative = [c for c in progress.succeeded_tests if c.case.IsNegative()] if len(positive) > 0: - print + print() write("Test262 Succeeded Tests") for result in positive: write(" %s in %s (pass)" % (result.case.GetName(), result.case.GetMode())) write("Succeeded Tests End") if len(negative) > 0: - print + print() write("Test262 Expected to fail") for result in negative: write(" %s in %s (pass)" % (result.case.GetName(), result.case.GetMode())) @@ -673,13 +681,13 @@ def write(s): positive = [c for c in progress.failed_tests if not c.case.IsNegative()] negative = [c for c in progress.failed_tests if c.case.IsNegative()] if len(positive) > 0: - print + print() write("Test262 Failed Tests") for result in positive: write(" %s in %s (fail)" % (result.case.GetName(), result.case.GetMode())) write("Failed Tests End") if len(negative) > 0: - print + print() write("Test262 Expected to fail but passed") for result in negative: write(" %s in %s (fail)" % (result.case.GetName(), result.case.GetMode())) @@ -689,7 +697,7 @@ def PrintFailureOutput(self, progress, logfile): for result in progress.failed_tests: if logfile: self.WriteLog(result) - print + print() result.ReportOutcome(False) def Run(self, command_template, tests, print_summary, print_full, logname, junitfile): @@ -700,20 +708,20 @@ def Run(self, command_template, tests, print_summary, print_full, logname, junit ReportError("No tests to run") progress = ProgressIndicator(len(cases)) if logname: - self.logf = open(logname, "w") + self.logf = open(logname, "w", encoding="utf-8") if junitfile: - self.outfile = open(junitfile, "w") + self.outfile = open(junitfile, "w", encoding="utf-8") TestSuitesElement = xmlj.Element("testsuites") TestSuiteElement = xmlj.Element("testsuite") TestSuitesElement.append(TestSuiteElement) TestSuiteElement.attrib["name "] = "test262" for x in range(len(EXCLUDE_LIST)): - if self.ShouldRun (unicode(EXCLUDE_LIST[x].encode('utf-8','ignore')), tests): + if self.ShouldRun (str(EXCLUDE_LIST[x].encode('utf-8','ignore')), tests): SkipCaseElement = xmlj.Element("testcase") - SkipCaseElement.attrib["classname"] = unicode(EXCLUDE_LIST[x]).encode('utf-8','ignore') - SkipCaseElement.attrib["name"] = unicode(EXCLUDE_LIST[x]).encode('utf-8','ignore') + SkipCaseElement.attrib["classname"] = str(EXCLUDE_LIST[x]).encode('utf-8','ignore') + SkipCaseElement.attrib["name"] = str(EXCLUDE_LIST[x]).encode('utf-8','ignore') SkipElement = xmlj.Element("skipped") - SkipElement.attrib["message"] = unicode(EXCLUDE_REASON[x].firstChild.nodeValue) + SkipElement.attrib["message"] = str(EXCLUDE_REASON[x].firstChild.nodeValue) SkipCaseElement.append(SkipElement) TestSuiteElement.append(SkipCaseElement) @@ -769,7 +777,7 @@ def Run(self, command_template, tests, print_summary, print_full, logname, junit print print "Use --full-summary to see output from failed tests" ''' - print + print() return progress.failed def WriteLog(self, result): @@ -801,7 +809,7 @@ def ListIncludes(self, tests): includes = case.GetIncludeList() includes_dict.update(includes) - print includes_dict + print(includes_dict) def Main(): @@ -813,7 +821,8 @@ def Main(): options.strict_only, options.non_strict_only, options.unmarked_default, - options.print_handle) + options.print_handle, + options.skip) test_suite.Validate() if options.loglevel == 'debug': logging.basicConfig(level=logging.DEBUG) @@ -841,6 +850,6 @@ def Main(): try: code = Main() sys.exit(code) - except Test262Error, e: - print "Error: %s" % e.message + except Test262Error as e: + print("Error: %s" % e.message) sys.exit(1)