def test_worksheet_2() : #-------------------------------------------------------------------------------------- from test_utils import adjust_environment global_settings = adjust_environment() import os examplesdir = global_settings.examples_dir filename = os.path.join(examplesdir, 'imshow.rws').decode('UTF-8') #-------------------------------------------------------------------------------------- from reinteract.notebook import Notebook from reinteract.worksheet import Worksheet worksheet = Worksheet( Notebook() ) worksheet.load(filename) worksheet.calculate(wait=True) custom_results = [] from reinteract.chunks import StatementChunk from reinteract.custom_result import CustomResult for x in worksheet.iterate_chunks() : if not isinstance(x,StatementChunk) : continue if len(x.results) == 0 : continue arg = x.results[0] if isinstance(arg, CustomResult): custom_results.append(arg) pass pass assert len(custom_results) == 2 #-------------------------------------------------------------------------------------- pass
def test_worksheet_0() : #-------------------------------------------------------------------------------------- from test_utils import adjust_environment adjust_environment() from reinteract.chunks import StatementChunk, BlankChunk, CommentChunk from reinteract.notebook import Notebook, NotebookFile from reinteract.worksheet import Worksheet, _debug S = StatementChunk B = BlankChunk C = CommentChunk #-------------------------------------------------------------------------------------- def compare(l1, l2): if len(l1) != len(l2): return False for i in xrange(0, len(l1)): e1 = l1[i] e2 = l2[i] if type(e1) != type(e2) or e1.start != e2.start or e1.end != e2.end: return False return True #-------------------------------------------------------------------------------------- worksheet = Worksheet(Notebook()) #-------------------------------------------------------------------------------------- def expect(expected): chunks = [ x for x in worksheet.iterate_chunks() ] if not compare(chunks, expected): raise AssertionError("\nGot:\n %s\nExpected:\n %s" % (chunks, expected)) #-------------------------------------------------------------------------------------- def expect_text(expected, start_line=0, start_offset=0, end_line=-1, end_offset=-1): text = worksheet.get_text(start_line, start_offset, end_line, end_offset) if (text != expected): raise AssertionError("\nGot:\n '%s'\nExpected:\n '%s'" % (text, expected)) #-------------------------------------------------------------------------------------- def expect_doctests(expected, start_line, end_line): text = worksheet.get_doctests(start_line, end_line) if (text != expected): raise AssertionError("\nGot:\n '%s'\nExpected:\n '%s'" % (text, expected)) #-------------------------------------------------------------------------------------- def expect_results(expected): results = [ (x.results if isinstance(x,StatementChunk) else None) for x in worksheet.iterate_chunks() ] if (results != expected): raise AssertionError("\nGot:\n '%s'\nExpected:\n '%s'" % (results, expected)) #-------------------------------------------------------------------------------------- def insert(line, offset, text): worksheet.insert(line, offset, text) #-------------------------------------------------------------------------------------- def delete(start_line, start_offset, end_line, end_offset): worksheet.delete_range(start_line, start_offset, end_line, end_offset) #-------------------------------------------------------------------------------------- def calculate(): worksheet.calculate(wait=True) #-------------------------------------------------------------------------------------- def clear(): worksheet.clear() #-------------------------------------------------------------------------------------- def chunk_label(chunk): if chunk.end - chunk.start == 1: return "[%s]" % chunk.start else: return "[%s:%s]" % (chunk.start, chunk.end) #-------------------------------------------------------------------------------------- class CI: def __init__(self, start, end): self.start = start self.end = end def __eq__(self, other): if not isinstance(other, CI): return False return self.start == other.start and self.end == other.end def __repr__(self): return "CI(%s, %s)" % (self.start, self.end) #-------------------------------------------------------------------------------------- class CC: def __init__(self, start, end, changed_lines): self.start = start self.end = end self.changed_lines = changed_lines def __eq__(self, other): if not isinstance(other, CC): return False return self.start == other.start and self.end == other.end and self.changed_lines == other.changed_lines def __repr__(self): return "CC(%s, %s, %s)" % (self.start, self.end, self.changed_lines) #-------------------------------------------------------------------------------------- class CD: def __eq__(self, other): if not isinstance(other, CD): return False return True def __repr__(self): return "CD()" #-------------------------------------------------------------------------------------- class CSC: def __init__(self, start, end): self.start = start self.end = end def __eq__(self, other): if not isinstance(other, CSC): return False return self.start == other.start and self.end == other.end def __repr__(self): return "CSC(%s, %s)" % (self.start, self.end) #-------------------------------------------------------------------------------------- class CRC: def __init__(self, start, end): self.start = start self.end = end def __eq__(self, other): if not isinstance(other, CRC): return False return self.start == other.start and self.end == other.end def __repr__(self): return "CRC(%s, %s)" % (self.start, self.end) pass #-------------------------------------------------------------------------------------- class Logger : def __init__( self ) : self._log = [] pass def on_chunk_inserted( self, worksheet, chunk ) : _debug("...Chunk %s inserted", chunk_label(chunk)) self._log.append(CI(chunk.start, chunk.end)) pass def on_chunk_changed( self, worksheet, chunk, changed_lines ) : _debug("...Chunk %s changed", chunk_label(chunk)) self._log.append(CC(chunk.start, chunk.end, changed_lines)) pass def on_chunk_deleted( self, worksheet, chunk ) : _debug("...Chunk %s deleted", chunk_label(chunk)) self._log.append(CD()) pass def on_chunk_status_changed( self, worksheet, chunk ) : _debug("...Chunk %s status changed", chunk_label(chunk)) self._log.append(CSC(chunk.start, chunk.end)) pass def on_chunk_results_changed( self, worksheet, chunk ) : _debug("...Chunk %s results changed", chunk_label(chunk)) self._log.append(CRC(chunk.start, chunk.end)) pass def clear_log( self ) : self._log = [] pass def expect_log( self, expected ) : if self._log != expected: raise AssertionError("\nGot:\n '%s'\nExpected:\n '%s'" % (log, expected)) self.clear_log() pass pass #-------------------------------------------------------------------------------------- a_logger = Logger() worksheet.sig_chunk_inserted.connect( a_logger.on_chunk_inserted ) worksheet.sig_chunk_changed.connect( a_logger.on_chunk_changed ) worksheet.sig_chunk_deleted.connect( a_logger.on_chunk_deleted ) worksheet.sig_chunk_status_changed.connect( a_logger.on_chunk_status_changed ) worksheet.sig_chunk_results_changed.connect( a_logger.on_chunk_results_changed ) # Insertions insert(0, 0, "11\n22\n33") expect_text("11\n22\n33") expect([S(0,1), S(1,2), S(2,3)]) insert(0, 1, "a") expect_text("1a1\n22\n33") expect([S(0,1), S(1,2), S(2,3)]) insert(1, 1, "a\na") expect_text("1a1\n2a\na2\n33") expect([S(0,1), S(1,2), S(2,3), S(3,4)]) insert(1, 0, "bb\n") expect_text("1a1\nbb\n2a\na2\n33") expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)]) insert(4, 3, "\n") expect_text("1a1\nbb\n2a\na2\n33\n") expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5), B(5, 6)]) # Deletions delete(4, 3, 5, 0) expect_text("1a1\nbb\n2a\na2\n33") expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)]) delete(0, 1, 0, 2) expect_text("11\nbb\n2a\na2\n33") expect([S(0,1), S(1,2), S(2,3), S(3,4), S(4, 5)]) delete(0, 0, 1, 0) expect_text("bb\n2a\na2\n33") expect([S(0,1), S(1,2), S(2,3), S(3,4)]) delete(1, 1, 2, 1) expect_text("bb\n22\n33") expect([S(0,1), S(1,2), S(2,3)]) delete(2, 1, 1, 0) expect_text("bb\n3") expect([S(0,1), S(1,2)]) # Test deleting part of a BlankChunk clear() insert(0, 0, "if True\n: pass\n \n") delete(2, 4, 3, 0) # Check that tracking of changes works properly when there # is an insertion or deletion before the change clear() insert(0, 0, "1\n2") worksheet.begin_user_action() insert(1, 0, "#") insert(0, 0, "0\n") worksheet.end_user_action() expect_text("0\n1\n#2") expect([S(0,1), S(1,2), C(2,3)]) worksheet.begin_user_action() delete(2, 0, 2, 1) delete(0, 0, 1, 0) worksheet.end_user_action() expect([S(0,1), S(1,2)]) # Basic tokenization of valid python clear() insert(0, 0, "1\n\n#2\ndef a():\n 3") expect([S(0,1), B(1,2), C(2,3), S(3,5)]) clear() expect([B(0,1)]) # Multiple consecutive blank lines clear() insert(0, 0, "1") insert(0, 1, "\n") expect([S(0,1),B(1,2)]) insert(1, 0, "\n") expect([S(0,1),B(1,3)]) # Continuation lines at the beginning clear() insert(0, 0, "# Something\n pass") expect([C(0,1), S(1,2)]) delete(0, 0, 1, 0) expect([S(0,1)]) # Decorators clear() insert(0, 0, "def foo():\n return 42") expect([S(0,2)]) insert(0, 0, "@decorated\n") expect([S(0,3)]) insert(0, 0, "@decorated\n") expect([S(0,4)]) # decorator in the middle breaks things up insert(3, 0, "@decorated\n") expect([S(0,3), S(3,5)]) delete(3, 0, 4, 0) expect([S(0,4)]) # lonely decorator at the end of a worksheet clear() insert(0, 0, "@decorated\n# some comment\n") expect([S(0,1), C(1,2), B(2,3)]) insert(2, 0, "def foo():\n return 42") expect([S(0,4)]) # Calculation clear() insert(0, 0, "1 + 1") calculate() expect_results([['2']]) clear() insert(0, 0, "print 1") calculate() expect_results([['1']]) clear() insert(0, 0, "if True:\n print 1\n print 1") calculate() expect_results([['1', '1']]) clear() insert(0, 0, "a = 1\nb = 2\na + b") calculate() expect_results([[], [], ['3']]) delete(1, 4, 1, 5) insert(1, 4, "3") calculate() expect_results([[], [], ['4']]) #-------------------------------------------------------------------------------------- # # Test out signals and expect_log() # clear() a_logger.clear_log() insert(0, 0, "1 + 1") a_logger.expect_log([CD(), CI(0,1)]) calculate() a_logger.expect_log([CSC(0,1), CRC(0,1)]) insert(0, 0, "#") a_logger.expect_log([CD(), CI(0,1)]) # Deleting a chunk with results clear() insert(0, 0, "1\n2") calculate() expect([S(0,1),S(1,2)]) expect_results([['1'],['2']]) a_logger.clear_log() delete(0, 0, 0, 1) expect([B(0,1),S(1,2)]) a_logger.expect_log([CD(), CI(0,1), CSC(1,2)]) # change a statement into a comment clear() insert(0, 0, "# a\nb") a_logger.clear_log() insert(1, 0, "#") expect([C(0,2)]) a_logger.expect_log([CD(), CC(0,2,[1])]) # Turning a statement into a continuation line clear() insert(0, 0, "1 \\\n+ 2\n") a_logger.clear_log() insert(1, 0, " ") expect([S(0,2), B(2,3)]) a_logger.expect_log([CD(), CC(0,2,[1])]) # And back delete(1, 0, 1, 1) expect([S(0,1), S(1,2), B(2,3)]) a_logger.expect_log([CC(0,1,[]),CI(1,2)]) # Shortening the last chunk in the buffer clear() insert(0, 0, "def a():\n x = 1\n return 1") delete(1, 0, 2, 0) expect([S(0, 2)]) # Inserting a statement above a continuation line at the start of the buffer clear() insert(0, 0, "#def a(x):\n return x") delete(0, 0, 0, 1) expect([S(0,2)]) # Deleting an entire continuation line clear() insert(0, 0, "for i in (1,2):\n print i\n print i + 1\n") expect([S(0,3), B(3,4)]) delete(1, 0, 2, 0) expect([S(0,2), B(2,3)]) # Editing a continuation line, while leaving it a continuation clear() insert(0, 0, "1\\\n + 2\\\n + 3") delete(1, 0, 1, 1) expect([S(0,3)]) # Test that changes that substitute text with identical # text counts as changes # New text clear() insert(0, 0, "if") a_logger.clear_log() worksheet.begin_user_action() delete(0, 1, 0, 2) insert(0, 1, "f") worksheet.end_user_action() expect([S(0,1)]) a_logger.expect_log([CC(0,1,[0])]) # Text from elsewhere in the buffer clear() insert(0, 0, "if\nif") a_logger.clear_log() delete(0, 1, 1, 1) expect([S(0,1)]) a_logger.expect_log([CD(), CC(0,1,[0])]) # Test that commenting out a line marks subsequent lines for recalculation clear() insert(0, 0, "a = 1\na = 2\na") calculate() insert(1, 0, "#") assert worksheet.get_chunk(2).needs_execute # Test that we don't send out '::sig_chunk_deleted' signal for chunks for # which we never sent a '::sig_chunk_inserted' signal clear() insert(0, 0, "[1]") a_logger.clear_log() worksheet.begin_user_action() insert(0, 2, "\n") worksheet.rescan() insert(1, 0, " ") worksheet.end_user_action() a_logger.expect_log([CC(0,2,[0,1])]) # # Undo tests # clear() insert(0, 0, "1") worksheet.undo() expect_text("") worksheet.redo() expect_text("1") # Undoing insertion of a newline clear() insert(0, 0, "1 ") insert(0, 1, "\n") calculate() worksheet.undo() expect_text("1 ") # Test the "pruning" behavior of modifications after undos clear() insert(0, 0, "1") worksheet.undo() expect_text("") insert(0, 0, "2") worksheet.redo() # does nothing expect_text("2") insert(0, 0, "2\n") # Test coalescing consecutive inserts clear() insert(0, 0, "1") insert(0, 1, "2") worksheet.undo() expect_text("") # Test grouping of multiple undos by user actions clear() insert(0, 0, "1") worksheet.begin_user_action() delete(0, 0, 0, 1) insert(0, 0, "2") worksheet.end_user_action() worksheet.undo() expect_text("1") worksheet.redo() expect_text("2") # Make sure that coalescing doesn't coalesce one user action with # only part of another clear() insert(0, 0, "1") worksheet.begin_user_action() insert(0, 1, "2") delete(0, 0, 0, 1) worksheet.end_user_action() worksheet.undo() expect_text("1") worksheet.redo() expect_text("2") # # Tests of get_text() # clear() insert(0, 0, "12\n34\n56") expect_text("12\n34\n56", -1, -1, 0, 0) expect_text("2\n34\n5", 0, 1, 2, 1) expect_text("", -1, -1, -1, -1) expect_text("1", 0, 0, 0, 1) expect_text("2\n3", 0, 1, 1, 1) expect_text("2\n3", 1, 1, 0, 1) # # Tests of get_doctests() # clear() insert(0, 0, """# A tests of doctests def a(x): return x + 1 a(2) """) calculate() expect_doctests("""# A tests of doctests >>> def a(x): ... return x + 1 >>> a(2) 3 """, 0, 5) expect_doctests(""">>> def a(x): ... return x + 1 """, 2, 2) # # Try writing to a file, and reading it back # import tempfile, os clear() expect([B(0,1)]) SAVE_TEST = """a = 1 a # A comment b = 2""" insert(0, 0, SAVE_TEST) calculate() handle, fname = tempfile.mkstemp(u".rws", u"reinteract_worksheet") os.close(handle) try: worksheet.save(fname) f = open(fname, "r") saved = f.read() f.close() if saved != SAVE_TEST: raise AssertionError("Got '%s', expected '%s'", saved, SAVE_TEST) worksheet.load(fname) calculate() expect_text(SAVE_TEST) expect([S(0,1), S(1,2), C(2,3), B(3,4), S(4,5)]) expect_results([[], ['1'], None, None, []]) finally: os.remove(fname) clear() expect([B(0,1)]) pass