mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
lsp.py: Port to support running on Windows & adapt to changes due to prior merged PR.
- lsp.py: Fixes invalid-syntax by Python interpreter on Windows CI (older Python version). - lsp.py: Savely strip CRLF from right side of the string, ignoring accidental multiple occurrences of \r (such as \r\r\n). - lsp.py: Fixes reading single character from stdin (wrt. Windows platform). - lsp.py: Adds header line reading to I/O tracing (useful for debugging). - lsp.py: When running the tests on Windows, don't care test file content's newlines but simply expect LFs (instead of CRLF for example). - Apply pylint notes. - Fixing use of @functools.lru_cache for older python versions (CircleCI Windows)
This commit is contained in:
parent
c2f245b40a
commit
e8d07772d9
@ -1283,6 +1283,9 @@ jobs:
|
||||
- run:
|
||||
name: Install LSP test dependencies
|
||||
command: python -m pip install --user deepdiff colorama
|
||||
- run:
|
||||
name: Inspect lsp.py
|
||||
command: Get-Content ./test/lsp.py
|
||||
- run:
|
||||
name: Executing solc LSP test suite
|
||||
command: python ./test/lsp.py .\build\solc\Release\solc.exe
|
||||
|
70
test/lsp.py
70
test/lsp.py
@ -1,26 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
# pragma pylint: disable=too-many-lines
|
||||
# test line 1
|
||||
import argparse
|
||||
import fnmatch
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
import re
|
||||
import tty
|
||||
import functools
|
||||
from collections import namedtuple
|
||||
from copy import deepcopy
|
||||
from enum import Enum, auto
|
||||
from itertools import islice
|
||||
from pathlib import PurePath
|
||||
from typing import Any, List, Optional, Tuple, Union
|
||||
from itertools import islice
|
||||
|
||||
from enum import Enum, auto
|
||||
|
||||
import colorama # Enables the use of SGR & CUP terminal VT sequences on Windows.
|
||||
import colorama # Enables the use of SGR & CUP terminal VT sequences on Windows.
|
||||
from deepdiff import DeepDiff
|
||||
|
||||
if os.name == 'nt':
|
||||
# pragma pylint: disable=import-error
|
||||
import msvcrt
|
||||
else:
|
||||
import tty
|
||||
# Turn off user input buffering so we get the input immediately,
|
||||
# not only after a line break
|
||||
tty.setcbreak(sys.stdin.fileno())
|
||||
|
||||
|
||||
def escape_string(text: str) -> str:
|
||||
"""
|
||||
Trivially escapes given input string's \r \n and \\.
|
||||
"""
|
||||
return text.translate(str.maketrans({
|
||||
"\r": r"\r",
|
||||
"\n": r"\n",
|
||||
"\\": r"\\"
|
||||
}))
|
||||
|
||||
|
||||
def getCharFromStdin():
|
||||
"""
|
||||
Gets a single character from stdin without line-buffering.
|
||||
"""
|
||||
if os.name == 'nt':
|
||||
# pragma pylint: disable=import-error
|
||||
return msvcrt.getch().decode("utf-8")
|
||||
else:
|
||||
return sys.stdin.buffer.read(1)
|
||||
|
||||
|
||||
"""
|
||||
Named tuple that holds various regexes used to parse the test specification.
|
||||
"""
|
||||
@ -101,7 +132,6 @@ class BadHeader(Exception):
|
||||
def __init__(self, msg: str):
|
||||
super().__init__("Bad header: " + msg)
|
||||
|
||||
|
||||
class JsonRpcProcess:
|
||||
exe_path: str
|
||||
exe_args: List[str]
|
||||
@ -144,10 +174,12 @@ class JsonRpcProcess:
|
||||
# server quit
|
||||
return None
|
||||
line = line.decode("utf-8")
|
||||
if self.trace_io:
|
||||
print(f"Received header-line: {escape_string(line)}")
|
||||
if not line.endswith("\r\n"):
|
||||
raise BadHeader("missing newline")
|
||||
# remove the "\r\n"
|
||||
line = line[:-2]
|
||||
# Safely remove the "\r\n".
|
||||
line = line.rstrip("\r\n")
|
||||
if line == '':
|
||||
break # done with the headers
|
||||
if line.startswith(CONTENT_LENGTH_HEADER):
|
||||
@ -589,7 +621,7 @@ class FileTestRunner:
|
||||
|
||||
while True:
|
||||
print("(u)pdate/(r)etry/(i)gnore?")
|
||||
user_response = sys.stdin.read(1)
|
||||
user_response = getCharFromStdin()
|
||||
if user_response == "i":
|
||||
return self.TestResult.SuccessOrIgnored
|
||||
|
||||
@ -787,7 +819,7 @@ class SolidityLSPTestSuite: # {{{
|
||||
in the test path (test/libsolidity/lsp).
|
||||
"""
|
||||
with open(self.get_test_file_path(test_case_name), mode="r", encoding="utf-8", newline='') as f:
|
||||
return f.read()
|
||||
return f.read().replace("\r\n", "\n")
|
||||
|
||||
def require_params_for_method(self, method_name: str, message: dict) -> Any:
|
||||
"""
|
||||
@ -1059,7 +1091,7 @@ class SolidityLSPTestSuite: # {{{
|
||||
"""
|
||||
while True:
|
||||
print("(u)pdate/(r)etry/(s)kip file?")
|
||||
user_response = sys.stdin.read(1)
|
||||
user_response = getCharFromStdin()
|
||||
if user_response == "u":
|
||||
while True:
|
||||
try:
|
||||
@ -1068,8 +1100,8 @@ class SolidityLSPTestSuite: # {{{
|
||||
# pragma pylint: disable=broad-except
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if ret := self.user_interaction_failed_autoupdate(test):
|
||||
return ret
|
||||
if self.user_interaction_failed_autoupdate(test):
|
||||
return True
|
||||
elif user_response == 's':
|
||||
return True
|
||||
elif user_response == 'r':
|
||||
@ -1077,7 +1109,7 @@ class SolidityLSPTestSuite: # {{{
|
||||
|
||||
def user_interaction_failed_autoupdate(self, test):
|
||||
print("(e)dit/(r)etry/(s)kip file?")
|
||||
user_response = sys.stdin.read(1)
|
||||
user_response = getCharFromStdin()
|
||||
if user_response == "r":
|
||||
print("retrying...")
|
||||
# pragma pylint: disable=no-member
|
||||
@ -1142,7 +1174,7 @@ class SolidityLSPTestSuite: # {{{
|
||||
marker = self.get_file_tags("lib")["@diagnostics"]
|
||||
self.expect_diagnostic(report['diagnostics'][0], code=2072, marker=marker)
|
||||
|
||||
@functools.lru_cache # pragma pylint: disable=lru-cache-decorating-method
|
||||
@functools.lru_cache() # pragma pylint: disable=lru-cache-decorating-method
|
||||
def get_file_tags(self, test_name: str, verbose=False):
|
||||
"""
|
||||
Finds all tags (e.g. @tagname) in the given test and returns them as a
|
||||
@ -1653,10 +1685,8 @@ class SolidityLSPTestSuite: # {{{
|
||||
# }}}
|
||||
# }}}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Turn off user input buffering so we get the input immediately,
|
||||
# not only after a line break
|
||||
tty.setcbreak(sys.stdin.fileno())
|
||||
suite = SolidityLSPTestSuite()
|
||||
exit_code = suite.main()
|
||||
sys.exit(exit_code)
|
||||
|
Loading…
Reference in New Issue
Block a user