Skip to content

Commit

Permalink
lsp: Add e2e role completion tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Apr 22, 2024
1 parent bc3bb92 commit 381d659
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 0 deletions.
210 changes: 210 additions & 0 deletions lib/esbonio/tests/e2e/test_e2e_roles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
from __future__ import annotations

import pathlib
import typing

import pytest
from lsprotocol import types
from pytest_lsp import LanguageClient

if typing.TYPE_CHECKING:
from typing import Optional
from typing import Set


EXPECTED = {
"ref",
"doc",
"option",
"func",
"class",
"c:macro",
"c:func",
"py:func",
"py:class",
"std:ref",
"std:doc",
}

UNEXPECTED = {
"macro",
"restructuredtext-unimplemented-role",
}


@pytest.mark.parametrize(
"text, expected, unexpected",
[
("::", None, None),
(":", EXPECTED, UNEXPECTED),
(":r", EXPECTED, UNEXPECTED),
(":c:func", EXPECTED, UNEXPECTED),
(":c:func: ", None, None),
(" ::", None, None),
(" :", EXPECTED, UNEXPECTED),
(" :r", EXPECTED, UNEXPECTED),
(" :c:func", EXPECTED, UNEXPECTED),
(" :c:func: ", None, None),
("(:", EXPECTED, UNEXPECTED),
("(:r", EXPECTED, UNEXPECTED),
("(:c:func", EXPECTED, UNEXPECTED),
],
)
@pytest.mark.asyncio(scope="session")
async def test_rst_role_completions(
client: LanguageClient,
uri_for,
text: str,
expected: Optional[Set[str]],
unexpected: Optional[Set[str]],
):
"""Ensure that the language server can offer role completions in rst documents."""
test_uri = uri_for("workspaces", "demo", "rst", "roles.rst")

uri = str(test_uri)
fpath = pathlib.Path(test_uri)
contents = fpath.read_text()
linum = contents.splitlines().index(".. Add your reference here...")

# Open the file
client.text_document_did_open(
types.DidOpenTextDocumentParams(
text_document=types.TextDocumentItem(
uri=uri,
language_id="restructuredtext",
version=1,
text=contents,
)
)
)

# Write some text
#
# This should replace the '.. Add your note here...' comment in
# 'demo/rst/directives.rst' with the provided text
client.text_document_did_change(
types.DidChangeTextDocumentParams(
text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2),
content_changes=[
types.TextDocumentContentChangeEvent_Type1(
text=text,
range=types.Range(
start=types.Position(line=linum, character=0),
end=types.Position(line=linum + 1, character=0),
),
)
],
)
)

# Make the completion request
results = await client.text_document_completion_async(
types.CompletionParams(
text_document=types.TextDocumentIdentifier(uri=uri),
position=types.Position(line=linum, character=len(text)),
)
)

# Close the document - without saving!
client.text_document_did_close(
types.DidCloseTextDocumentParams(
text_document=types.TextDocumentIdentifier(uri=uri)
)
)

if expected is None:
assert results is None
else:
items = {item.label for item in results.items}
unexpected = unexpected or set()

assert expected == items & expected
assert set() == items & unexpected


@pytest.mark.parametrize(
"text, expected, unexpected",
[
("{", EXPECTED, UNEXPECTED),
("{r", EXPECTED, UNEXPECTED),
("{c:func", EXPECTED, UNEXPECTED),
("{c:func} ", None, None),
(" {", EXPECTED, UNEXPECTED),
(" {r", EXPECTED, UNEXPECTED),
(" {c:func", EXPECTED, UNEXPECTED),
(" {c:func} ", None, None),
("({", EXPECTED, UNEXPECTED),
("({r", EXPECTED, UNEXPECTED),
("({c:func", EXPECTED, UNEXPECTED),
],
)
@pytest.mark.asyncio(scope="session")
async def test_myst_directive_completions(
client: LanguageClient,
uri_for,
text: str,
expected: Optional[Set[str]],
unexpected: Optional[Set[str]],
):
"""Ensure that the language server can offer completions in MyST documents."""
test_uri = uri_for("workspaces", "demo", "myst", "roles.md")

uri = str(test_uri)
fpath = pathlib.Path(test_uri)
contents = fpath.read_text()
linum = contents.splitlines().index("% Add your reference here...")

# Open the file
client.text_document_did_open(
types.DidOpenTextDocumentParams(
text_document=types.TextDocumentItem(
uri=uri,
language_id="markdown",
version=1,
text=contents,
)
)
)

# Write some text
#
# This should replace the '% Add your note here...' comment in
# 'demo/myst/directives.md' with the provided text
client.text_document_did_change(
types.DidChangeTextDocumentParams(
text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2),
content_changes=[
types.TextDocumentContentChangeEvent_Type1(
text=text,
range=types.Range(
start=types.Position(line=linum, character=0),
end=types.Position(line=linum + 1, character=0),
),
)
],
)
)

# Make the completion request
results = await client.text_document_completion_async(
types.CompletionParams(
text_document=types.TextDocumentIdentifier(uri=uri),
position=types.Position(line=linum, character=len(text)),
)
)

# Close the document - without saving!
client.text_document_did_close(
types.DidCloseTextDocumentParams(
text_document=types.TextDocumentIdentifier(uri=uri)
)
)

if expected is None:
assert results is None
else:
items = {item.label for item in results.items}
unexpected = unexpected or set()

assert expected == items & expected
assert set() == items & unexpected
12 changes: 12 additions & 0 deletions lib/esbonio/tests/workspaces/demo/myst/roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Roles

The language server has extensive support for roles.

(myst-roles-completion)=
## Completion

The most obvious feature is the completion suggestions, try inserting a `{ref}` role on the next line that links to the ``Completion`` heading above.

% Add your reference here...

Notice how VSCode automatically presented you with a list of all the directives you can use in this Sphinx project?
15 changes: 15 additions & 0 deletions lib/esbonio/tests/workspaces/demo/rst/roles.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Roles
=====

The language server has extensive support for roles.

.. _rst-roles-completion:

Completion
----------

The most obvious feature is the completion suggestions, try inserting a ``:ref:`` role on the next line that links to the ``Completion`` heading above.

.. Add your reference here...
Notice how VSCode automatically presented you with a list of all the roles you can use in this Sphinx project?

0 comments on commit 381d659

Please sign in to comment.