Skip to content

[lldb] Improve completion tests #65973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions lldb/packages/Python/lldbsuite/test/lldbtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2223,12 +2223,15 @@ def check_completion_with_desc(
)
self.assertFalse(got_failure, error_msg)

def complete_exactly(self, str_input, patterns):
self.complete_from_to(str_input, patterns, True)

def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
def complete_from_to(self, str_input, patterns):
"""Test that the completion mechanism completes str_input to patterns,
where patterns could be a pattern-string or a list of pattern-strings"""
where patterns could be a single pattern-string or a list of
pattern-strings.

If there is only one pattern and it is exactly equal to str_input, this
assumes that there should be no completions provided and that the result
should be the same as the input."""

# Patterns should not be None in order to proceed.
self.assertFalse(patterns is None)
# And should be either a string or list of strings. Check for list type
Expand All @@ -2254,21 +2257,16 @@ def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
for idx in range(1, num_matches + 1):
compare_string += match_strings.GetStringAtIndex(idx) + "\n"

if len(patterns) == 1 and str_input == patterns[0] and num_matches:
self.fail("Expected no completions but got:\n" + compare_string)

for p in patterns:
if turn_off_re_match:
self.expect(
compare_string,
msg=COMPLETION_MSG(str_input, p, match_strings),
exe=False,
substrs=[p],
)
else:
self.expect(
compare_string,
msg=COMPLETION_MSG(str_input, p, match_strings),
exe=False,
patterns=[p],
)
self.expect(
compare_string,
msg=COMPLETION_MSG(str_input, p, match_strings),
exe=False,
substrs=[p],
)

def completions_match(self, command, completions):
"""Checks that the completions for the given command are equal to the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,34 @@ def test_expr_completion(self):
)

# Completing member functions
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooNoArgs", "expr some_expr.FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooWithArgs", "expr some_expr.FooWithArgsBar("
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooWithMultipleArgs",
"expr some_expr.FooWithMultipleArgsBar(",
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooUnderscore", "expr some_expr.FooUnderscoreBar_()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooNumbers", "expr some_expr.FooNumbersBar1()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.StaticMemberMethod",
"expr some_expr.StaticMemberMethodBar()",
)

