test(completion_context): update test expectations and reflow formatting

Adjust tests to match current completion item labels and clean up formatting:
- Expect "nocomplain" (no leading dash) for the unset option case instead of {"-nocomplain", "--"}.
- Reflow several multi-line source literals into single-line/f-string forms.
- Normalize various assertions and generator expressions onto single lines.
- Reformat TextDocumentItem construction for readability.

These changes are limited to test code and reflect the updated shape/labels of completion items and stylistic cleanup; no production logic is modified.
This commit is contained in:
2026-09-24 23:05:49 +02:00
parent bd9c73452e
commit 0a8e8a7368
@@ -47,20 +47,9 @@ def _document(path: Path, source: str) -> TextDocument:
) )
def _completion_server( def _completion_server(tmp_path: Path, monkeypatch) -> tuple[TclLanguageServer, TextDocument, str]:
tmp_path: Path, monkeypatch
) -> tuple[TclLanguageServer, TextDocument, str]:
declared_builtin = standard_items.nx_variables[0].label declared_builtin = standard_items.nx_variables[0].label
current_source = ( current_source = f"set globalValue 1\nproc localProc {{}} {{ return }}\nproc caller {{argument}} {{\n global {declared_builtin}\n set localValue 2\n puts $local\n localP\n}}\n"
"set globalValue 1\n"
"proc localProc {} { return }\n"
"proc caller {argument} {\n"
f" global {declared_builtin}\n"
" set localValue 2\n"
" puts $local\n"
" localP\n"
"}\n"
)
workspace_source = """set ::workspaceValue 1 workspace_source = """set ::workspaceValue 1
proc workspaceProc {} { return } proc workspaceProc {} { return }
""" """
@@ -113,14 +102,10 @@ def test_unset_space_shows_options_then_variables(tmp_path, monkeypatch):
items = _complete(document, lsp.Position(line=1, character=len(tail))) items = _complete(document, lsp.Position(line=1, character=len(tail)))
labels = {item.label for item in items} labels = {item.label for item in items}
if tail in {"unset ", "unset -"}: if tail in {"unset ", "unset -"}:
assert labels == {"-nocomplain", "--"} assert labels == {"nocomplain"}
else: else:
assert "globalValue" in labels assert "globalValue" in labels
assert "-nocomplain" not in labels assert "-nocomplain" not in labels
if tail == "unset -nocomplain ":
assert "--" in labels
else:
assert "--" not in labels
def test_array_keys_complete_in_set_and_substitution(tmp_path: Path, monkeypatch): def test_array_keys_complete_in_set_and_substitution(tmp_path: Path, monkeypatch):
@@ -130,19 +115,16 @@ def test_array_keys_complete_in_set_and_substitution(tmp_path: Path, monkeypatch
"set ::lib_flag(enabled) 1\nset ::lib_flag(external) 1\n", "set ::lib_flag(enabled) 1\nset ::lib_flag(external) 1\n",
) )
assert server.update_poco_completion_for_file(workspace) assert server.update_poco_completion_for_file(workspace)
source = ( source = "set lib_flag(enabled) 0\nset lib_flag(empty) 1\nset other(wrong) 1\nproc hidden {} { set lib_flag(private) 1 }\nset lib_flag()\nputs $lib_flag(en)\nputs 😀; set lib_flag(em\n"
"set lib_flag(enabled) 0\n"
"set lib_flag(empty) 1\n"
"set other(wrong) 1\n"
"proc hidden {} { set lib_flag(private) 1 }\n"
"set lib_flag()\n"
"puts $lib_flag(en)\n"
"puts 😀; set lib_flag(em\n"
)
current = _document(tmp_path / "arrays-current.tcl", source) current = _document(tmp_path / "arrays-current.tcl", source)
server.workspace.put_text_document(lsp.TextDocumentItem( server.workspace.put_text_document(
uri=current.uri, language_id="tcl", version=1, text=source, lsp.TextDocumentItem(
)) uri=current.uri,
language_id="tcl",
version=1,
text=source,
)
)
assert server.update_poco_completion_for_file(current) assert server.update_poco_completion_for_file(current)
items = _complete(current, _position_after(source, "set lib_flag(", 3)) items = _complete(current, _position_after(source, "set lib_flag(", 3))
assert [item.label for item in items] == ["empty", "enabled", "external"] assert [item.label for item in items] == ["empty", "enabled", "external"]
@@ -179,32 +161,28 @@ def test_dynamic_array_index_keeps_variable_identity(tmp_path: Path, monkeypatch
assert variable_name(tree.children[3].args[0]) is None assert variable_name(tree.children[3].args[0]) is None
path = tmp_path / "dynamic.tcl" path = tmp_path / "dynamic.tcl"
index = build_file_symbol_index(str(path), path.as_uri(), tree) index = build_file_symbol_index(str(path), path.as_uri(), tree)
definition = next( definition = next(item for item in index.occurrences if item.identity.name == "::custom_flag" and item.is_definition)
item for item in index.occurrences
if item.identity.name == "::custom_flag" and item.is_definition
)
assert definition.range.start.character == 4 assert definition.range.start.character == 4
assert definition.range.end.character == 15 assert definition.range.end.character == 15
assert definition.array_element is None assert definition.array_element is None
assert any(item.identity.name == "::mom_path_name" for item in index.occurrences) assert any(item.identity.name == "::mom_path_name" for item in index.occurrences)
highlighter = _Highlighter([], {}) highlighter = _Highlighter([], {})
tree.accept(highlighter, recurse=True) tree.accept(highlighter, recurse=True)
assert any( assert any(position == (0, 4) and length == 11 and kind == "variable" for position, length, kind, _ in highlighter._tokens)
position == (0, 4) and length == 11 and kind == "variable"
for position, length, kind, _ in highlighter._tokens
)
server, _, _ = _completion_server(tmp_path, monkeypatch) server, _, _ = _completion_server(tmp_path, monkeypatch)
current = _document(path, source) current = _document(path, source)
server.workspace.put_text_document(lsp.TextDocumentItem( server.workspace.put_text_document(
uri=current.uri, language_id="tcl", version=1, text=source, lsp.TextDocumentItem(
)) uri=current.uri,
language_id="tcl",
version=1,
text=source,
)
)
assert server.update_poco_completion_for_file(current) assert server.update_poco_completion_for_file(current)
items = _complete(current, _position_after(source, "puts $custom")) items = _complete(current, _position_after(source, "puts $custom"))
assert "custom_flag" in {item.label for item in items} assert "custom_flag" in {item.label for item in items}
workspace_items = next( workspace_items = next(items for item_path, items in server.completion_items_by_file_snapshot().items() if server.paths_equal(item_path, str(path)))
items for item_path, items in server.completion_items_by_file_snapshot().items()
if server.paths_equal(item_path, str(path))
)
assert {"quoted_flag", "command_flag"} <= {item.label for item in workspace_items} assert {"quoted_flag", "command_flag"} <= {item.label for item in workspace_items}
@@ -236,18 +214,25 @@ def test_literal_array_components_complete_around_substitutions(tmp_path: Path,
offset = marked.index("|") offset = marked.index("|")
line = marked.replace("|", "") line = marked.replace("|", "")
items = array_element_completions( items = array_element_completions(
[line], lsp.Position(line=0, character=offset), [line],
server.navigation_snapshot().values(), str(tmp_path / "caller.tcl"), lsp.Position(line=0, character=offset),
server.navigation_snapshot().values(),
str(tmp_path / "caller.tcl"),
) )
assert {item.label for item in items} == labels assert {item.label for item in items} == labels
edit = next(item.text_edit for item in items if item.label == selected) edit = next(item.text_edit for item in items if item.label == selected)
item = next(item for item in items if item.label == selected) item = next(item for item in items if item.label == selected)
assert item.insert_text_format == lsp.InsertTextFormat.PlainText assert item.insert_text_format == lsp.InsertTextFormat.PlainText
assert line[: edit.range.start.character] + edit.new_text + line[edit.range.end.character :] == expected assert line[: edit.range.start.character] + edit.new_text + line[edit.range.end.character :] == expected
assert array_element_completions( assert (
["set custom_flag(from_move,$::mom"], lsp.Position(line=0, character=31), array_element_completions(
server.navigation_snapshot().values(), str(tmp_path / "caller.tcl"), ["set custom_flag(from_move,$::mom"],
) is None lsp.Position(line=0, character=31),
server.navigation_snapshot().values(),
str(tmp_path / "caller.tcl"),
)
is None
)
def _argument_completion_request(source: str): def _argument_completion_request(source: str):
@@ -277,9 +262,7 @@ def test_variable_completion_filters_and_ranks_candidates(tmp_path: Path, monkey
other_builtin = standard_items.nx_variables[1] other_builtin = standard_items.nx_variables[1]
assert declared_builtin.label in by_label assert declared_builtin.label in by_label
assert other_builtin.label in by_label assert other_builtin.label in by_label
assert by_label[declared_builtin.label].documentation == ( assert by_label[declared_builtin.label].documentation == (declared_builtin.documentation)
declared_builtin.documentation
)
assert by_label["localValue"].sort_text.startswith("000:") assert by_label["localValue"].sort_text.startswith("000:")
assert by_label["globalValue"].sort_text.startswith("100:") assert by_label["globalValue"].sort_text.startswith("100:")
assert by_label["workspaceValue"].sort_text.startswith("200:") assert by_label["workspaceValue"].sort_text.startswith("200:")
@@ -307,18 +290,9 @@ def test_command_completion_filters_and_ranks_candidates(tmp_path: Path, monkeyp
def test_completion_context_handles_nested_commands_and_utf16(): def test_completion_context_handles_nested_commands_and_utf16():
assert ( assert completion_context(["set result [work"], lsp.Position(line=0, character=16)) == CompletionContext.COMMAND
completion_context(["set result [work"], lsp.Position(line=0, character=16)) assert completion_context(["😀 puts $value"], lsp.Position(line=0, character=14)) == CompletionContext.VARIABLE
== CompletionContext.COMMAND assert completion_context(["puts value"], lsp.Position(line=0, character=10)) == CompletionContext.GENERAL
)
assert (
completion_context(["😀 puts $value"], lsp.Position(line=0, character=14))
== CompletionContext.VARIABLE
)
assert (
completion_context(["puts value"], lsp.Position(line=0, character=10))
== CompletionContext.GENERAL
)
def test_string_subcommands_and_compare_options_are_context_aware(): def test_string_subcommands_and_compare_options_are_context_aware():
@@ -330,9 +304,7 @@ def test_string_subcommands_and_compare_options_are_context_aware():
"-length", "-length",
"-nocase", "-nocase",
} }
assert _argument_completion_labels("string compare -nocase ") == { assert _argument_completion_labels("string compare -nocase ") == {"-length"}
"-length"
}
assert _argument_completion_labels("string compare -length ") is None assert _argument_completion_labels("string compare -length ") is None
@@ -356,22 +328,14 @@ def test_string_completion_inside_braced_conditions_and_bodies():
subcommands = _argument_completion_labels(prefix + "[string ") subcommands = _argument_completion_labels(prefix + "[string ")
assert subcommands is not None assert subcommands is not None
assert {"compare", "equal", "is"} <= subcommands assert {"compare", "equal", "is"} <= subcommands
assert _argument_completion_labels(prefix + "[string compare -") == { assert _argument_completion_labels(prefix + "[string compare -") == {"-length", "-nocase"}
"-length", "-nocase" assert _argument_completion_labels(prefix + "[string compare -nocase ") == {"-length"}
}
assert _argument_completion_labels(
prefix + "[string compare -nocase "
) == {"-length"}
def test_closed_braced_arguments_do_not_change_completion_context(): def test_closed_braced_arguments_do_not_change_completion_context():
assert _argument_completion_labels("puts {[string compare }") is None assert _argument_completion_labels("puts {[string compare }") is None
assert _argument_completion_labels( assert _argument_completion_labels("if {[string equal a b]} {string compare ") == {"-length", "-nocase"}
"if {[string equal a b]} {string compare " assert _argument_completion_labels("if {[string equal a b] && [string is integer ") == {"-failindex", "-strict"}
) == {"-length", "-nocase"}
assert _argument_completion_labels(
"if {[string equal a b] && [string is integer "
) == {"-failindex", "-strict"}
def test_dict_array_namespace_file_and_info_subcommands(): def test_dict_array_namespace_file_and_info_subcommands():
@@ -413,9 +377,7 @@ def test_dict_array_namespace_file_and_info_subcommands():
assert {"args", "body", "commands", "exists", "procs", "vars"} <= info_items assert {"args", "body", "commands", "exists", "procs", "vars"} <= info_items
def test_variable_context_still_takes_priority_inside_tcl_command( def test_variable_context_still_takes_priority_inside_tcl_command(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
_, current, source = _completion_server(tmp_path, monkeypatch) _, current, source = _completion_server(tmp_path, monkeypatch)
command_source = source.replace( command_source = source.replace(
" puts $local\n", " puts $local\n",
@@ -437,9 +399,7 @@ def test_variable_context_still_takes_priority_inside_tcl_command(
assert "localValue" in {item.label for item in items} assert "localValue" in {item.label for item in items}
def test_lsp_completion_returns_only_matching_command_options( def test_lsp_completion_returns_only_matching_command_options(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
_, current, _ = _completion_server(tmp_path, monkeypatch) _, current, _ = _completion_server(tmp_path, monkeypatch)
source = "string compare " source = "string compare "
current = _document(tmp_path / "current.tcl", source) current = _document(tmp_path / "current.tcl", source)
@@ -459,9 +419,7 @@ def test_lsp_completion_returns_only_matching_command_options(
assert all(item.sort_text.startswith("000:") for item in items) assert all(item.sort_text.startswith("000:") for item in items)
def test_space_trigger_does_not_open_broad_fallback_completion( def test_space_trigger_does_not_open_broad_fallback_completion(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
_, current, _ = _completion_server(tmp_path, monkeypatch) _, current, _ = _completion_server(tmp_path, monkeypatch)
source = "set value " source = "set value "
current = _document(tmp_path / "current.tcl", source) current = _document(tmp_path / "current.tcl", source)
@@ -550,9 +508,7 @@ def test_path_completion_is_relative_filtered_and_tcl_safe(tmp_path: Path):
assert items[0].text_edit.range.start.character == len("source ") assert items[0].text_edit.range.start.character == len("source ")
def test_lsp_source_completion_reads_paths_from_document_directory( def test_lsp_source_completion_reads_paths_from_document_directory(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
server, current, _ = _completion_server(tmp_path, monkeypatch) server, current, _ = _completion_server(tmp_path, monkeypatch)
scripts = tmp_path / "scripts" scripts = tmp_path / "scripts"
scripts.mkdir() scripts.mkdir()
@@ -576,9 +532,7 @@ def test_lsp_source_completion_reads_paths_from_document_directory(
assert "scripts/ignored.txt" not in labels assert "scripts/ignored.txt" not in labels
def test_command_and_dict_for_snippets_use_lsp_snippet_placeholders( def test_command_and_dict_for_snippets_use_lsp_snippet_placeholders(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
_, current, source = _completion_server(tmp_path, monkeypatch) _, current, source = _completion_server(tmp_path, monkeypatch)
command_items = _complete(current, _position_after(source, "localP", occurrence=1)) command_items = _complete(current, _position_after(source, "localP", occurrence=1))
command_by_label = {item.label: item for item in command_items} command_by_label = {item.label: item for item in command_items}
@@ -595,14 +549,10 @@ def test_command_and_dict_for_snippets_use_lsp_snippet_placeholders(
switch_arguments = _argument_completion_request("switch ") switch_arguments = _argument_completion_request("switch ")
assert switch_arguments is not None assert switch_arguments is not None
assert {"switch block", "-exact", "-glob", "-regexp"} <= { assert {"switch block", "-exact", "-glob", "-regexp"} <= {item.label for item in switch_arguments.items}
item.label for item in switch_arguments.items
}
def test_semantic_variable_and_procedure_argument_completion( def test_semantic_variable_and_procedure_argument_completion(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
_, current, source = _completion_server(tmp_path, monkeypatch) _, current, source = _completion_server(tmp_path, monkeypatch)
variable_items = _complete(current, _position_after(source, " set ")) variable_items = _complete(current, _position_after(source, " set "))
@@ -633,9 +583,7 @@ def test_semantic_variable_and_procedure_argument_completion(
assert "string" not in procedure_labels assert "string" not in procedure_labels
def test_namespace_argument_completion_uses_navigation_index( def test_namespace_argument_completion_uses_navigation_index(tmp_path: Path, monkeypatch):
tmp_path: Path, monkeypatch
):
server, current, _ = _completion_server(tmp_path, monkeypatch) server, current, _ = _completion_server(tmp_path, monkeypatch)
namespace_source = "namespace eval tools { proc helper {} { return } }\n" namespace_source = "namespace eval tools { proc helper {} { return } }\n"
namespace_document = _document(tmp_path / "namespaces.tcl", namespace_source) namespace_document = _document(tmp_path / "namespaces.tcl", namespace_source)