def test_CS_push(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" new_cmd = """(set-name #:target (interval #:index 1 #:name "b") #:new-name "z")""" cs.push(eved.parse(new_cmd)) # push adds new_cmd to head of stack assert cs.labels[1]['name'] == "z" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" cs.undo() cs.undo() cs.push(eved.parse( new_cmd)) # TEST_OPS[1] is gone; new_cmd now at head of stack assert len(cs.undo_stack) == 2 assert cs.labels[1]['name'] == "z" assert cs.labels[2]['stop'] == 4.2 assert cs.labels[0]['name'] == "q" os.remove(tf.name)
def test_CS_delete(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) cs.create(0, 0.5, stop=0.9, name='q', tier='spam') assert len(cs.labels) == 5 assert cs.labels[0]['start'] == 0.5 assert cs.labels[0]['stop'] == 0.9 assert cs.labels[0]['name'] == 'q' assert cs.labels[0]['tier'] == 'spam' cs.delete(0) assert len(cs.undo_stack) == 2 assert len(cs.labels) == 4 assert cs.labels[0]['start'] == 1.0 assert cs.labels[0]['stop'] == 2.1 assert cs.labels[0]['name'] == 'a' cs.undo() # extra data associated with deleted item are restored assert len(cs.labels) == 5 assert cs.labels[0]['start'] == 0.5 assert cs.labels[0]['stop'] == 0.9 assert cs.labels[0]['name'] == 'q' assert cs.labels[0]['tier'] == 'spam' os.remove(tf.name)
def test_context_manager(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) # exception is passed through, and .bak file is created with pytest.raises(ZeroDivisionError): with eved.EditStack(labels=labels, ops_file=tf.name, load=True) as cs: cs.rename(3, 'eggs') x = 3 / 0 assert os.path.exists(tf.name + '.bak') # .bak file contains all operations in stack at time of exception labels = copy.deepcopy(TEST_LABELS) assert labels[3]['name'] == 'd' with eved.EditStack(labels=labels, ops_file=(tf.name + '.bak'), load=True) as cs: assert cs.labels[0]['name'] == 'q' assert cs.labels[2]['stop'] == 4.5 assert cs.labels[3]['name'] == 'eggs' # regular file doesn't contain state written to .bak file labels = copy.deepcopy(TEST_LABELS) assert labels[3]['name'] == 'd' with eved.EditStack(labels=labels, ops_file=tf.name, load=True) as cs: assert cs.labels[0]['name'] == 'q' assert cs.labels[2]['stop'] == 4.5 assert cs.labels[3]['name'] == 'd' # regular exit doesn't create .bak file tf2 = make_corr_file(tmpdir) labels = copy.deepcopy(TEST_LABELS) assert labels[3]['name'] == 'd' with eved.EditStack(labels=labels, ops_file=tf2.name, load=True) as cs: cs.rename(3, 'eggs') assert not os.path.exists(tf2.name + '.bak') # regular exit writes entire stack to regular file labels = copy.deepcopy(TEST_LABELS) assert labels[3]['name'] == 'd' with eved.EditStack(labels=labels, ops_file=tf2.name, load=True) as cs: assert cs.labels[0]['name'] == 'q' assert cs.labels[2]['stop'] == 4.5 assert cs.labels[3]['name'] == 'eggs' os.remove(tf.name + '.bak') os.remove(tf.name)
def test_CS_set_stop(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) cs.set_stop(0, 1.8) assert len(cs.undo_stack) == 1 assert cs.labels[0]['stop'] == 1.8 os.remove(tf.name)
def test_CS_write_to_file(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) new_cmd = """(set-name #:target (interval #:index 1 #:name "b") #:new-name "z")""" cs.push(eved.parse(new_cmd)) os.remove(tf.name) cs.write_to_file() assert os.path.exists(cs.file) assert os.path.exists(cs.file + '.yaml') labels = copy.deepcopy(TEST_LABELS) cs_new = eved.EditStack(labels=labels, ops_file=tf.name, load=True) assert len(cs_new.undo_stack) == 3 assert cs_new.undo_stack == cs.undo_stack assert cs_new.undo_stack[-1] == eved.parse(new_cmd) assert cs_new.hash_pre == cs.hash_pre os.remove(tf.name)
def test_CS_read_from_file(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) cs.read_from_file(tf.name) assert cs.labels[0]['name'] == 'q' assert cs.labels[2]['stop'] == 4.5 assert list(cs.undo_stack) == [eved.parse(op) for op in TEST_OPS] os.remove(tf.name)
def test_CS_init(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) assert cs.labels == TEST_LABELS assert cs.file == tf.name assert len(cs.undo_stack) == 0 cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) assert cs.file == tf.name assert len(cs.undo_stack) == 2 assert cs.undo_stack[0] == eved.parse(TEST_OPS[0]) assert cs.undo_stack[1] == eved.parse(TEST_OPS[1]) assert cs.labels[1] == TEST_LABELS[1] assert cs.labels[3] == TEST_LABELS[3] assert cs.labels[0]['name'] == 'q' assert cs.labels[2]['stop'] == 4.5 os.remove(tf.name)
def test_CS__apply(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) new_cmd = """(set-name #:target (interval #:index 1 #:name "b") #:new-name "z")""" cs._apply(eved.parse(new_cmd)) # the stack is now in an undefined state # but we can still check that _apply performed the new_cmd operation assert cs.labels[1]['name'] == 'z' os.remove(tf.name)
def test_CS_merge_next(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) for i in range(len(labels)): labels[i]['tier'] = 'tier' + str(i) cs.merge_next(0) assert len(cs.undo_stack) == 1 assert len(cs.labels) == 3 assert cs.labels[0]['start'] == 1.0 assert cs.labels[0]['stop'] == 3.5 assert cs.labels[0]['name'] == 'a' assert cs.labels[0]['tier'] == 'tier0' assert cs.labels[1]['tier'] == 'tier2' # merge saves all column info, for restoration on undo cs.undo() assert cs.labels[0]['start'] == 1.0 assert cs.labels[0]['stop'] == 2.1 assert cs.labels[0]['name'] == 'a' assert cs.labels[0]['tier'] == 'tier0' assert cs.labels[1]['start'] == 2.1 assert cs.labels[1]['stop'] == 3.5 assert cs.labels[1]['name'] == 'b' assert cs.labels[1]['tier'] == 'tier1' cs.merge_next(0) assert len(cs.labels) == 3 assert cs.labels[0]['name'] == 'a' # can merge two intervals that don't share a boundary, # and their respective stop/start will be preserved after undo cs.merge_next(1) assert len(cs.labels) == 2 assert cs.labels[1]['start'] == 3.5 assert cs.labels[1]['stop'] == 5.0 assert cs.labels[1]['name'] == 'c' assert cs.labels[1]['tier'] == 'tier2' cs.undo() assert len(cs.labels) == 3 assert cs.labels[1]['start'] == 3.5 assert cs.labels[1]['stop'] == 4.2 assert cs.labels[1]['name'] == 'c' assert cs.labels[1]['tier'] == 'tier2' assert cs.labels[2]['start'] == 4.7 assert cs.labels[2]['stop'] == 5.0 assert cs.labels[2]['name'] == 'd' assert cs.labels[2]['tier'] == 'tier3' os.remove(tf.name)
def test_CS_rename(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) with pytest.raises(ValueError): cs.rename(0, '"cannot use double-quotes"') cs.rename(0, 'q') assert len(cs.undo_stack) == 1 assert cs.labels[0]['name'] == 'q' os.remove(tf.name)
def test_CS_create(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) cs.create(0, 0.5, stop=0.9, name='q', tier='spam') assert len(cs.undo_stack) == 1 assert len(cs.labels) == 5 assert cs.labels[0]['start'] == 0.5 assert cs.labels[0]['stop'] == 0.9 assert cs.labels[0]['name'] == 'q' assert cs.labels[0]['tier'] == 'spam' assert cs.labels[1] == TEST_LABELS[0] os.remove(tf.name)
def test_CS_split(): labels = copy.deepcopy(TEST_LABELS) tf = tempfile.NamedTemporaryFile(delete=False) tf.close() cs = eved.EditStack(labels=labels, ops_file=tf.name, load=False) cs.split(0, 1.8) assert len(cs.undo_stack) == 1 assert len(cs.labels) == 5 assert cs.labels[0]['start'] == 1.0 assert cs.labels[0]['stop'] == 1.8 assert cs.labels[0]['name'] == 'a' assert cs.labels[1]['start'] == 1.8 assert cs.labels[1]['stop'] == 2.1 assert cs.labels[1]['name'] == 'a' os.remove(tf.name)
def test_CS_peek(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) p = cs.peek() # default: show op at top of undo_stack assert p == eved.parse(TEST_OPS[1]) with pytest.raises(IndexError): p = cs.peek(len(cs.undo_stack) + 10) with pytest.raises(IndexError): p = cs.peek(-10) p = cs.peek(0) assert p == eved.parse(TEST_OPS[0]) os.remove(tf.name)
def test_CS_undo_and_redo(tmpdir): labels = copy.deepcopy(TEST_LABELS) tf = make_corr_file(tmpdir) cs = eved.EditStack(labels=labels, ops_file=tf.name, load=True) new_cmd = """(set-name #:target (interval #:index 1 #:name "b") #:new-name "z")""" cs.push(eved.parse(new_cmd)) assert len(cs.undo_stack) == 3 assert len(cs.redo_stack) == 0 assert cs.labels[1]['name'] == "z" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" cs.undo() # undo new_cmd assert len(cs.undo_stack) == 2 assert len(cs.redo_stack) == 1 assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" cs.undo() # undo TEST_OPS[1] assert len(cs.undo_stack) == 1 assert len(cs.redo_stack) == 2 assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.2 assert cs.labels[0]['name'] == "q" cs.undo() # undo TEST_OPS[0] assert len(cs.undo_stack) == 0 assert len(cs.redo_stack) == 3 assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.2 assert cs.labels[0]['name'] == "a" # undo on an empty undo_stack raises exception with pytest.raises(IndexError): cs.undo() cs.redo() # redo TEST_OPS[0] assert len(cs.undo_stack) == 1 assert len(cs.redo_stack) == 2 assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.2 assert cs.labels[0]['name'] == "q" cs.redo() # redo TEST_OPS[1] assert len(cs.undo_stack) == 2 assert len(cs.redo_stack) == 1 assert cs.labels[1]['name'] == "b" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" cs.redo() # redo new_cmd assert len(cs.undo_stack) == 3 assert len(cs.redo_stack) == 0 assert cs.labels[1]['name'] == "z" assert cs.labels[2]['stop'] == 4.5 assert cs.labels[0]['name'] == "q" # redo on an empty redo_stack raises exception with pytest.raises(IndexError): cs.redo() os.remove(tf.name)