1"""
2Test lldb-vscode completions request
3"""
4
5
6import lldbvscode_testcase
7import unittest2
8import vscode
9from lldbsuite.test import lldbutil
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12
13class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):
14
15    def assertEvaluate(self, expression, regex):
16        self.assertRegexpMatches(
17            self.vscode.request_evaluate(expression, context=self.context)['body']['result'],
18            regex)
19
20    def assertEvaluateFailure(self, expression):
21        self.assertNotIn('result',
22            self.vscode.request_evaluate(expression, context=self.context)['body'])
23
24    def isExpressionParsedExpected(self):
25        return self.context != "hover"
26
27    def run_test_evaluate_expressions(self, context=None):
28        """
29            Tests the evaluate expression request at different breakpoints
30        """
31        self.context = context
32        program = self.getBuildArtifact("a.out")
33        self.build_and_launch(program)
34        source = "main.cpp"
35        self.set_source_breakpoints(
36            source,
37            [
38                line_number(source, "// breakpoint 1"),
39                line_number(source, "// breakpoint 2"),
40                line_number(source, "// breakpoint 3"),
41                line_number(source, "// breakpoint 4"),
42                line_number(source, "// breakpoint 5"),
43                line_number(source, "// breakpoint 6"),
44                line_number(source, "// breakpoint 7"),
45            ]
46        )
47        self.continue_to_next_stop()
48
49        # Expressions at breakpoint 1, which is in main
50        self.assertEvaluate("var1", "20")
51        self.assertEvaluate("var2", "21")
52        self.assertEvaluate("static_int", "42")
53        self.assertEvaluate("non_static_int", "43")
54        self.assertEvaluate("struct1", "my_struct @ 0x.*")
55        self.assertEvaluate("struct1.foo", "15")
56        self.assertEvaluate("struct2->foo", "16")
57
58        self.assertEvaluateFailure("var") # local variable of a_function
59        self.assertEvaluateFailure("my_struct") # type name
60        self.assertEvaluateFailure("int") # type name
61        self.assertEvaluateFailure("foo") # member of my_struct
62
63        if self.isExpressionParsedExpected():
64            self.assertEvaluate(
65                "a_function",
66                "0x.*a.out`a_function.*")
67            self.assertEvaluate("a_function(1)", "1")
68            self.assertEvaluate("var2 + struct1.foo", "36")
69            self.assertEvaluate(
70                "foo_func",
71                "0x.*a.out`foo_func.*")
72            self.assertEvaluate("foo_var", "44")
73        else:
74            self.assertEvaluateFailure("a_function")
75            self.assertEvaluateFailure("a_function(1)")
76            self.assertEvaluateFailure("var2 + struct1.foo")
77            self.assertEvaluateFailure("foo_func")
78            self.assertEvaluateFailure("foo_var")
79
80        # Expressions at breakpoint 2, which is an anonymous block
81        self.continue_to_next_stop()
82        self.assertEvaluate("var1", "20")
83        self.assertEvaluate("var2", "2") # different variable with the same name
84        self.assertEvaluate("static_int", "42")
85        self.assertEvaluate("non_static_int", "10") # different variable with the same name
86        self.assertEvaluate("struct1", "my_struct @ 0x.*")
87        self.assertEvaluate("struct1.foo", "15")
88        self.assertEvaluate("struct2->foo", "16")
89
90        if self.isExpressionParsedExpected():
91            self.assertEvaluate(
92                "a_function",
93                "0x.*a.out`a_function.*")
94            self.assertEvaluate("a_function(1)", "1")
95            self.assertEvaluate("var2 + struct1.foo", "17")
96            self.assertEvaluate(
97                "foo_func",
98                "0x.*a.out`foo_func.*")
99            self.assertEvaluate("foo_var", "44")
100        else:
101            self.assertEvaluateFailure("a_function")
102            self.assertEvaluateFailure("a_function(1)")
103            self.assertEvaluateFailure("var2 + struct1.foo")
104            self.assertEvaluateFailure("foo_func")
105            self.assertEvaluateFailure("foo_var")
106
107        # Expressions at breakpoint 3, which is inside a_function
108        self.continue_to_next_stop()
109        self.assertEvaluate("var", "42")
110        self.assertEvaluate("static_int", "42")
111        self.assertEvaluate("non_static_int", "43")
112
113        self.assertEvaluateFailure("var1")
114        self.assertEvaluateFailure("var2")
115        self.assertEvaluateFailure("struct1")
116        self.assertEvaluateFailure("struct1.foo")
117        self.assertEvaluateFailure("struct2->foo")
118        self.assertEvaluateFailure("var2 + struct1.foo")
119
120        if self.isExpressionParsedExpected():
121            self.assertEvaluate(
122                "a_function",
123                "0x.*a.out`a_function.*")
124            self.assertEvaluate("a_function(1)", "1")
125            self.assertEvaluate("var + 1", "43")
126            self.assertEvaluate(
127                "foo_func",
128                "0x.*a.out`foo_func.*")
129            self.assertEvaluate("foo_var", "44")
130        else:
131            self.assertEvaluateFailure("a_function")
132            self.assertEvaluateFailure("a_function(1)")
133            self.assertEvaluateFailure("var + 1")
134            self.assertEvaluateFailure("foo_func")
135            self.assertEvaluateFailure("foo_var")
136
137        # Now we check that values are updated after stepping
138        self.continue_to_next_stop()
139        self.assertEvaluate("my_vec", "size=2")
140        self.continue_to_next_stop()
141        self.assertEvaluate("my_vec", "size=3")
142
143        self.assertEvaluate("my_map", "size=2")
144        self.continue_to_next_stop()
145        self.assertEvaluate("my_map", "size=3")
146
147        self.assertEvaluate("my_bool_vec", "size=1")
148        self.continue_to_next_stop()
149        self.assertEvaluate("my_bool_vec", "size=2")
150
151    @skipIfWindows
152    @skipIfRemote
153    def test_generic_evaluate_expressions(self):
154        # Tests context-less expression evaluations
155        self.run_test_evaluate_expressions()
156
157    @skipIfWindows
158    @skipIfRemote
159    def test_repl_evaluate_expressions(self):
160        # Tests expression evaluations that are triggered from the Debug Console
161        self.run_test_evaluate_expressions("repl")
162
163    @skipIfWindows
164    @skipIfRemote
165    def test_watch_evaluate_expressions(self):
166        # Tests expression evaluations that are triggered from a watch expression
167        self.run_test_evaluate_expressions("watch")
168
169    @skipIfWindows
170    @skipIfRemote
171    def test_hover_evaluate_expressions(self):
172        # Tests expression evaluations that are triggered when hovering on the editor
173        self.run_test_evaluate_expressions("hover")
174