Skip to content

Commit 13f22f5

Browse files
committed
[lldb] Add expect_expr function for testing expression evaluation in dotests.
Summary: This patch adds a new function to lldbtest: `expect_expr`. This function is supposed to replace the current approach of calling `expect`/`runCmd` with `expr`, `p` etc. `expect_expr` allows evaluating expressions and matching their value/summary/type/error message without having to do any string matching that might allow unintended passes (e.g., `self.expect("expr 3+4", substrs=["7"])` can unexpectedly pass for results like `(Class7) $0 = 7`, `(int) $7 = 22`, `(int) $0 = 77` and so on). This only uses the function in a few places to test and demonstrate it. I'll migrate the tests in follow up commits. Reviewers: JDevlieghere, shafik, labath Reviewed By: labath Subscribers: christof, abidh, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D70314
1 parent 06cfcdc commit 13f22f5

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

lldb/packages/Python/lldbsuite/test/commands/expression/call-function/TestCallBuiltinFunction.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test(self):
3939

4040
# Test different builtin functions.
4141

42-
self.expect("expr __builtin_isinf(0.0f)", substrs=["(int) $", " = 0\n"])
43-
self.expect("expr __builtin_isnormal(0.0f)", substrs=["(int) $", " = 0\n"])
44-
self.expect("expr __builtin_constant_p(1)", substrs=["(int) $", " = 1\n"])
45-
self.expect("expr __builtin_abs(-14)", substrs=["(int) $", " = 14\n"])
42+
self.expect_expr("__builtin_isinf(0.0f)", result_type="int", result_value="0")
43+
self.expect_expr("__builtin_isnormal(0.0f)", result_type="int", result_value="0")
44+
self.expect_expr("__builtin_constant_p(1)", result_type="int", result_value="1")
45+
self.expect_expr("__builtin_abs(-14)", result_type="int", result_value="14")

lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ def cleanup():
9696
cappedSummary.find("someText") <= 0,
9797
"cappedSummary includes the full string")
9898

99+
self.expect_expr("s", result_type=ns+"::wstring", result_summary='L"hello world! מזל טוב!"')
100+
99101
self.expect(
100102
"frame variable",
101103
substrs=[
102-
'(%s::wstring) s = L"hello world! מזל טוב!"'%ns,
103104
'(%s::wstring) S = L"!!!!!"'%ns,
104105
'(const wchar_t *) mazeltov = 0x',
105106
'L"מזל טוב"',

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,6 +2366,45 @@ def expect(
23662366
self.assertTrue(matched if matching else not matched,
23672367
msg if msg else EXP_MSG(str, output, exe))
23682368

2369+
def expect_expr(
2370+
self,
2371+
expr,
2372+
result_summary=None,
2373+
result_value=None,
2374+
result_type=None,
2375+
error_msg=None,
2376+
):
2377+
"""
2378+
Evaluates the given expression and verifies the result.
2379+
:param expr: The expression as a string.
2380+
:param result_summary: The summary that the expression should have. None if the summary should not be checked.
2381+
:param result_value: The value that the expression should have. None if the value should not be checked.
2382+
:param result_type: The type that the expression result should have. None if the type should not be checked.
2383+
:param error_msg: The error message the expression should return. None if the error output should not be checked.
2384+
"""
2385+
self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'")
2386+
2387+
frame = self.frame()
2388+
eval_result = frame.EvaluateExpression(expr)
2389+
2390+
if error_msg:
2391+
self.assertFalse(eval_result.IsValid())
2392+
self.assertEqual(error_msg, eval_result.GetError().GetCString())
2393+
return
2394+
2395+
if not eval_result.GetError().Success():
2396+
self.assertTrue(eval_result.GetError().Success(),
2397+
"Unexpected failure with msg: " + eval_result.GetError().GetCString())
2398+
2399+
if result_type:
2400+
self.assertEqual(result_type, eval_result.GetTypeName())
2401+
2402+
if result_value:
2403+
self.assertEqual(result_value, eval_result.GetValue())
2404+
2405+
if result_summary:
2406+
self.assertEqual(result_summary, eval_result.GetSummary())
2407+
23692408
def invoke(self, obj, name, trace=False):
23702409
"""Use reflection to call a method dynamically with no argument."""
23712410
trace = (True if traceAlways else trace)

0 commit comments

Comments
 (0)