Replace yapf with black
This commit is contained in:
@@ -14,18 +14,20 @@ from cmake_language_server.server import CMakeLanguageServer
|
||||
|
||||
@pytest.fixture()
|
||||
def cmake_build(shared_datadir):
|
||||
source = shared_datadir / 'cmake'
|
||||
build = source / 'build'
|
||||
source = shared_datadir / "cmake"
|
||||
build = source / "build"
|
||||
build.mkdir()
|
||||
p = run(['cmake', str(source)],
|
||||
cwd=build,
|
||||
stdout=PIPE,
|
||||
stderr=PIPE,
|
||||
universal_newlines=True)
|
||||
p = run(
|
||||
["cmake", str(source)],
|
||||
cwd=build,
|
||||
stdout=PIPE,
|
||||
stderr=PIPE,
|
||||
universal_newlines=True,
|
||||
)
|
||||
if p.returncode != 0:
|
||||
logging.error('env:\n' + pprint.pformat(os.environ))
|
||||
logging.error('stdout:\n' + p.stdout)
|
||||
logging.error('stderr:\n' + p.stderr)
|
||||
logging.error("env:\n" + pprint.pformat(os.environ))
|
||||
logging.error("stdout:\n" + p.stdout)
|
||||
logging.error("stderr:\n" + p.stderr)
|
||||
raise RuntimeError("CMake failed")
|
||||
yield build
|
||||
|
||||
@@ -40,7 +42,7 @@ def client_server():
|
||||
# disable `close()` to avoid error messages
|
||||
close = ls.loop.close
|
||||
ls.loop.close = lambda: None
|
||||
ls.start_io(os.fdopen(fdr, 'rb'), os.fdopen(fdw, 'wb'))
|
||||
ls.start_io(os.fdopen(fdr, "rb"), os.fdopen(fdw, "wb"))
|
||||
ls.loop.close = close
|
||||
|
||||
server = CMakeLanguageServer(asyncio.new_event_loop())
|
||||
|
||||
@@ -4,109 +4,115 @@ from cmake_language_server.api import API
|
||||
|
||||
|
||||
def test_query_with_cache(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
assert api.query()
|
||||
|
||||
query = cmake_build / '.cmake' / 'api' / 'v1' / 'query'
|
||||
query = cmake_build / ".cmake" / "api" / "v1" / "query"
|
||||
assert query.exists()
|
||||
|
||||
reply = cmake_build / '.cmake' / 'api' / 'v1' / 'reply'
|
||||
reply = cmake_build / ".cmake" / "api" / "v1" / "reply"
|
||||
assert reply.exists()
|
||||
|
||||
|
||||
def test_query_without_cache(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
(cmake_build / 'CMakeCache.txt').unlink()
|
||||
api = API("cmake", cmake_build)
|
||||
(cmake_build / "CMakeCache.txt").unlink()
|
||||
|
||||
assert not api.query()
|
||||
|
||||
|
||||
def test_read_variable(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
assert api.query()
|
||||
assert api.read_reply()
|
||||
|
||||
assert api.get_variable_doc('testproject_BINARY_DIR')
|
||||
assert api.get_variable_doc("testproject_BINARY_DIR")
|
||||
|
||||
|
||||
def test_read_cmake_files(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
assert api.query()
|
||||
api.read_reply()
|
||||
|
||||
import platform
|
||||
|
||||
system = platform.system()
|
||||
if system == 'Linux':
|
||||
assert 'GNU' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
||||
elif system == 'Windows':
|
||||
assert 'MSVC' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
||||
elif system == 'Darwin':
|
||||
assert 'Clang' in api.get_variable_doc('CMAKE_CXX_COMPILER_ID')
|
||||
if system == "Linux":
|
||||
assert "GNU" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||
elif system == "Windows":
|
||||
assert "MSVC" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||
elif system == "Darwin":
|
||||
assert "Clang" in api.get_variable_doc("CMAKE_CXX_COMPILER_ID")
|
||||
else:
|
||||
raise RuntimeError('Unexpected system')
|
||||
raise RuntimeError("Unexpected system")
|
||||
|
||||
|
||||
def test_parse_commands(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
p = subprocess.run(['cmake', '--help-command-list'],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
commands = p.stdout.strip().split('\n')
|
||||
p = subprocess.run(
|
||||
["cmake", "--help-command-list"],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
commands = p.stdout.strip().split("\n")
|
||||
|
||||
for command in commands:
|
||||
assert api.get_command_doc(command) is not None, f'{command} not found'
|
||||
assert api.get_command_doc(command) is not None, f"{command} not found"
|
||||
|
||||
assert 'break()' in api.get_command_doc('break')
|
||||
assert api.get_command_doc('not_existing_command') is None
|
||||
assert "break()" in api.get_command_doc("break")
|
||||
assert api.get_command_doc("not_existing_command") is None
|
||||
|
||||
|
||||
def test_parse_variables(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
p = subprocess.run(['cmake', '--help-variable-list'],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
variables = p.stdout.strip().split('\n')
|
||||
p = subprocess.run(
|
||||
["cmake", "--help-variable-list"],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
variables = p.stdout.strip().split("\n")
|
||||
|
||||
for variable in variables:
|
||||
if '<' in variable:
|
||||
if "<" in variable:
|
||||
continue
|
||||
assert api.get_variable_doc(
|
||||
variable) is not None, f'{variable} not found'
|
||||
assert api.get_variable_doc(variable) is not None, f"{variable} not found"
|
||||
|
||||
assert api.get_variable_doc('BUILD_SHARED_LIBS') is not None
|
||||
assert api.get_variable_doc('not_existing_variable') is None
|
||||
assert api.get_variable_doc("BUILD_SHARED_LIBS") is not None
|
||||
assert api.get_variable_doc("not_existing_variable") is None
|
||||
|
||||
|
||||
def test_parse_modules(cmake_build):
|
||||
api = API('cmake', cmake_build)
|
||||
api = API("cmake", cmake_build)
|
||||
api.parse_doc()
|
||||
|
||||
p = subprocess.run(['cmake', '--help-module-list'],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
modules = p.stdout.strip().split('\n')
|
||||
p = subprocess.run(
|
||||
["cmake", "--help-module-list"],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
modules = p.stdout.strip().split("\n")
|
||||
|
||||
for module in modules:
|
||||
if module.startswith('Find'):
|
||||
assert api.get_module_doc(module[4:],
|
||||
True) is not None, f'{module} not found'
|
||||
if module.startswith("Find"):
|
||||
assert (
|
||||
api.get_module_doc(module[4:], True) is not None
|
||||
), f"{module} not found"
|
||||
else:
|
||||
assert api.get_module_doc(module,
|
||||
False) is not None, f'{module} not found'
|
||||
assert api.get_module_doc(module, False) is not None, f"{module} not found"
|
||||
|
||||
assert api.get_module_doc('GoogleTest', False) is not None
|
||||
assert api.get_module_doc('GoogleTest', True) is None
|
||||
assert api.search_module('GoogleTest', False) == ['GoogleTest']
|
||||
assert api.search_module('GoogleTest', True) == []
|
||||
assert api.get_module_doc('Boost', False) is None
|
||||
assert api.get_module_doc('Boost', True) is not None
|
||||
assert api.search_module('Boost', False) == []
|
||||
assert api.search_module('Boost', True) == ['Boost']
|
||||
assert api.get_module_doc("GoogleTest", False) is not None
|
||||
assert api.get_module_doc("GoogleTest", True) is None
|
||||
assert api.search_module("GoogleTest", False) == ["GoogleTest"]
|
||||
assert api.search_module("GoogleTest", True) == []
|
||||
assert api.get_module_doc("Boost", False) is None
|
||||
assert api.get_module_doc("Boost", True) is not None
|
||||
assert api.search_module("Boost", False) == []
|
||||
assert api.search_module("Boost", True) == ["Boost"]
|
||||
|
||||
@@ -15,50 +15,57 @@ def make_formatter_test(liststr: str, expect: str):
|
||||
return test
|
||||
|
||||
|
||||
test_command = make_formatter_test('a()', 'a()\n')
|
||||
test_command_tolower = make_formatter_test('A()', 'a()\n')
|
||||
test_remove_space = make_formatter_test('''
|
||||
test_command = make_formatter_test("a()", "a()\n")
|
||||
test_command_tolower = make_formatter_test("A()", "a()\n")
|
||||
test_remove_space = make_formatter_test(
|
||||
"""
|
||||
#a
|
||||
b ( c ) # d
|
||||
''', '''\
|
||||
""",
|
||||
"""\
|
||||
#a
|
||||
b(c) # d
|
||||
''')
|
||||
""",
|
||||
)
|
||||
test_indent_if = make_formatter_test(
|
||||
'''
|
||||
"""
|
||||
if()
|
||||
a() # a
|
||||
else()
|
||||
# b
|
||||
b()
|
||||
endif()
|
||||
''', '''\
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
a() # a
|
||||
else()
|
||||
# b
|
||||
b()
|
||||
endif()
|
||||
''')
|
||||
""",
|
||||
)
|
||||
test_indent_if_nested = make_formatter_test(
|
||||
'''
|
||||
"""
|
||||
if()
|
||||
if()
|
||||
a()
|
||||
b()
|
||||
endif()
|
||||
endif()
|
||||
''', '''\
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
if()
|
||||
a()
|
||||
b()
|
||||
endif()
|
||||
endif()
|
||||
''')
|
||||
test_argument = make_formatter_test('a( b c d)', 'a(b c d)\n')
|
||||
""",
|
||||
)
|
||||
test_argument = make_formatter_test("a( b c d)", "a(b c d)\n")
|
||||
test_argument_multiline = make_formatter_test(
|
||||
'''
|
||||
"""
|
||||
if()
|
||||
a(b c
|
||||
d # e
|
||||
@@ -66,7 +73,8 @@ f
|
||||
# g
|
||||
) # h
|
||||
endif()
|
||||
''', '''\
|
||||
""",
|
||||
"""\
|
||||
if()
|
||||
a(
|
||||
b c
|
||||
@@ -75,7 +83,8 @@ if()
|
||||
# g
|
||||
) # h
|
||||
endif()
|
||||
''')
|
||||
""",
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
@@ -87,70 +96,70 @@ def mock_stdin(buf: str):
|
||||
|
||||
|
||||
def test_main_stdin(capsys):
|
||||
with mock_stdin(' a()'):
|
||||
with mock_stdin(" a()"):
|
||||
main([])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == 'a()\n'
|
||||
assert captured.err == ''
|
||||
assert captured.out == "a()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_stdin_diff(capsys):
|
||||
with mock_stdin(' a()'):
|
||||
main(['-d'])
|
||||
with mock_stdin(" a()"):
|
||||
main(["-d"])
|
||||
captured = capsys.readouterr()
|
||||
assert '- a()' in captured.out
|
||||
assert '+a()' in captured.out
|
||||
assert captured.err == ''
|
||||
assert "- a()" in captured.out
|
||||
assert "+a()" in captured.out
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_file_1(capsys, tmp_path):
|
||||
testfile1 = tmp_path / 'list1.cmake'
|
||||
with testfile1.open('w') as fp:
|
||||
fp.write(' a()')
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
|
||||
main([str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == 'a()\n'
|
||||
assert captured.err == ''
|
||||
assert captured.out == "a()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_file_2(capsys, tmp_path):
|
||||
testfile1 = tmp_path / 'list1.cmake'
|
||||
with testfile1.open('w') as fp:
|
||||
fp.write(' a()')
|
||||
testfile2 = tmp_path / 'list2.cmake'
|
||||
with testfile2.open('w') as fp:
|
||||
fp.write(' b()')
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
testfile2 = tmp_path / "list2.cmake"
|
||||
with testfile2.open("w") as fp:
|
||||
fp.write(" b()")
|
||||
|
||||
main([str(testfile1), str(testfile2)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == 'a()\nb()\n'
|
||||
assert captured.err == ''
|
||||
assert captured.out == "a()\nb()\n"
|
||||
assert captured.err == ""
|
||||
|
||||
|
||||
def test_main_inplace(capsys, tmp_path):
|
||||
testfile1 = tmp_path / 'list1.cmake'
|
||||
with testfile1.open('w') as fp:
|
||||
fp.write(' a()')
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
|
||||
main(['-i', str(testfile1)])
|
||||
main(["-i", str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == ''
|
||||
assert captured.err == ''
|
||||
assert captured.out == ""
|
||||
assert captured.err == ""
|
||||
|
||||
with testfile1.open() as fp:
|
||||
content = fp.read()
|
||||
assert content == 'a()\n'
|
||||
assert content == "a()\n"
|
||||
|
||||
|
||||
def test_main_diff(capsys, tmp_path):
|
||||
testfile1 = tmp_path / 'list1.cmake'
|
||||
with testfile1.open('w') as fp:
|
||||
fp.write(' a()')
|
||||
testfile1 = tmp_path / "list1.cmake"
|
||||
with testfile1.open("w") as fp:
|
||||
fp.write(" a()")
|
||||
|
||||
main(['-d', str(testfile1)])
|
||||
main(["-d", str(testfile1)])
|
||||
captured = capsys.readouterr()
|
||||
assert str(testfile1) in captured.out
|
||||
assert '- a()' in captured.out
|
||||
assert '+a()' in captured.out
|
||||
assert captured.err == ''
|
||||
assert "- a()" in captured.out
|
||||
assert "+a()" in captured.out
|
||||
assert captured.err == ""
|
||||
|
||||
@@ -3,9 +3,9 @@ from typing import List
|
||||
from cmake_language_server.parser import ListParser, TokenType
|
||||
|
||||
|
||||
def make_parser_test(liststr: str,
|
||||
expect_token: List[TokenType],
|
||||
expect_remain: str = ''):
|
||||
def make_parser_test(
|
||||
liststr: str, expect_token: List[TokenType], expect_remain: str = ""
|
||||
):
|
||||
def test():
|
||||
actual_token, actual_remain = ListParser().parse(liststr)
|
||||
assert actual_token == expect_token
|
||||
@@ -14,51 +14,70 @@ def make_parser_test(liststr: str,
|
||||
return test
|
||||
|
||||
|
||||
test_command_no_args = make_parser_test('a()', [('a', [])])
|
||||
test_command_space = make_parser_test(' a ()', [' ', ('a', [])])
|
||||
test_command_arg = make_parser_test('a(b)', [('a', ['b'])])
|
||||
test_command_arg_space = make_parser_test('a ( b )', [('a', ['b'])])
|
||||
test_command_arg_escape = make_parser_test(r'a(\n\")', [('a', [r'\n\"'])])
|
||||
test_command_arg_paren = make_parser_test('a((b))', [('a', ['(', 'b', ')'])])
|
||||
test_command_no_args = make_parser_test("a()", [("a", [])])
|
||||
test_command_space = make_parser_test(" a ()", [" ", ("a", [])])
|
||||
test_command_arg = make_parser_test("a(b)", [("a", ["b"])])
|
||||
test_command_arg_space = make_parser_test("a ( b )", [("a", ["b"])])
|
||||
test_command_arg_escape = make_parser_test(r"a(\n\")", [("a", [r"\n\""])])
|
||||
test_command_arg_paren = make_parser_test("a((b))", [("a", ["(", "b", ")"])])
|
||||
test_command_arg_paren_paren = make_parser_test(
|
||||
'a(((b)))', [('a', ['(', '(', 'b', ')', ')'])])
|
||||
test_command_arg_quote = make_parser_test(r'a("b\"")', [('a', [r'"b\""'])])
|
||||
test_command_arg_quote_cont = make_parser_test('a("\\\n")',
|
||||
[('a', ['"\\\n"'])])
|
||||
test_command_arg_quo_multiline = make_parser_test('''a("b
|
||||
"a(((b)))", [("a", ["(", "(", "b", ")", ")"])]
|
||||
)
|
||||
test_command_arg_quote = make_parser_test(r'a("b\"")', [("a", [r'"b\""'])])
|
||||
test_command_arg_quote_cont = make_parser_test('a("\\\n")', [("a", ['"\\\n"'])])
|
||||
test_command_arg_quo_multiline = make_parser_test(
|
||||
"""a("b
|
||||
c
|
||||
")''', [('a', ['"b\nc\n"'])])
|
||||
test_command_arg_bracket_0 = make_parser_test('a([[b]])', [('a', ['[[b]]'])])
|
||||
test_command_arg_bracket_1 = make_parser_test('a([=[b]=])',
|
||||
[('a', ['[=[b]=]'])])
|
||||
test_command_arg_space = make_parser_test('a ( b )', [('a', [' ', 'b', ' '])])
|
||||
test_command_arg_multi = make_parser_test('a(b c)', [('a', ['b', ' ', 'c'])])
|
||||
test_command_multielement = make_parser_test('''a(
|
||||
")""",
|
||||
[("a", ['"b\nc\n"'])],
|
||||
)
|
||||
test_command_arg_bracket_0 = make_parser_test("a([[b]])", [("a", ["[[b]]"])])
|
||||
test_command_arg_bracket_1 = make_parser_test("a([=[b]=])", [("a", ["[=[b]=]"])])
|
||||
test_command_arg_space = make_parser_test("a ( b )", [("a", [" ", "b", " "])])
|
||||
test_command_arg_multi = make_parser_test("a(b c)", [("a", ["b", " ", "c"])])
|
||||
test_command_multielement = make_parser_test(
|
||||
"""a(
|
||||
b
|
||||
c # c
|
||||
)''', [('a', ['\n', ' ', 'b', '\n', ' ', 'c', ' ', '# c', '\n'])])
|
||||
test_line_comment = make_parser_test('a() # b # c',
|
||||
[('a', []), ' ', '# b # c'])
|
||||
test_bracket_comment = make_parser_test('#[[a]]#[[b]]', ['#[[a]]', '#[[b]]'])
|
||||
test_bracket_comment_nested = make_parser_test('#[=[[[a]]]=]',
|
||||
['#[=[[[a]]]=]'])
|
||||
test_bracket_comment_multiline = make_parser_test('#[[\na\nb\nc\n]]',
|
||||
['#[[\na\nb\nc\n]]'])
|
||||
test_if_block = make_parser_test('''if()
|
||||
)""",
|
||||
[("a", ["\n", " ", "b", "\n", " ", "c", " ", "# c", "\n"])],
|
||||
)
|
||||
test_line_comment = make_parser_test("a() # b # c", [("a", []), " ", "# b # c"])
|
||||
test_bracket_comment = make_parser_test("#[[a]]#[[b]]", ["#[[a]]", "#[[b]]"])
|
||||
test_bracket_comment_nested = make_parser_test("#[=[[[a]]]=]", ["#[=[[[a]]]=]"])
|
||||
test_bracket_comment_multiline = make_parser_test(
|
||||
"#[[\na\nb\nc\n]]", ["#[[\na\nb\nc\n]]"]
|
||||
)
|
||||
test_if_block = make_parser_test(
|
||||
"""if()
|
||||
a()
|
||||
else()
|
||||
b()
|
||||
endif()''', [('if', []), '\n', ' ', ('a', []), '\n', ('else', []), '\n', ' ',
|
||||
('b', []), '\n', ('endif', [])])
|
||||
endif()""",
|
||||
[
|
||||
("if", []),
|
||||
"\n",
|
||||
" ",
|
||||
("a", []),
|
||||
"\n",
|
||||
("else", []),
|
||||
"\n",
|
||||
" ",
|
||||
("b", []),
|
||||
"\n",
|
||||
("endif", []),
|
||||
],
|
||||
)
|
||||
test_comment_multi_linecomment = make_parser_test(
|
||||
'''a()# a
|
||||
"""a()# a
|
||||
b() # b
|
||||
c() # c''', [('a', []), '# a', '\n', ('b', []), ' ', '# b', '\n',
|
||||
('c', []), ' ', '# c'])
|
||||
c() # c""",
|
||||
[("a", []), "# a", "\n", ("b", []), " ", "# b", "\n", ("c", []), " ", "# c"],
|
||||
)
|
||||
|
||||
test_incomplete_id = make_parser_test('a', [], 'a')
|
||||
test_incomplete_command = make_parser_test('a(', [], 'a(')
|
||||
test_incomplete_id_after_command = make_parser_test('a()\nb',
|
||||
[('a', []), '\n'], 'b')
|
||||
test_incomplete_id = make_parser_test("a", [], "a")
|
||||
test_incomplete_command = make_parser_test("a(", [], "a(")
|
||||
test_incomplete_id_after_command = make_parser_test("a()\nb", [("a", []), "\n"], "b")
|
||||
test_incomplete_command_after_command = make_parser_test(
|
||||
'a()\nb(c', [('a', []), '\n'], 'b(c')
|
||||
"a()\nb(c", [("a", []), "\n"], "b(c"
|
||||
)
|
||||
|
||||
@@ -2,14 +2,27 @@ from concurrent import futures
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from pygls.features import (COMPLETION, FORMATTING, HOVER, INITIALIZE,
|
||||
TEXT_DOCUMENT_DID_OPEN)
|
||||
from pygls.features import (
|
||||
COMPLETION,
|
||||
FORMATTING,
|
||||
HOVER,
|
||||
INITIALIZE,
|
||||
TEXT_DOCUMENT_DID_OPEN,
|
||||
)
|
||||
from pygls.server import LanguageServer
|
||||
from pygls.types import (CompletionContext, CompletionParams,
|
||||
CompletionTriggerKind, DidOpenTextDocumentParams,
|
||||
DocumentFormattingParams, FormattingOptions,
|
||||
InitializeParams, Position, TextDocumentIdentifier,
|
||||
TextDocumentItem, TextDocumentPositionParams)
|
||||
from pygls.types import (
|
||||
CompletionContext,
|
||||
CompletionParams,
|
||||
CompletionTriggerKind,
|
||||
DidOpenTextDocumentParams,
|
||||
DocumentFormattingParams,
|
||||
FormattingOptions,
|
||||
InitializeParams,
|
||||
Position,
|
||||
TextDocumentIdentifier,
|
||||
TextDocumentItem,
|
||||
TextDocumentPositionParams,
|
||||
)
|
||||
|
||||
CALL_TIMEOUT = 2
|
||||
|
||||
@@ -21,8 +34,9 @@ def _init(client: LanguageServer, root: Path):
|
||||
client.lsp.send_request(
|
||||
INITIALIZE,
|
||||
InitializeParams(
|
||||
process_id=1234, root_uri=root.as_uri(),
|
||||
capabilities=None)).result(timeout=CALL_TIMEOUT)
|
||||
process_id=1234, root_uri=root.as_uri(), capabilities=None
|
||||
),
|
||||
).result(timeout=CALL_TIMEOUT)
|
||||
except futures.TimeoutError:
|
||||
retry -= 1
|
||||
else:
|
||||
@@ -36,23 +50,24 @@ def _open(client: LanguageServer, path: Path, text: Optional[str] = None):
|
||||
|
||||
client.lsp.notify(
|
||||
TEXT_DOCUMENT_DID_OPEN,
|
||||
DidOpenTextDocumentParams(
|
||||
TextDocumentItem(path.as_uri(), 'cmake', 1, text)))
|
||||
DidOpenTextDocumentParams(TextDocumentItem(path.as_uri(), "cmake", 1, text)),
|
||||
)
|
||||
|
||||
|
||||
def _test_completion(client_server, datadir, content: str,
|
||||
context: Optional[CompletionContext]):
|
||||
def _test_completion(
|
||||
client_server, datadir, content: str, context: Optional[CompletionContext]
|
||||
):
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / 'CMakeLists.txt'
|
||||
path = datadir / "CMakeLists.txt"
|
||||
_open(client, path, content)
|
||||
params = CompletionParams(TextDocumentIdentifier(path.as_uri()),
|
||||
Position(0, len(content)), context)
|
||||
params = CompletionParams(
|
||||
TextDocumentIdentifier(path.as_uri()), Position(0, len(content)), context
|
||||
)
|
||||
if context is None:
|
||||
# some clients do not send context
|
||||
del params.context
|
||||
return client.lsp.send_request(COMPLETION,
|
||||
params).result(timeout=CALL_TIMEOUT)
|
||||
return client.lsp.send_request(COMPLETION, params).result(timeout=CALL_TIMEOUT)
|
||||
|
||||
|
||||
def test_initialize(client_server, datadir):
|
||||
@@ -65,72 +80,83 @@ def test_initialize(client_server, datadir):
|
||||
|
||||
def test_completions_invoked(client_server, datadir):
|
||||
response = _test_completion(
|
||||
client_server, datadir, 'projec',
|
||||
CompletionContext(CompletionTriggerKind.Invoked))
|
||||
item = next(filter(lambda x: x.label == 'project', response.items), None)
|
||||
client_server,
|
||||
datadir,
|
||||
"projec",
|
||||
CompletionContext(CompletionTriggerKind.Invoked),
|
||||
)
|
||||
item = next(filter(lambda x: x.label == "project", response.items), None)
|
||||
assert item is not None
|
||||
assert '<PROJECT-NAME>' in item.documentation
|
||||
assert "<PROJECT-NAME>" in item.documentation
|
||||
|
||||
|
||||
def test_completions_nocontext(client_server, datadir):
|
||||
response = _test_completion(client_server, datadir, 'projec', None)
|
||||
item = next(filter(lambda x: x.label == 'project', response.items), None)
|
||||
response = _test_completion(client_server, datadir, "projec", None)
|
||||
item = next(filter(lambda x: x.label == "project", response.items), None)
|
||||
assert item is not None
|
||||
assert '<PROJECT-NAME>' in item.documentation
|
||||
assert "<PROJECT-NAME>" in item.documentation
|
||||
|
||||
|
||||
def test_completions_triggercharacter_variable(client_server, datadir):
|
||||
response = _test_completion(
|
||||
client_server, datadir, '${',
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '{'))
|
||||
assert 'PROJECT_VERSION' in [x.label for x in response.items]
|
||||
client_server,
|
||||
datadir,
|
||||
"${",
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, "{"),
|
||||
)
|
||||
assert "PROJECT_VERSION" in [x.label for x in response.items]
|
||||
|
||||
response_nocontext = _test_completion(client_server, datadir, '${', None)
|
||||
response_nocontext = _test_completion(client_server, datadir, "${", None)
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_completions_triggercharacter_module(client_server, datadir):
|
||||
response = _test_completion(
|
||||
client_server, datadir, 'include(',
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
|
||||
assert 'GoogleTest' in [x.label for x in response.items]
|
||||
client_server,
|
||||
datadir,
|
||||
"include(",
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, "("),
|
||||
)
|
||||
assert "GoogleTest" in [x.label for x in response.items]
|
||||
|
||||
response_nocontext = _test_completion(client_server, datadir, 'include(',
|
||||
None)
|
||||
response_nocontext = _test_completion(client_server, datadir, "include(", None)
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_completions_triggercharacter_package(client_server, datadir):
|
||||
response = _test_completion(
|
||||
client_server, datadir, 'find_package(',
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
|
||||
assert 'Boost' in [x.label for x in response.items]
|
||||
client_server,
|
||||
datadir,
|
||||
"find_package(",
|
||||
CompletionContext(CompletionTriggerKind.TriggerCharacter, "("),
|
||||
)
|
||||
assert "Boost" in [x.label for x in response.items]
|
||||
|
||||
response_nocontext = _test_completion(client_server, datadir,
|
||||
'find_package(', None)
|
||||
response_nocontext = _test_completion(client_server, datadir, "find_package(", None)
|
||||
assert response == response_nocontext
|
||||
|
||||
|
||||
def test_formatting(client_server, datadir):
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / 'CMakeLists.txt'
|
||||
_open(client, path, 'a ( b c ) ')
|
||||
path = datadir / "CMakeLists.txt"
|
||||
_open(client, path, "a ( b c ) ")
|
||||
response = client.lsp.send_request(
|
||||
FORMATTING,
|
||||
DocumentFormattingParams(TextDocumentIdentifier(path.as_uri()),
|
||||
FormattingOptions(
|
||||
2, True))).result(timeout=CALL_TIMEOUT)
|
||||
assert response[0].newText == 'a(b c)\n'
|
||||
DocumentFormattingParams(
|
||||
TextDocumentIdentifier(path.as_uri()), FormattingOptions(2, True)
|
||||
),
|
||||
).result(timeout=CALL_TIMEOUT)
|
||||
assert response[0].newText == "a(b c)\n"
|
||||
|
||||
|
||||
def test_hover(client_server, datadir):
|
||||
client, server = client_server
|
||||
_init(client, datadir)
|
||||
path = datadir / 'CMakeLists.txt'
|
||||
_open(client, path, 'project()')
|
||||
path = datadir / "CMakeLists.txt"
|
||||
_open(client, path, "project()")
|
||||
response = client.lsp.send_request(
|
||||
HOVER,
|
||||
TextDocumentPositionParams(TextDocumentIdentifier(path.as_uri()),
|
||||
Position())).result(timeout=CALL_TIMEOUT)
|
||||
assert '<PROJECT-NAME>' in response.contents.value
|
||||
TextDocumentPositionParams(TextDocumentIdentifier(path.as_uri()), Position()),
|
||||
).result(timeout=CALL_TIMEOUT)
|
||||
assert "<PROJECT-NAME>" in response.contents.value
|
||||
|
||||
Reference in New Issue
Block a user