def test_is_singleton(self): """ Tests that two newly created Qdb objects are the same. """ self.assertIs( Qdb(cmd_manager=NopCommandManager()), Qdb(cmd_manager=NopCommandManager()) )
def test_as_ctx_mgr(self): """ Tests the debugger as a context manager. """ line_1 = False cmd_stop = None with patch.object(NopCommandManager, 'start') as cmd_start, \ patch.object(NopCommandManager, 'stop') as cmd_stop, \ Qdb(cmd_manager=NopCommandManager()) as db: db.set_trace() cmd_start.assert_called_once_with(db, '') line_1 = True self.assertTrue(line_1) self.assertIs(Qdb._instance, db) self.assertEqual( db.get_line( self.filename, db.curframe.f_lineno), ' db.curframe.f_lineno),' ) # Assert the __exit__ clears the singleton so a new one can be used. self.assertIs(Qdb._instance, None) # Assert that __exit__ stopped the command manager. cmd_stop.assert_called_once_with()
def test_inject_default_ns_no_trample(self): """ Tests adding the default namespace does not override a defined name. """ ns = {'a': 1, 'b': 2} with Qdb(cmd_manager=NopCommandManager(), default_namespace=ns) as db,\ db.inject_default_namespace(sys._getframe()): a = 'a' b = 'b' self.assertEqual(a, 'a') self.assertEqual(b, 'b')
def test_inject_default_ns_curframe(self): """ Tests adding a default namespace to the curframe. """ ns = {'a': 1, 'b': 2} # rip pyflakes with Qdb(cmd_manager=NopCommandManager(), default_namespace=ns) as db: db.curframe = sys._getframe() with db.inject_default_namespace(): self.assertEqual(a, 1) # NOQA self.assertEqual(b, 2) # NOQA with self.assertRaises(NameError): a # NOQA with self.assertRaises(NameError): b # NOQA
def test_inject_default_ns(self): """ Tests adding a default namespace to a frame. """ ns = {'a': 1, 'b': 2} # rip pyflakes with Qdb(cmd_manager=NopCommandManager(), default_namespace=ns) as db,\ db.inject_default_namespace(sys._getframe()): self.assertEqual(a, 1) # NOQA self.assertEqual(b, 2) # NOQA # Assert that the namespace was cleaned. with self.assertRaises(NameError): a # NOQA with self.assertRaises(NameError): b # NOQA
def test_file_cache_from_string(self): """ Asserts that manual caching from a string works. """ contents = dedent("""\ line 1 line 2 line 3 line 4 """) db = Qdb(cmd_manager=NopCommandManager()) db.cache_file('file', contents=contents) # Check the whole 'file'. self.assertEquals(db.get_file('file'), contents[:-1]) # drop '\n' for n in range(1, 5): # Check all the lines. self.assertEquals('line %d' % n, db.get_line('file', n))
def test_file_cache_from_disk(self): """ Asserts that the disk caching works. """ # We will use this file, as it is the only file we know that exists. # The first time this is run after a change, __file__ will point to # the source code file; however, if we run this twice in a row, it # points to the byte-compiled file. filename = fix_filename(__file__) db = Qdb(cmd_manager=NopCommandManager()) db.cache_file(filename) with open(filename) as f: contents = f.read()[:-1] # Drop the last newline. # Assert that querying the entire file works. self.assertEqual(db.get_file(filename), contents) for n, line in zip(count(start=1), contents.splitlines()): # Iterate over all the lines of the file, asserting that we # have saved them correctly. This also asserts that the line # indexing is working as intended. self.assertEqual(db.get_line(filename, n), line)
def test_set_trace_without_stop(self): """ Asserts that calling set_trace with stop=False will start tracing but not stop. WARNING: This test relies on the relative line numbers inside the test. """ cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) line_offset = 8 # The difference in the set_break call and line_3. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, ) cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace(stop=False) # Should not stop us here. line_1 = True line_2 = True line_3 = True # Since we are stepping, we should not hit this line. self.assertTrue(line_1) self.assertTrue(line_2) # We should have still stopped at this breakpoint if we are tracing. self.assertFalse(line_3) db.disable() db = Qdb(cmd_manager=NopCommandManager()) line_1 = False with Timeout(0.1, False): db.set_trace(stop=False) line_1 = True self.assertTrue(line_1)
def test_watchlist(self): """ Tests the watchlist by evaluating a constant, local function, local variable, global function, and global variable. """ db = Qdb(cmd_manager=NopCommandManager(), execution_timeout=1) too_long_msg = db.exception_serializer( QdbExecutionTimeout('too_long()', 1) ) db.extend_watchlist( '2 + 2', 'local_var', 'local_fn()', 'global_var', 'global_fn()', 'too_long()', ) def new_curframe(): """ Test function for checking for NameErrors on the watchlist. This changes the curframe of the tracer to eval the watchlist with a new set of locals. """ self.assertEqual(db.watchlist['2 + 2'], (None, 4)) self.assertEqual( db.watchlist['local_var'], ('NameError', "NameError: name 'local_var' is not defined") ) self.assertEqual( db.watchlist['local_fn()'], ('NameError', "NameError: name 'local_fn' is not defined") ) self.assertEqual(db.watchlist['global_var'], (None, 'global_var')) self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn')) local_var = 'local_var' # NOQA local_fn = lambda: 'local_fn' # NOQA def too_long(): while True: pass # Set trace and check innitial assertions. db.set_trace() self.assertEqual(db.watchlist['2 + 2'], (None, 4)) self.assertEqual(db.watchlist['local_var'], (None, 'local_var')) self.assertEqual(db.watchlist['local_fn()'], (None, 'local_fn')) self.assertEqual(db.watchlist['global_var'], (None, 'global_var')) self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn')) # Testing this as a tuple causes strange behavior. self.assertEqual(db.watchlist['too_long()'][0], 'QdbExecutionTimeout') self.assertEqual(db.watchlist['too_long()'][1], too_long_msg) local_var = 'updated_local_var' # NOQA local_fn = lambda: 'updated_local_fn' # NOQA self.assertEqual(db.watchlist['2 + 2'], (None, 4)) self.assertEqual(db.watchlist['local_var'], (None, 'updated_local_var')) self.assertEqual(db.watchlist['local_fn()'], (None, 'updated_local_fn')) self.assertEqual(db.watchlist['global_var'], (None, 'global_var')) self.assertEqual(db.watchlist['global_fn()'], (None, 'global_fn')) new_curframe()