# Completing static functions
self.complete_exactly(
self.complete_from_to(
"expr Expr::StaticMemberMethod", "expr Expr::StaticMemberMethodBar()"
)

# Completing member variables
self.complete_exactly(
self.complete_from_to(
"expr some_expr.MemberVariab", "expr some_expr.MemberVariableBar"
)

Expand Down Expand Up @@ -94,43 +94,43 @@ def test_expr_completion(self):
self.completions_contain("expr 1+", ["1+some_expr", "1+static_cast"])

# Test with spaces
self.complete_exactly(
self.complete_from_to(
"expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr .FooNoArgs", "expr some_expr .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr. FooNoArgs", "expr some_expr. FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr . FooNoArgs", "expr some_expr . FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr Expr :: StaticMemberMethod", "expr Expr :: StaticMemberMethodBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr Expr ::StaticMemberMethod", "expr Expr ::StaticMemberMethodBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr Expr:: StaticMemberMethod", "expr Expr:: StaticMemberMethodBar()"
)

# Test that string literals don't break our parsing logic.
self.complete_exactly(
self.complete_from_to(
'expr const char *cstr = "some_e"; char c = *cst',
'expr const char *cstr = "some_e"; char c = *cstr',
)
self.complete_exactly(
self.complete_from_to(
'expr const char *cstr = "some_e" ; char c = *cst',
'expr const char *cstr = "some_e" ; char c = *cstr',
)
# Requesting completions inside an incomplete string doesn't provide any
# completions.
self.complete_exactly(
self.complete_from_to(
'expr const char *cstr = "some_e', 'expr const char *cstr = "some_e'
)

Expand All @@ -139,110 +139,110 @@ def test_expr_completion(self):
self.assume_no_completions("expr -i0 -- some_expr.", 11)

# Test with expr arguments
self.complete_exactly(
self.complete_from_to(
"expr -i0 -- some_expr .FooNoArgs", "expr -i0 -- some_expr .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr -i0 -- some_expr .FooNoArgs",
"expr -i0 -- some_expr .FooNoArgsBar()",
)

# Addrof and deref
self.complete_exactly(
self.complete_from_to(
"expr (*(&some_expr)).FooNoArgs", "expr (*(&some_expr)).FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (*(&some_expr)) .FooNoArgs", "expr (*(&some_expr)) .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (* (&some_expr)) .FooNoArgs", "expr (* (&some_expr)) .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (* (& some_expr)) .FooNoArgs",
"expr (* (& some_expr)) .FooNoArgsBar()",
)

# Addrof and deref (part 2)
self.complete_exactly(
self.complete_from_to(
"expr (&some_expr)->FooNoArgs", "expr (&some_expr)->FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (&some_expr) ->FooNoArgs", "expr (&some_expr) ->FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (&some_expr) -> FooNoArgs", "expr (&some_expr) -> FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr (&some_expr)-> FooNoArgs", "expr (&some_expr)-> FooNoArgsBar()"
)

# Builtin arg
self.complete_exactly("expr static_ca", "expr static_cast")
self.complete_from_to("expr static_ca", "expr static_cast")

# From other files
self.complete_exactly(
self.complete_from_to(
"expr fwd_decl_ptr->Hidden", "expr fwd_decl_ptr->HiddenMember"
)

# Types
self.complete_exactly("expr LongClassNa", "expr LongClassName")
self.complete_exactly(
self.complete_from_to("expr LongClassNa", "expr LongClassName")
self.complete_from_to(
"expr LongNamespaceName::NestedCla", "expr LongNamespaceName::NestedClass"
)

# Namespaces
self.complete_exactly("expr LongNamespaceNa", "expr LongNamespaceName::")
self.complete_from_to("expr LongNamespaceNa", "expr LongNamespaceName::")

# Multiple arguments
self.complete_exactly(
self.complete_from_to(
"expr &some_expr + &some_e", "expr &some_expr + &some_expr"
)
self.complete_exactly(
self.complete_from_to(
"expr SomeLongVarNameWithCapitals + SomeLongVarName",
"expr SomeLongVarNameWithCapitals + SomeLongVarNameWithCapitals",
)
self.complete_exactly(
self.complete_from_to(
"expr SomeIntVar + SomeIntV", "expr SomeIntVar + SomeIntVar"
)

# Multiple statements
self.complete_exactly(
self.complete_from_to(
"expr long LocalVariable = 0; LocalVaria",
"expr long LocalVariable = 0; LocalVariable",
)

# Custom Decls
self.complete_exactly(
self.complete_from_to(
"expr auto l = [](int LeftHandSide, int bx){ return LeftHandS",
"expr auto l = [](int LeftHandSide, int bx){ return LeftHandSide",
)
self.complete_exactly(
self.complete_from_to(
"expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.Mem",
"expr struct LocalStruct { long MemberName; } ; LocalStruct S; S.MemberName",
)

# Completing function call arguments
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooWithArgsBar(some_exp",
"expr some_expr.FooWithArgsBar(some_expr",
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooWithArgsBar(SomeIntV",
"expr some_expr.FooWithArgsBar(SomeIntVar",
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVa",
"expr some_expr.FooWithMultipleArgsBar(SomeIntVar, SomeIntVar",
)

# Function return values
self.complete_exactly(
self.complete_from_to(
"expr some_expr.Self().FooNoArgs", "expr some_expr.Self().FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.Self() .FooNoArgs", "expr some_expr.Self() .FooNoArgsBar()"
)
self.complete_exactly(
self.complete_from_to(
"expr some_expr.Self(). FooNoArgs", "expr some_expr.Self(). FooNoArgsBar()"
)

Expand Down
14 changes: 3 additions & 11 deletions lldb/test/API/functionalities/completion/TestCompletion.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,18 +235,12 @@ def test_log_file(self):
def test_log_dir(self):
# Complete our source directory.
src_dir = os.path.dirname(os.path.realpath(__file__))
self.complete_from_to(
"log enable lldb expr -f " + src_dir,
[src_dir + os.sep],
turn_off_re_match=True,
)
self.complete_from_to("log enable lldb expr -f " + src_dir, [src_dir + os.sep])

# <rdar://problem/11052829>
def test_infinite_loop_while_completing(self):
"""Test that 'process print hello\' completes to itself and does not infinite loop."""
self.complete_from_to(
"process print hello\\", "process print hello\\", turn_off_re_match=True
)
self.complete_from_to("process print hello\\", "process print hello\\")

def test_watchpoint_co(self):
"""Test that 'watchpoint co' completes to 'watchpoint command '."""
Expand Down Expand Up @@ -726,9 +720,7 @@ def test_symbol_name(self):
self.build()
self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.complete_from_to(
"breakpoint set -n Fo",
"breakpoint set -n Foo::Bar(int,\\ int)",
turn_off_re_match=True,
"breakpoint set -n Fo", "breakpoint set -n Foo::Bar(int,\\ int)"
)
# No completion for Qu because the candidate is
# (anonymous namespace)::Quux().
Expand Down