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