Skip to content

Commit

Permalink
Update test suite to use LanguageClient
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Mar 17, 2023
1 parent c15a1ed commit 30e7a49
Show file tree
Hide file tree
Showing 31 changed files with 463 additions and 645 deletions.
70 changes: 27 additions & 43 deletions tests/ls_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@
import threading

import pytest
from lsprotocol.types import (
EXIT,
INITIALIZE,
SHUTDOWN,
ClientCapabilities,
InitializeParams,
)
from pygls.server import LanguageServer
from lsprotocol.types import EXIT
from lsprotocol.types import INITIALIZE
from lsprotocol.types import SHUTDOWN
from lsprotocol.types import ClientCapabilities
from lsprotocol.types import InitializeParams

from pygls.lsp.client import LanguageClient
from pygls.server import LanguageServer

from . import CMD_ASYNC, CMD_SYNC, CMD_THREAD
from . import CMD_ASYNC
from . import CMD_SYNC
from . import CMD_THREAD
from ._init_server_stall_fix_hack import retry_stalled_init_fix_hack


CALL_TIMEOUT = 3


def setup_ls_features(server):

# Commands
Expand Down Expand Up @@ -64,9 +65,7 @@ def close(self):

def write(self, data):
object_hook = self.dest.lsp._deserialize_message
self.dest.lsp._procedure_handler(
json.loads(data, object_hook=object_hook)
)
self.dest.lsp._procedure_handler(json.loads(data, object_hook=object_hook))


class PyodideClientServer:
Expand All @@ -75,8 +74,8 @@ class PyodideClientServer:

def __init__(self, LS=LanguageServer):

self.server = LS('pygls-server', 'v1')
self.client = LS('pygls-client', 'v1')
self.server = LS("pygls-server", "v1")
self.client = LS("pygls-client", "v1")

self.server.lsp.connection_made(PyodideTestTransportAdapter(self.client))
self.server.lsp._send_only_body = True
Expand All @@ -92,20 +91,14 @@ def stop(self):

@classmethod
def decorate(cls):
return pytest.mark.parametrize(
'client_server',
[cls],
indirect=True
)
return pytest.mark.parametrize("client_server", [cls], indirect=True)

def initialize(self):
response = self.client.lsp.send_request(
INITIALIZE,
InitializeParams(
process_id=12345,
root_uri="file://",
capabilities=ClientCapabilities()
)
process_id=12345, root_uri="file://", capabilities=ClientCapabilities()
),
).result(timeout=CALL_TIMEOUT)

assert response.capabilities is not None
Expand All @@ -123,30 +116,26 @@ def __init__(self, LS=LanguageServer):
scr, scw = os.pipe()

# Setup Server
self.server = LS('server', 'v1')
self.server = LS("server", "v1")
self.server_thread = threading.Thread(
name='Server Thread',
name="Server Thread",
target=self.server.start_io,
args=(os.fdopen(csr, "rb"), os.fdopen(scw, "wb")),
)
self.server_thread.daemon = True

# Setup client
self.client = LS('client', 'v1', asyncio.new_event_loop())
self.client = LanguageClient("client", "v1", loop=asyncio.new_event_loop())
self.client_thread = threading.Thread(
name='Client Thread',
name="Client Thread",
target=self.client.start_io,
args=(os.fdopen(scr, "rb"), os.fdopen(csw, "wb")),
)
self.client_thread.daemon = True

@classmethod
def decorate(cls):
return pytest.mark.parametrize(
'client_server',
[cls],
indirect=True
)
return pytest.mark.parametrize("client_server", [cls], indirect=True)

def start(self):
self.server_thread.start()
Expand All @@ -155,11 +144,9 @@ def start(self):
self.initialize()

def stop(self):
shutdown_response = self.client.lsp.send_request(
SHUTDOWN
).result()
shutdown_response = self.client.shutdown(None).result()
assert shutdown_response is None
self.client.lsp.notify(EXIT)
self.client.exit(None)
self.server_thread.join()
self.client._stop_event.set()
try:
Expand All @@ -171,13 +158,10 @@ def stop(self):
@retry_stalled_init_fix_hack()
def initialize(self):

