1"""
2Test lldb data formatter subsystem.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class NSSetSyntheticTestCase(TestBase):
14
15    def setUp(self):
16        # Call super's setUp().
17        TestBase.setUp(self)
18        # Find the line number to break at.
19        self.line = line_number('main.m', '// Set break point at this line.')
20
21    @skipUnlessDarwin
22    def test_rdar12529957_with_run_command(self):
23        """Test that NSSet reports its synthetic children properly."""
24        self.build()
25        self.run_tests()
26
27    @skipUnlessDarwin
28    def test_rdar12529957_with_run_command_no_const(self):
29        """Test that NSSet reports its synthetic children properly."""
30        disable_constant_classes = {
31            'CC':
32            'xcrun clang',  # FIXME: Remove when flags are available upstream.
33            'CFLAGS_EXTRAS':
34            '-fno-constant-nsnumber-literals ' +
35            '-fno-constant-nsarray-literals ' +
36            '-fno-constant-nsdictionary-literals'
37        }
38        self.build(dictionary=disable_constant_classes)
39        self.run_tests()
40
41    def run_tests(self):
42        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
43
44        lldbutil.run_break_set_by_file_and_line(
45            self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
46
47        self.runCmd("run", RUN_SUCCEEDED)
48
49        # The stop reason of the thread should be breakpoint.
50        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
51                    substrs=['stopped',
52                             'stop reason = breakpoint'])
53
54        # This is the function to remove the custom formats in order to have a
55        # clean slate for the next test case.
56        def cleanup():
57            self.runCmd('type format clear', check=False)
58            self.runCmd('type summary clear', check=False)
59            self.runCmd('type synth clear', check=False)
60
61        # Execute the cleanup function during test case tear down.
62        self.addTearDownHook(cleanup)
63
64        # Now check that we are displaying Cocoa classes correctly
65        self.expect('frame variable set',
66                    substrs=['4 elements'])
67        self.expect('frame variable mutable',
68                    substrs=['9 elements'])
69        self.expect(
70            'frame variable set --ptr-depth 1 -d run -T',
71            substrs=[
72                '4 elements',
73                '[0]',
74                'hello',
75                '[1]',
76                '(int)2',
77                '[2]',
78                '(int)1',
79                '[3]',
80                'world',
81            ])
82        self.expect(
83            'frame variable mutable --ptr-depth 1 -d run -T',
84            substrs=[
85                '9 elements',
86                '(int)5',
87                '@"3 elements"',
88                '@"www.apple.com"',
89                '(int)3',
90                '@"world"',
91                '(int)4'])
92
93        self.runCmd("next")
94        self.expect('frame variable mutable',
95                    substrs=['0 elements'])
96
97        self.runCmd("next")
98        self.expect('frame variable mutable',
99                    substrs=['4 elements'])
100        self.expect(
101            'frame variable mutable --ptr-depth 1 -d run -T',
102            substrs=[
103                '4 elements',
104                '[0]',
105                '(int)1',
106                '[1]',
107                '(int)2',
108                '[2]',
109                'hello',
110                '[3]',
111                'world',
112            ])
113
114        self.runCmd("next")
115        self.expect('frame variable mutable', substrs=['4 elements'])
116        self.expect(
117            'frame variable mutable --ptr-depth 1 -d run -T',
118            substrs=[
119                '4 elements',
120                '[0]',
121                '(int)1',
122                '[1]',
123                '(int)2',
124                '[2]',
125                'hello',
126                '[3]',
127                'world',
128            ])
129