def remove_instruction(self, index): """Remove an instruction from the instructions list. Parameters ---------- index : int Index at which the instruction to remove is located. """ instruction = self.instructions.pop(index) # Cleanup database db_entries = self.database_entries.copy() for k in db_entries: if k in instruction.database_entries: del db_entries[k] self.database_entries = db_entries instruction.unobserve('database_entries', self._react_to_instr_database_entries_change) # Update preferences self.register_preferences() change = ContainerChange(obj=self, name='instructions', removed=[(index, instruction)]) self.instruction_changed(change)
def move_instruction(self, old, new): """Move an instruction. Parameters ---------- old : int Index at which the instruction to move is currently located. new : BaseTask Index at which to insert the instruction. """ instruction = self.instructions.pop(old) self.instructions.insert(new, instruction) # In the absence of a root task do nothing else than moving the # child. if self.has_root: # Register anew preferences to keep the right ordering for the # children self.register_preferences() change = ContainerChange(obj=self, name='instructions', moved=[(old, new, instruction)]) self.instruction_changed(change)
def add_instruction(self, instruction, index): """Add an instruction at the given index. Parameters ---------- index : int Index at which to insert the new child task. instruction : BaseInstruction Instruction to insert in the list of instructions. """ self.instructions.insert(index, instruction) # In the absence of a root task do nothing else than inserting the # child. if self.has_root: # Register the new entries in the database db_entries = self.database_entries.copy() db_entries.update(instruction.database_entries) self.database_entries = db_entries instruction.observe('database_entries', self._react_to_instr_database_entries_change) # Register anew preferences to keep the right ordering for the # instructions self.register_preferences() change = ContainerChange(obj=self, name='instructions', added=[(index, instruction)]) self.instruction_changed(change)
def remove_child_item(self, index): """Remove a child item from the items list. Parameters ---------- index : int Index at which the child to remove is located. """ child = self.items.pop(index) with child.suppress_notifications(): child.root = None child.parent = None child.index = 0 if self.has_root: child.unobserve('linkable_vars', self.root._update_global_vars) if isinstance(child, BaseSequence): child.unobserve('_last_index', self._item_last_index_updated) self._recompute_indexes() notification = ContainerChange(obj=self, name='items', removed=[(index, child)]) self.items_changed(notification)
def add_child_item(self, index, child): """Add a child item at the given index. Parameters ---------- index : int Index at which to insert the new child item. child : Item Item to insert in the list of items. """ self.items.insert(index, child) child.parent = self # In the absence of a root item do nothing else than inserting the # child. if self.has_root: # Give him its root so that it can proceed to any child # registration it needs to. child.root = self.root #: If we update linkable vars on this item then we need to inform #: the root of this. child.observe('linkable_vars', self.root._update_global_vars) if isinstance(child, BaseSequence): child.observe('_last_index', self._item_last_index_updated) self._recompute_indexes() #: Wrap it up and notify the rest of the world, if it is listening. notification = ContainerChange(obj=self, name='items', added=[(index, child)]) self.items_changed(notification)
def test_node_sorting(task): """Test that a node model correctly order its children and react to task re-ordering. """ ed = EditorModel(root=task) nmodel = ed.nodes['root'] task.add_child_task(0, ComplexTask(name='cc')) nmodel.sort_nodes() assert [c.task.name for c in nmodel.children] == ['cc', 'comp1'] assert sorted(nmodel.entries) == sorted( ['default_path', 'simp1_t', 'comp1_t1', 'comp1_t2']) task.move_child_task(0, 2) assert [c.task.name for c in nmodel.children] == ['comp1', 'cc'] assert (sorted(nmodel.children[0].entries) == sorted( ['simp2_t', 'comp2_t1', 'comp2_t2'])) change = ContainerChange(collapsed=[ContainerChange()]) nmodel._react_to_task_children_event(change) # For coverage
def test_model_observe_child_adding_removing(task): """Test that adding removing a child does trigger the expected behavior. """ model = ExecutionEditorModel(root=task) assert model.pools == ['test'] c = ComplexTask(name='comp2', parallel={ 'activated': True, 'pool': 'test2' }) task.add_child_task(2, c) assert 'test2' in model.pools c.add_child_task( 0, SimpleTask(name='simp3', parallel={ 'activated': True, 'pool': 'test3' })) assert 'test3' in model.pools task.move_child_task(2, 0) assert sorted(model.pools) == sorted(['test', 'test2', 'test3']) task.remove_child_task(0) assert model.pools == ['test'] model.root = None task.children[0].parallel = {'activated': True, 'pool': 'test2'} assert 'test2' not in model.pools # For coverage notification = ContainerChange(collapsed=[ContainerChange()]) model._child_notifier_observer(notification)
def move_child_item(self, old, new): """Move a child item. Parameters ---------- old : int Index at which the child to move is currently located. new : Item Index at which to insert the child item. """ child = self.items.pop(old) self.items.insert(new, child) if self.has_root: self._recompute_indexes() notification = ContainerChange(obj=self, name='items', moved=[(old, new, child)]) self.items_changed(notification)
def setup(self): self.obj = object() self.name = 'name' self.container = ContainerChange(obj=self.obj, name=self.name)
class TestContainerChange(object): """Test the ContainerChange capabilities. """ def setup(self): self.obj = object() self.name = 'name' self.container = ContainerChange(obj=self.obj, name=self.name) def test_adding_moved(self): self.container.add_operation('moved', (1, 2, 'test')) assert (1, 2, 'test') in self.container.moved assert not self.container.added assert not self.container.removed assert not self.container.collapsed def test_adding_added(self): self.container.add_operation('added', (1, 'test')) assert (1, 'test') in self.container.added assert not self.container.moved assert not self.container.removed assert not self.container.collapsed def test_adding_removed(self): self.container.add_operation('removed', (1, 'test')) assert (1, 'test') in self.container.removed assert not self.container.added assert not self.container.moved assert not self.container.collapsed def test_adding_wrong_typ(self): with raises(ValueError): self.container.add_operation('test', (1, 'test')) def test_adding_wrong_desc(self): with raises(ValueError): self.container.add_operation('added', ('test')) with raises(ValueError): self.container.add_operation('moved', ('test')) with raises(ValueError): self.container.add_operation('removed', ('test')) def test_collapsing(self): self.container.add_operation('moved', (1, 2, 'test')) self.container.add_operation('added', (1, 'test')) self.container.add_operation('added', (2, 'aux')) assert self.container.collapsed assert not self.container.added assert not self.container.moved assert not self.container.removed assert len(self.container.collapsed) == 2 assert len(self.container.collapsed[0].moved) == 1 assert len(self.container.collapsed[1].added) == 2 for c in self.container.collapsed: assert c.obj == self.obj assert c.name == self.name