timeout = None if 'DISABLE_TIMEOUT' in os.environ else 1
response = self.client.lsp.send_request(
INITIALIZE,
timeout = None if "DISABLE_TIMEOUT" in os.environ else 1
response = self.client.initialize(
InitializeParams(
process_id=12345,
root_uri="file://",
capabilities=ClientCapabilities()
process_id=12345, root_uri="file://", capabilities=ClientCapabilities()
),
).result(timeout=timeout)
assert response.capabilities is not None
Expand Down
37 changes: 14 additions & 23 deletions tests/lsp/semantic_tokens/test_delta_missing_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,16 @@
# See the License for the specific language governing permissions and #
# limitations under the License. #
############################################################################
from typing import Optional, Union
from typing import Optional
from typing import Union

from lsprotocol.types import (
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA,
)
from lsprotocol.types import (
SemanticTokens,
SemanticTokensDeltaParams,
SemanticTokensLegend,
SemanticTokensPartialResult,
SemanticTokensOptionsFullType1,
TextDocumentIdentifier,
)
from lsprotocol.types import TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA
from lsprotocol.types import SemanticTokens
from lsprotocol.types import SemanticTokensDeltaParams
from lsprotocol.types import SemanticTokensLegend
from lsprotocol.types import SemanticTokensOptionsFullType1
from lsprotocol.types import SemanticTokensPartialResult
from lsprotocol.types import TextDocumentIdentifier

from ...conftest import ClientServer

Expand All @@ -38,8 +35,7 @@ def __init__(self):
@self.server.feature(
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL_DELTA,
SemanticTokensLegend(
token_types=["keyword", "operator"],
token_modifiers=["readonly"]
token_types=["keyword", "operator"], token_modifiers=["readonly"]
),
)
def f(
Expand All @@ -60,19 +56,15 @@ def test_capabilities(client_server):
"keyword",
"operator",
]
assert provider.legend.token_modifiers == [
"readonly"
]
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,
response = client.text_document_semantic_tokens_full_delta(
SemanticTokensDeltaParams(
text_document=TextDocumentIdentifier(
uri="file://return.tokens"),
text_document=TextDocumentIdentifier(uri="file://return.tokens"),
previous_result_id="id",
),
).result()
Expand All @@ -85,8 +77,7 @@ def test_semantic_tokens_full_delta_return_tokens(client_server):
@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,
response = client.text_document_semantic_tokens_full_delta(
SemanticTokensDeltaParams(
text_document=TextDocumentIdentifier(uri="file://return.none"),
previous_result_id="id",
Expand Down
46 changes: 17 additions & 29 deletions tests/lsp/semantic_tokens/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,22 @@
# 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 typing import Optional
from typing import Union

from lsprotocol.types import TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE
from lsprotocol.types import Position
from lsprotocol.types import Range
from lsprotocol.types import SemanticTokens
from lsprotocol.types import SemanticTokensLegend
from lsprotocol.types import SemanticTokensPartialResult
from lsprotocol.types import SemanticTokensRangeParams
from lsprotocol.types import TextDocumentIdentifier

from ...conftest import ClientServer

SemanticTokenReturnType = Optional[
Union[
SemanticTokensPartialResult,
Optional[SemanticTokens]
]
Union[SemanticTokensPartialResult, Optional[SemanticTokens]]
]


Expand All @@ -46,8 +40,7 @@ def __init__(self):
@self.server.feature(
TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE,
SemanticTokensLegend(
token_types=["keyword", "operator"],
token_modifiers=["readonly"]
token_types=["keyword", "operator"], token_modifiers=["readonly"]
),
)
def f(
Expand All @@ -68,19 +61,15 @@ def test_capabilities(client_server):
"keyword",
"operator",
]
assert provider.legend.token_modifiers == [
"readonly"
]
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,
response = client.text_document_semantic_tokens_range(
SemanticTokensRangeParams(
text_document=TextDocumentIdentifier(
uri="file://return.tokens"),
text_document=TextDocumentIdentifier(uri="file://return.tokens"),
range=Range(
start=Position(line=0, character=0),
end=Position(line=10, character=80),
Expand All @@ -96,8 +85,7 @@ def test_semantic_tokens_range_return_tokens(client_server):
@ConfiguredLS.decorate()
def test_semantic_tokens_range_return_none(client_server):
client, _ = client_server
response = client.lsp.send_request(
TEXT_DOCUMENT_SEMANTIC_TOKENS_RANGE,
response = client.text_document_semantic_tokens_range(
SemanticTokensRangeParams(
text_document=TextDocumentIdentifier(uri="file://return.none"),
range=Range(
Expand Down
42 changes: 15 additions & 27 deletions tests/lsp/semantic_tokens/test_semantic_tokens_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,20 @@
# 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 typing import Optional
from typing import Union

from lsprotocol.types import TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL
from lsprotocol.types import SemanticTokens
from lsprotocol.types import SemanticTokensLegend
from lsprotocol.types import SemanticTokensParams
from lsprotocol.types import SemanticTokensPartialResult
from lsprotocol.types import TextDocumentIdentifier

from ...conftest import ClientServer

SemanticTokenReturnType = Optional[
Union[
SemanticTokensPartialResult,
Optional[SemanticTokens]
]
Union[SemanticTokensPartialResult, Optional[SemanticTokens]]
]


Expand All @@ -44,8 +38,7 @@ def __init__(self):
@self.server.feature(
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
SemanticTokensLegend(
token_types=["keyword", "operator"],
token_modifiers=["readonly"]
token_types=["keyword", "operator"], token_modifiers=["readonly"]
),
)
def f(
Expand All @@ -66,19 +59,15 @@ def test_capabilities(client_server):
"keyword",
"operator",
]
assert provider.legend.token_modifiers == [
"readonly"
]
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,
response = client.text_document_semantic_tokens_full(
SemanticTokensParams(
text_document=TextDocumentIdentifier(
uri="file://return.tokens")
text_document=TextDocumentIdentifier(uri="file://return.tokens")
),
).result()

Expand All @@ -90,8 +79,7 @@ def test_semantic_tokens_full_return_tokens(client_server):
@ConfiguredLS.decorate()
def test_semantic_tokens_full_return_none(client_server):
client, _ = client_server
response = client.lsp.send_request(
TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
response = client.text_document_semantic_tokens_full(
SemanticTokensParams(
text_document=TextDocumentIdentifier(uri="file://return.none")
),
Expand Down
Loading

0 comments on commit 30e7a49

Please sign in to comment.