Files
Sheerka-Old/tests/repl/test_SheerkaPromptCompleter.py
kodjo dd3d8f4abe Fixed #61 : SheerkaDebugManager: Add get_value()
Fixed #60 : Hash error when ReturnValue is a list of list
Fixed #59 : Implement smart_get()
Fixed #58 : SheerkaPromptCompleter: Cannot parse concept token
Fixed #57 : SheerkaPrompt: Add concept autocompletion
Fixed #56 : automatically backup command
Fixed #54 : I can record execution status
Fixed #53 : ConceptManager: modify_concept fails
2021-04-09 15:47:32 +02:00

279 lines
14 KiB
Python

import pytest
from prompt_toolkit.completion import CompleteEvent
from prompt_toolkit.document import Document
from core.concept import Concept
from core.tokenizer import TokenKind
from repl.SheerkaPromptCompleter import SheerkaPromptCompleter, FuncFound, ConceptCompleterHelper
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
class TestSheerkaPromptCompleter(TestUsingMemoryBasedSheerka):
def test_i_can_complete_with_builtins(self):
sheerka = self.get_sheerka()
completions = SheerkaPromptCompleter(sheerka).get_completions(Document("get"), CompleteEvent())
as_dict = {c.display_text: c for c in completions}
assert "get_partition" in as_dict
assert as_dict["get_partition"].text == "get_partition("
assert as_dict["get_partition"].display_text == "get_partition"
assert as_dict["get_partition"].display_meta_text == "builtin"
completions = SheerkaPromptCompleter(sheerka).get_completions(Document("cache"), CompleteEvent())
as_dict = {c.display_text: c for c in completions}
assert "caches_names" in as_dict
assert as_dict["caches_names"].text == "caches_names()"
assert as_dict["caches_names"].display_text == "caches_names"
assert as_dict["caches_names"].display_meta_text == "builtin"
def test_i_can_complete_with_commands(self):
sheerka = self.get_sheerka()
completions = SheerkaPromptCompleter(sheerka).get_completions(Document("q"), CompleteEvent())
as_dict = {c.display_text: c for c in completions}
assert "quit" in as_dict
assert as_dict["quit"].text == "quit"
assert as_dict["quit"].display_text == "quit"
assert as_dict["quit"].display_meta_text == "command"
@pytest.mark.parametrize("concept_name", [
"foo",
"a long name",
])
def test_i_can_complete_concept(self, concept_name):
sheerka, context, foo = self.init_concepts(Concept(concept_name), create_new=True)
completer = SheerkaPromptCompleter(sheerka)
completer.complete_commands = False
completer.complete_builtins = False
for i in range(1, len(concept_name)):
before_cursor = concept_name[:i]
completions = list(completer.get_completions(Document(before_cursor), CompleteEvent()))
as_dict = {c.display_text: c for c in completions}
assert concept_name in as_dict, f"{i=}, {before_cursor=}"
def test_i_can_complete_sya_concept_with_variable(self):
sheerka, context, foo, something, bar = self.init_concepts(
Concept("if true x then do y else do z end").def_var("x").def_var("y").def_var("z"),
Concept("something"),
Concept("bar"),
create_new=True)
completer = SheerkaPromptCompleter(sheerka)
completer.complete_commands = False
completer.complete_builtins = False
text = "if true some cond then do some thing else do something else end"
# i 0123456789012345678901234567890123456789012345678901234567890123
# 0 1 2 3 4 5 6
for i in range(1, len(text) + 1):
before_cursor = text[:i]
d, c = Document(before_cursor), CompleteEvent()
completions = list(completer.get_completions(d, c))
display_as_dict = {(c.display_text, c.start_position): c for c in completions}
if i == 0:
assert len(completer.concepts_candidates) == 3
assert (foo.name, 0) in display_as_dict
assert display_as_dict[(foo.name, 0)].text == "if true "
assert (something.name, 0) in display_as_dict
assert (bar.name, 0) in display_as_dict
if i in range(1, 8): # 'if true'
assert len(completer.concepts_candidates) == 1
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 0
assert display_as_dict[(foo.name, -i)].text == "if true "
assert len(display_as_dict) == 1
if i == 8: # 'if true '
assert len(completer.concepts_candidates) == 1
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 1
assert display_as_dict[(foo.name, -i)].text == "if true "
assert len(display_as_dict) == 1
elif i in range(9, 13): # 'some'
assert len(completer.concepts_candidates) == 2
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 1
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " then do "
assert (something.name, 8 - i) in display_as_dict
assert display_as_dict[(something.name, 8 - i)].text == "something"
elif i in range(13, 18): # ' cond'
assert len(completer.concepts_candidates) == 2, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 1
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " then do "
elif i == 18: # 'cond '
assert len(completer.concepts_candidates) == 2, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 1
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " then do "
elif i in range(19, 26): # 'then do'
assert len(completer.concepts_candidates) == 2, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 2
assert display_as_dict[(foo.name, -i)].text == "if true some cond then do "
elif i == 26: # 'then do '
assert len(completer.concepts_candidates) == 2, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 3
assert display_as_dict[(foo.name, -i)].text == "if true some cond then do "
elif i in range(27, 31): # 'some'
assert len(completer.concepts_candidates) == 3, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 3
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " else do "
assert (something.name, 26 - i) in display_as_dict
assert display_as_dict[(something.name, 26 - i)].text == "something"
elif i in range(31, 38): # ' thing '
assert len(completer.concepts_candidates) == 3, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 3
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " else do "
elif i in range(38, 45): # 'else do'
assert len(completer.concepts_candidates) == 3, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 4
assert display_as_dict[(foo.name, -i)].text == "if true some cond then do some thing else do "
elif i == 45: # 'else do '
assert len(completer.concepts_candidates) == 3, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 5
assert display_as_dict[(foo.name, -i)].text == "if true some cond then do some thing else do "
elif i in range(46, 54): # 'something'
assert len(completer.concepts_candidates) == 4, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 5
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " end"
assert (something.name, 45 - i) in display_as_dict
assert display_as_dict[(something.name, 45 - i)].text == "something"
elif i == 54: # 'g' from 'something'
assert len(completer.concepts_candidates) == 4, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 5
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " end"
elif i == 55: # ' ' before 'else '
assert len(completer.concepts_candidates) == 7, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 5
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " end"
elif i == 56: # 'e' from 'else '
assert len(completer.concepts_candidates) == 7, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 6
assert display_as_dict[(foo.name, -i)].text == "if true some cond then do some thing else do something end"
elif i in range(57, 60): # 'lse '
assert len(completer.concepts_candidates) == 7, f"{i=}, {before_cursor=}"
assert (foo.name, -i) in display_as_dict
assert completer.concepts_candidates[(foo.id, 1)].last_part_index == 5
assert display_as_dict[(foo.name, -i)].text == before_cursor.rstrip() + " end"
# @pytest.mark.parametrize("text, expected", [
# ("func(", ["10", "20", "30"]),
# ("func(1", ["10"]),
# ("func( 1", ["10"]),
# ("func( 10, ", ["'hello'"]),
# ("func( 10, v", []),
# ("func( 10, 'hel", ["'hello'"]),
# ('func( 10, "hel', []),
# ("func('hell,,', func2(2,4), 'w", ["'world'"]),
# ])
# def test_i_can_complete_function_parameters(self, text, expected):
# sheerka = self.get_sheerka()
# context = self.get_context(sheerka)
# params_history_service = sheerka.services[SheerkaFunctionsParametersHistory.NAME]
# params_history_service.record_function_parameter(context, "func", 0, "10")
# params_history_service.record_function_parameter(context, "func", 0, "20")
# params_history_service.record_function_parameter(context, "func", 0, "30")
# params_history_service.record_function_parameter(context, "func", 1, "'hello'")
# params_history_service.record_function_parameter(context, "func", 2, "'world'")
#
# document = Document(text)
# completions = SheerkaPromptCompleter(sheerka).get_completions(document, CompleteEvent())
# as_list = [c.display_text for c in completions]
# assert as_list == expected
@pytest.mark.parametrize("text, pos, expected", [
("", 0, None),
("foo", 3, None),
("foo(", 4, FuncFound("foo", 0, 3)),
("foo(a, ", 7, FuncFound("foo", 0, 3)),
("foo( a , ", 9, FuncFound("foo", 0, 3)),
("foo(bar)", 8, None),
("foo(bar)", 7, FuncFound("foo", 0, 3)),
("foo()", 5, None),
("foo()", 4, FuncFound("foo", 0, 3)),
("xxx foo(", 8, FuncFound("foo", 4, 7)),
("foo (", 5, FuncFound("foo", 0, 4)),
("foo (", 6, FuncFound("foo", 0, 5)),
])
def test_inside_function(self, text, pos, expected):
assert SheerkaPromptCompleter.inside_function(text, pos) == expected
@pytest.mark.parametrize("text, expected_param_number, expected_comma_index", [
("", 0, -1),
("foo", 0, -1),
("foo, ", 1, 3),
("foo, ", 1, 3),
("foo, 'he,llo', ", 2, 13),
("foo, (he,llo), ", 2, 13),
("foo, (he,llo ", 1, 3),
("foo, 'he,llo ", 1, 3),
])
def test_get_param_number(self, text, expected_param_number, expected_comma_index):
assert SheerkaPromptCompleter.get_param_number(text) == (expected_param_number, expected_comma_index)
@pytest.mark.parametrize("concept, expected_parts", [
(Concept("if true x then do y else do z end").def_var("x").def_var("y").def_var("z"), [
"if true ",
TokenKind.VAR_DEF,
"then do ",
TokenKind.VAR_DEF,
"else do ",
TokenKind.VAR_DEF,
"end"
]),
(Concept("x something y").def_var("x").def_var("y"), ["something ", TokenKind.VAR_DEF]),
(Concept("foo x y").def_var("x").def_var("y"), ["foo ", TokenKind.VAR_DEF]),
(Concept("foo x y bar").def_var("x").def_var("y"), ["foo ", TokenKind.VAR_DEF, "bar"]),
(Concept("x y foo").def_var("x").def_var("y"), ["foo"]),
])
def test_i_can_initialize_concept_parts(self, concept, expected_parts):
concept.init_key()
parts = ConceptCompleterHelper.initialize_parts(concept)
assert parts == expected_parts
# def test_jedi_infer(self):
# sheerka = self.get_sheerka()
#
# document = Document("get_partition(")
# SheerkaPromptCompleter(sheerka).test_jedi(document)
# pass
#
# def test_parso_parser(self):
# import parso
# module = parso.parse("get_results() | filter('id==4', param2) | format_d()")
# pass