Home | History | Annotate | Download | only in objc-property
      1 """
      2 Use lldb Python API to verify that expression evaluation for property references uses the correct getters and setters
      3 """
      4 
      5 import os, time
      6 import re
      7 import unittest2
      8 import lldb, lldbutil
      9 from lldbtest import *
     10 
     11 class ObjCPropertyTestCase(TestBase):
     12 
     13     mydir = os.path.join("lang", "objc", "objc-property")
     14 
     15     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     16     @python_api_test
     17     @dsym_test
     18     def test_objc_properties_with_dsym(self):
     19         """Test that expr uses the correct property getters and setters"""
     20         if self.getArchitecture() == 'i386':
     21             self.skipTest("requires modern objc runtime")
     22         self.buildDsym()
     23         self.do_test_properties()
     24 
     25     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     26     @python_api_test
     27     @dwarf_test
     28     def test_objc_properties_with_dwarf(self):
     29         """Test that expr uses the correct property getters and setters"""
     30         if self.getArchitecture() == 'i386':
     31             self.skipTest("requires modern objc runtime")
     32         self.buildDwarf()
     33         self.do_test_properties()
     34 
     35     def setUp(self):
     36         # Call super's setUp().                                                                                                           
     37         TestBase.setUp(self)
     38 
     39         # Find the line number to break for main.c.                                                                                       
     40 
     41         self.source_name = 'main.m'
     42 
     43     def run_to_main (self):
     44         """Test that expr uses the correct property getters and setters"""
     45         exe = os.path.join(os.getcwd(), "a.out")
     46 
     47         # Create a target from the debugger.
     48 
     49         target = self.dbg.CreateTarget (exe)
     50         self.assertTrue(target, VALID_TARGET)
     51 
     52         # Set up our breakpoints:
     53         
     54         main_bkpt = target.BreakpointCreateBySourceRegex ("Set a breakpoint here.", lldb.SBFileSpec (self.source_name))
     55         self.assertTrue(main_bkpt and
     56                         main_bkpt.GetNumLocations() == 1,
     57                         VALID_BREAKPOINT)
     58 
     59         # Now launch the process, and do not stop at the entry point.
     60         process = target.LaunchSimple (None, None, os.getcwd())
     61 
     62         self.assertTrue(process.GetState() == lldb.eStateStopped,
     63                         PROCESS_STOPPED)
     64 
     65         threads = lldbutil.get_threads_stopped_at_breakpoint (process, main_bkpt)
     66         self.assertTrue (len(threads) == 1)
     67         thread = threads[0]
     68         return thread
     69 
     70     def do_test_properties (self):
     71 
     72         thread = self.run_to_main()
     73 
     74         frame = thread.GetFrameAtIndex(0)
     75 
     76         mine = frame.FindVariable ("mine")
     77         self.assertTrue (mine.IsValid())
     78         access_count = mine.GetChildMemberWithName ("_access_count")
     79         self.assertTrue (access_count.IsValid())
     80         start_access_count = access_count.GetValueAsUnsigned (123456)
     81         self.assertTrue (start_access_count != 123456)
     82 
     83         #
     84         # The first set of tests test calling the getter & setter of
     85         # a property that actually only has a getter & setter and no
     86         # @property.
     87         #
     88         nonexistant_value = frame.EvaluateExpression("mine.nonexistantInt", False)
     89         nonexistant_error = nonexistant_value.GetError()
     90         self.assertTrue (nonexistant_error.Success())
     91         nonexistant_int = nonexistant_value.GetValueAsUnsigned (123456)
     92         self.assertTrue (nonexistant_int == 6)
     93         
     94         # Calling the getter function would up the access count, so make sure that happened.
     95         
     96         new_access_count = access_count.GetValueAsUnsigned (123456)
     97         self.assertTrue (new_access_count - start_access_count == 1)
     98         start_access_count = new_access_count
     99 
    100         #
    101         # Now call the setter, then make sure that
    102         nonexistant_change = frame.EvaluateExpression("mine.nonexistantInt = 10", False)
    103         nonexistant_error = nonexistant_change.GetError()
    104         self.assertTrue (nonexistant_error.Success())
    105 
    106         # Calling the setter function would up the access count, so make sure that happened.
    107         
    108         new_access_count = access_count.GetValueAsUnsigned (123456)
    109         self.assertTrue (new_access_count - start_access_count == 1)
    110         start_access_count = new_access_count
    111 
    112         #
    113         # Now we call the getter of a property that is backed by an ivar,
    114         # make sure it works and that we actually update the backing ivar.
    115         #
    116 
    117         backed_value = frame.EvaluateExpression("mine.backedInt", False)
    118         backed_error = backed_value.GetError()
    119         self.assertTrue (backed_error.Success())
    120         backing_value = mine.GetChildMemberWithName ("_backedInt")
    121         self.assertTrue (backing_value.IsValid())
    122         self.assertTrue (backed_value.GetValueAsUnsigned (12345) == backing_value.GetValueAsUnsigned(23456))
    123 
    124         unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False)
    125         unbacked_error = unbacked_value.GetError()
    126         self.assertTrue (unbacked_error.Success())
    127 
    128         idWithProtocol_value = frame.EvaluateExpression("mine.idWithProtocol", False)
    129         idWithProtocol_error = idWithProtocol_value.GetError()
    130         self.assertTrue (idWithProtocol_error.Success())
    131         self.assertTrue (idWithProtocol_value.GetTypeName() == "id")
    132         
    133 if __name__ == '__main__':
    134     import atexit
    135     lldb.SBDebugger.Initialize()
    136     atexit.register(lambda: lldb.SBDebugger.Terminate())
    137     unittest2.main()
    138