diff --git a/tests/e2e/test_semantic_tokens.py b/tests/e2e/test_semantic_tokens.py new file mode 100644 index 00000000..2058d39a --- /dev/null +++ b/tests/e2e/test_semantic_tokens.py @@ -0,0 +1,121 @@ +############################################################################ +# Copyright(c) Open Law Library. All rights reserved. # +# See ThirdPartyNotices.txt in the project root for additional notices. # +# # +# 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 annotations + +import typing + +import pytest +import pytest_asyncio +from lsprotocol import types + +if typing.TYPE_CHECKING: + from typing import List, Tuple + + from pygls.lsp.client import BaseLanguageClient + + +@pytest_asyncio.fixture(scope="module") +async def semantic_tokens(get_client_for): + async for result in get_client_for("semantic_tokens.py"): + yield result + + +@pytest.mark.parametrize( + "text,expected", + [ + # Just a handful of cases to check we've got the basics right + ("fn", [0, 0, 2, 0, 0]), + ("type", [0, 0, 4, 0, 0]), + ("Rectangle", [0, 0, 9, 5, 0]), + ( + "type Rectangle", + [ + # fmt: off + 0, 0, 4, 0, 0, + 0, 5, 9, 5, 8, + # fmt: on + ], + ), + ( + "fn area", + [ + # fmt: off + 0, 0, 2, 0, 0, + 0, 3, 4, 2, 8, + # fmt: on + ], + ), + ( + "fn\n area", + [ + # fmt: off + 0, 0, 2, 0, 0, + 1, 1, 4, 2, 8, + # fmt: on + ], + ), + ], +) +@pytest.mark.asyncio(scope="module") +async def test_semantic_tokens_full( + semantic_tokens: Tuple[BaseLanguageClient, types.InitializeResult], + uri_for, + path_for, + text: str, + expected: List[int], +): + """Ensure that the example semantic tokens server is working as expected.""" + client, initialize_result = semantic_tokens + + semantic_tokens_options = initialize_result.capabilities.semantic_tokens_provider + assert semantic_tokens_options.full is True + + legend = semantic_tokens_options.legend + assert legend.token_types == [ + "keyword", + "variable", + "function", + "operator", + "parameter", + "type", + ] + assert legend.token_modifiers == [ + "deprecated", + "readonly", + "defaultLibrary", + "definition", + ] + + test_uri = uri_for("code.txt") + + client.text_document_did_open( + types.DidOpenTextDocumentParams( + types.TextDocumentItem( + uri=test_uri, + language_id="plaintext", + version=0, + text=text, + ) + ) + ) + + response = await client.text_document_semantic_tokens_full_async( + types.SemanticTokensParams( + text_document=types.TextDocumentIdentifier(uri=test_uri), + ) + ) + assert response.data == expected diff --git a/tests/lsp/semantic_tokens/__init__.py b/tests/lsp/semantic_tokens/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/lsp/semantic_tokens/test_delta_missing_legend.py b/tests/lsp/semantic_tokens/test_delta_missing_legend.py deleted file mode 100644 index a3069da5..00000000 --- a/tests/lsp/semantic_tokens/test_delta_missing_legend.py +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA, -) -from lsprotocol.types import ( - SemanticTokens, - SemanticTokensDeltaParams, - SemanticTokensLegend, - SemanticTokensPartialResult, - SemanticTokensOptionsFullType1, - TextDocumentIdentifier, -) - -from ...conftest import ClientServer - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA, - SemanticTokensLegend( - token_types=["keyword", "operator"], token_modifiers=["readonly"] - ), - ) - def f( - params: SemanticTokensDeltaParams, - ) -> Union[SemanticTokensPartialResult, Optional[SemanticTokens]]: - if params.text_document.uri == "file://return.tokens": - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - - provider = capabilities.semantic_tokens_provider - assert provider.full == SemanticTokensOptionsFullType1(delta=True) - assert provider.legend.token_types == [ - "keyword", - "operator", - ] - assert provider.legend.token_modifiers == ["readonly"] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_full_delta_return_tokens(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA, - SemanticTokensDeltaParams( - text_document=TextDocumentIdentifier(uri="file://return.tokens"), - previous_result_id="id", - ), - ).result() - - assert response - - assert response.data == [0, 0, 3, 0, 0] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_full_delta_return_none(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA, - SemanticTokensDeltaParams( - text_document=TextDocumentIdentifier(uri="file://return.none"), - previous_result_id="id", - ), - ).result() - - assert response is None diff --git a/tests/lsp/semantic_tokens/test_delta_missing_legend_none.py b/tests/lsp/semantic_tokens/test_delta_missing_legend_none.py deleted file mode 100644 index 6f4fa17d..00000000 --- a/tests/lsp/semantic_tokens/test_delta_missing_legend_none.py +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - SemanticTokens, - SemanticTokensDeltaParams, - SemanticTokensPartialResult, -) -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA, -) - -from ...conftest import ClientServer - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature(TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA) - def f( - params: SemanticTokensDeltaParams, - ) -> Union[SemanticTokensPartialResult, Optional[SemanticTokens]]: - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - - assert capabilities.semantic_tokens_provider is None - assert capabilities.semantic_tokens_provider is None diff --git a/tests/lsp/semantic_tokens/test_full_missing_legend.py b/tests/lsp/semantic_tokens/test_full_missing_legend.py deleted file mode 100644 index e18dbde3..00000000 --- a/tests/lsp/semantic_tokens/test_full_missing_legend.py +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL, -) -from lsprotocol.types import ( - SemanticTokens, - SemanticTokensPartialResult, - SemanticTokensParams, -) - -from ...conftest import ClientServer - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature(TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL) - def f( - params: SemanticTokensParams, - ) -> Union[SemanticTokensPartialResult, Optional[SemanticTokens]]: - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - assert capabilities.semantic_tokens_provider is None diff --git a/tests/lsp/semantic_tokens/test_range.py b/tests/lsp/semantic_tokens/test_range.py deleted file mode 100644 index a65504b6..00000000 --- a/tests/lsp/semantic_tokens/test_range.py +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE, -) -from lsprotocol.types import ( - Position, - Range, - SemanticTokens, - SemanticTokensLegend, - SemanticTokensPartialResult, - SemanticTokensRangeParams, - TextDocumentIdentifier, -) - -from ...conftest import ClientServer - -SemanticTokenReturnType = Optional[ - Union[SemanticTokensPartialResult, Optional[SemanticTokens]] -] - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature( - TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE, - SemanticTokensLegend( - token_types=["keyword", "operator"], token_modifiers=["readonly"] - ), - ) - def f( - params: SemanticTokensRangeParams, - ) -> SemanticTokenReturnType: - if params.text_document.uri == "file://return.tokens": - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - - provider = capabilities.semantic_tokens_provider - assert provider.range - assert provider.legend.token_types == [ - "keyword", - "operator", - ] - assert provider.legend.token_modifiers == ["readonly"] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_range_return_tokens(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE, - SemanticTokensRangeParams( - text_document=TextDocumentIdentifier(uri="file://return.tokens"), - range=Range( - start=Position(line=0, character=0), - end=Position(line=10, character=80), - ), - ), - ).result() - - assert response - - assert response.data == [0, 0, 3, 0, 0] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_range_return_none(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE, - SemanticTokensRangeParams( - text_document=TextDocumentIdentifier(uri="file://return.none"), - range=Range( - start=Position(line=0, character=0), - end=Position(line=10, character=80), - ), - ), - ).result() - - assert response is None diff --git a/tests/lsp/semantic_tokens/test_range_missing_legends.py b/tests/lsp/semantic_tokens/test_range_missing_legends.py deleted file mode 100644 index 69780efa..00000000 --- a/tests/lsp/semantic_tokens/test_range_missing_legends.py +++ /dev/null @@ -1,47 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE, -) -from lsprotocol.types import ( - SemanticTokens, - SemanticTokensParams, - SemanticTokensPartialResult, -) - -from ...conftest import ClientServer - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature(TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE) - def f( - params: SemanticTokensParams, - ) -> Union[SemanticTokensPartialResult, Optional[SemanticTokens]]: - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - - assert capabilities.semantic_tokens_provider is None diff --git a/tests/lsp/semantic_tokens/test_semantic_tokens_full.py b/tests/lsp/semantic_tokens/test_semantic_tokens_full.py deleted file mode 100644 index dba9fa68..00000000 --- a/tests/lsp/semantic_tokens/test_semantic_tokens_full.py +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################ -# Copyright(c) Open Law Library. All rights reserved. # -# See ThirdPartyNotices.txt in the project root for additional notices. # -# # -# 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 typing import Optional, Union - -from lsprotocol.types import ( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL, -) -from lsprotocol.types import ( - SemanticTokens, - SemanticTokensLegend, - SemanticTokensParams, - SemanticTokensPartialResult, - TextDocumentIdentifier, -) - -from ...conftest import ClientServer - -SemanticTokenReturnType = Optional[ - Union[SemanticTokensPartialResult, Optional[SemanticTokens]] -] - - -class ConfiguredLS(ClientServer): - def __init__(self): - super().__init__() - - @self.server.feature( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL, - SemanticTokensLegend( - token_types=["keyword", "operator"], token_modifiers=["readonly"] - ), - ) - def f( - params: SemanticTokensParams, - ) -> SemanticTokenReturnType: - if params.text_document.uri == "file://return.tokens": - return SemanticTokens(data=[0, 0, 3, 0, 0]) - - -@ConfiguredLS.decorate() -def test_capabilities(client_server): - _, server = client_server - capabilities = server.server_capabilities - - provider = capabilities.semantic_tokens_provider - assert provider.full - assert provider.legend.token_types == [ - "keyword", - "operator", - ] - assert provider.legend.token_modifiers == ["readonly"] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_full_return_tokens(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL, - SemanticTokensParams( - text_document=TextDocumentIdentifier(uri="file://return.tokens") - ), - ).result() - - assert response - - assert response.data == [0, 0, 3, 0, 0] - - -@ConfiguredLS.decorate() -def test_semantic_tokens_full_return_none(client_server): - client, _ = client_server - response = client.lsp.send_request( - TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL, - SemanticTokensParams( - text_document=TextDocumentIdentifier(uri="file://return.none") - ), - ).result() - - assert response is None