Beispiel #1
0
 def setUp(self):
     self.history = ChangeHistory()
     self.ls = LiveList()
     self.history.track(self.ls)
     self.prevxs = None
     self.newxs = None
     self.ls.changeListener = self._onChanged
    def test_ExprField_changeHistory(self):
        d = self.ExprFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(d)

        self.assertIs(ChangeHistory.getChangeHistoryFor(d), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(d.x.expr), self.ch)
Beispiel #3
0
    def __init__(self, world, contents):
        self._world = world
        self._contents = contents

        self._changeHistory = ChangeHistory()
        self._changeHistory.track(self._contents)
        self._changeHistory.addChangeHistoryListener(self)

        self._docName = ''
        self._subject = None

        self._bHasUnsavedData = True
        self._filename = None
        self._saveTime = None

        self._documentModules = {}
    def test_TypedField_changeHistory(self):
        a = self.TypedFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(a)

        self.assertIs(ChangeHistory.getChangeHistoryFor(a), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        a.x.value = 10
        a.y.value = 20

        self.assertEqual(10, a.x.value)
        self.assertEqual(20, a.y.value)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10, a.x.value)
        self.assertEqual(1, a.y.value)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(0, a.x.value)
        self.assertEqual(1, a.y.value)
        self.assertEqual(0, self.ch.getNumUndoChanges())
    def test_ListField_changeHistory(self):
        a = self.ListFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(a)

        self.assertIs(ChangeHistory.getChangeHistoryFor(a), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        a.x.value.append(10)
        a.x.value.append(20)

        self.assertEqual([10, 20], a.x.value)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual([10], a.x.value)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual([], a.x.value)
        self.assertEqual(0, self.ch.getNumUndoChanges())
Beispiel #6
0
    def reload(self):
        # Shut down
        self.shutdown()

        # Reload
        if self._filename is None:
            raise ValueError, 'Cannot reload document - no filename'
        f = open(self._filename, 'rU')
        documentRoot = IsolationPickle.load(f)
        f.close()

        # New contents
        self._contents = documentRoot

        self._changeHistory.removeChangeHistoryListener(self)

        # New change history
        self._changeHistory = ChangeHistory()
        self._changeHistory.track(self._contents)
        self._changeHistory.addChangeHistoryListener(self)
    def test_ChildField_changeHistory(self):
        b = self.ChildFieldTest()
        a1 = self.TypedFieldTest()
        a2 = self.TypedFieldTest()
        a3 = self.TypedFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(b)

        self.assertIs(ChangeHistory.getChangeHistoryFor(b), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a1), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a2), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a3), None)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        b.p.node = a1
        b.q.nodes.append(a2)

        self.assertIs(ChangeHistory.getChangeHistoryFor(b), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a1), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a2), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a3), None)

        self.assertIs(a1, b.p.node)
        self.assertEqual([a2], b.q.nodes[:])
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertIs(a1, b.p.node)
        self.assertEqual([], b.q.nodes[:])
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertIs(None, b.p.node)
        self.assertEqual([], b.q.nodes[:])
        self.assertEqual(0, self.ch.getNumUndoChanges())
	def setUp(self):
		self.history = ChangeHistory()
		self.s = _Sequence()
		self.history.track( self.s )
class Test_TrackedList (unittest.TestCase):
	def setUp(self):
		self.history = ChangeHistory()
		self.s = _Sequence()
		self.history.track( self.s )
	
	def tearDown(self):
		self.history.stopTracking( self.s )
		self.s = None
		self.history = None
	
	
	def test_setitem(self):
		self.assertEqual( self.s.xs[:], [] )
		
		_two = _Value( -2 )
		self.s.xs.append( _two )
		self.assertEqual( self.s.xs[:], [ _two ] )
		self.assertTrue( _two.isTracked() )
		
		_one = _Value( -1 )
		self.s.xs[0] = _one
		self.assertEqual( self.s.xs[:], [ _one ] )
		self.assertFalse( _two.isTracked() )
		self.assertTrue( _one.isTracked() )
		
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]
		self.s.xs[1:] = _rng
		self.assertEqual( self.s.xs[:], [ _one ] + _rng )
		self.assertFalse( _two.isTracked() )
		self.assertTrue( _one.isTracked() )
		for x in _rng:
			self.assertTrue( x.isTracked() )
		
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], [ _one ] )
		self.assertFalse( _two.isTracked() )
		self.assertTrue( _one.isTracked() )
		for x in _rng:
			self.assertFalse( x.isTracked() )
		
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], [ _two ] )
		self.assertFalse( _one.isTracked() )
		self.assertTrue( _two.isTracked() )
		
		
		self.history.redo()
		self.assertEqual( self.s.xs[:], [ _one ] )
		self.assertFalse( _two.isTracked() )
		self.assertTrue( _one.isTracked() )
		for x in _rng:
			self.assertFalse( x.isTracked() )

			
		self.history.redo()
		self.assertEqual( self.s.xs[:], [ _one ] + _rng )
		self.assertFalse( _two.isTracked() )
		self.assertTrue( _one.isTracked() )
		for x in _rng:
			self.assertTrue( x.isTracked() )
		
			
			
		
	def test_delitem(self):
		self.assertEqual( self.s.xs[:], [] )
		
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]
		self.s.xs[:] = _rng
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		
		
		del self.s.xs[0]
		self.assertEqual( self.s.xs[:], _rng[1:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, True, True, True, True ] )

		
		del self.s.xs[1:3]
		self.assertEqual( self.s.xs[:], [ _rng[1], _rng[4] ] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, True, False, False, True ] )
		
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng[1:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, True, True, True, True ] )

		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		
		
		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng[1:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, True, True, True, True ] )
		
		
		self.history.redo()
		self.assertEqual( self.s.xs[:], [ _rng[1], _rng[4] ] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, True, False, False, True ] )
			
			
		
	def test_append(self):
		self.assertEqual( self.s.xs[:], [] )
		
		v = _Value( 2 )
		self.s.xs.append( v )
		self.assertTrue( v.isTracked() )
		
		self.assertEqual( self.s.xs[:], [ _Value( 2 ) ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], [] )
		self.assertFalse( v.isTracked() )

		self.history.redo()
		self.assertEqual( self.s.xs[:], [ _Value( 2 ) ] )
		self.assertTrue( v.isTracked() )
			
			
		
	def test_extend(self):
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]
		self.assertEqual( self.s.xs[:], [] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, False, False, False, False ] )
		
		self.s.xs.extend( _rng )
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], [] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ False, False, False, False, False ] )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		                 
	

	def test_insert(self):
		v = _Value( 20 )
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]

		self.s.xs[:] = _rng
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		self.assertFalse( v.isTracked() )

		self.s.xs.insert( 2, v )
		self.assertEqual( self.s.xs[:], _rng[:2] + [ v ] + _rng[2:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		self.assertTrue( v.isTracked() )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		self.assertFalse( v.isTracked() )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng[:2] + [ v ] + _rng[2:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		self.assertTrue( v.isTracked() )
		                 
	

	def test_pop(self):
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]

		self.s.xs[:] = _rng
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		v = self.s.xs.pop()
		self.assertTrue( v is _rng[-1] )
		self.assertEqual( self.s.xs[:], _rng[:-1] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, False ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng[:-1] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, False ] )
		                 
	

	def test_remove(self):
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]

		self.s.xs[:] = _rng
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.s.xs.remove( _Value( 2 ) )
		self.assertEqual( self.s.xs[:], _rng[:2] + _rng[3:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, False, True, True ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng[:2] + _rng[3:] )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, False, True, True ] )
		                 
	

	def test_reverse(self):
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]
		_rev = _rng[:]
		_rev.reverse()

		self.s.xs[:] = _rng
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.s.xs.reverse()
		self.assertEqual( self.s.xs[:], _rev )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rev )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		                 
	

	def test_sort(self):
		_rng = [ _Value( x )   for x in xrange( 0, 5 ) ]
		
		_shuf = _rng[:]
		r = random.Random( 12345 )
		r.shuffle( _shuf )

		self.s.xs[:] = _shuf
		self.assertEqual( self.s.xs[:], _shuf )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.s.xs.sort()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
		
		self.history.undo()
		self.assertEqual( self.s.xs[:], _shuf )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )

		self.history.redo()
		self.assertEqual( self.s.xs[:], _rng )
		self.assertEqual( [ x.isTracked() for x in _rng ],  [ True, True, True, True, True ] )
			
			
		
		
Beispiel #10
0
class Document(ChangeHistoryListener):
    def __init__(self, world, contents):
        self._world = world
        self._contents = contents

        self._changeHistory = ChangeHistory()
        self._changeHistory.track(self._contents)
        self._changeHistory.addChangeHistoryListener(self)

        self._docName = ''
        self._subject = None

        self._bHasUnsavedData = True
        self._filename = None
        self._saveTime = None

        self._documentModules = {}

    @property
    def contents(self):
        return self._contents

    def hasUnsavedData(self):
        return self._bHasUnsavedData

    def getFilename(self):
        return self._filename

    def hasFilename(self):
        return self._filename is not None

    def getSaveTime(self):
        return self._saveTime

    def getWorld(self):
        return self._world

    def getDocumentName(self):
        return self._docName

    def setDocumentName(self, name):
        self._docName = name

    def getChangeHistory(self):
        return self._changeHistory

    def hasUnsavedData(self):
        return self._bHasUnsavedData

    def newModule(self, fullname, loader):
        mod = imp.new_module(fullname)
        LoadBuiltins.loadBuiltins(mod)
        sys.modules[fullname] = mod
        mod.__file__ = fullname
        mod.__loader__ = loader
        mod.__path__ = fullname.split('.')
        self._documentModules[fullname] = mod
        self._world.registerImportedModule(fullname)
        return mod

    def unloadImportedModules(self, moduleFullnames):
        modules = set(moduleFullnames)
        modulesToRemove = set(self._documentModules.keys()) & modules
        for moduleFullname in modulesToRemove:
            del sys.modules[moduleFullname]
            del self._documentModules[moduleFullname]
        self._world.unregisterImportedModules(modulesToRemove)
        return modulesToRemove

    def unloadAllImportedModules(self):
        modulesToRemove = set(self._documentModules.keys())
        for moduleFullname in modulesToRemove:
            del sys.modules[moduleFullname]
        self._documentModules = {}
        self._world.unregisterImportedModules(modulesToRemove)
        return modulesToRemove

    def shutdown(self):
        print 'Document.shutdown: WARNING (TODO): commands have not been uninstalled'
        self.unloadAllImportedModules()

    def close(self):
        self.shutdown()

    def newSubject(self, enclosingSubject, importName, title):
        path = SubjectPath(_DocumentPathEntry(self, importName, title))
        documentSubject = _DocumentSubject(enclosingSubject, path, self)
        return self.newModelSubject(self._contents, documentSubject, path,
                                    importName, title)

    def newModelSubject(self, model, enclosingSubject, path, importName,
                        title):
        return model.__new_subject__(self, enclosingSubject, path, importName,
                                     title)

    def saveAs(self, filename):
        self._setFilename(filename)
        self.save()

    def save(self):
        data = IsolationPickle.dumps(self._contents)
        f = open(self._filename, 'w')
        f.write(data)
        f.close()
        if self._bHasUnsavedData:
            self._bHasUnsavedData = False
        self._saveTime = datetime.now()

    def writeAsBytes(self):
        return IsolationPickle.dumpToBytes(self._contents)

    def writeToOutputStream(self, stream):
        IsolationPickle.dumpToOutputStream(self._contents, stream)

    def reload(self):
        # Shut down
        self.shutdown()

        # Reload
        if self._filename is None:
            raise ValueError, 'Cannot reload document - no filename'
        f = open(self._filename, 'rU')
        documentRoot = IsolationPickle.load(f)
        f.close()

        # New contents
        self._contents = documentRoot

        self._changeHistory.removeChangeHistoryListener(self)

        # New change history
        self._changeHistory = ChangeHistory()
        self._changeHistory.track(self._contents)
        self._changeHistory.addChangeHistoryListener(self)

    def _setFilename(self, filename):
        self._filename = filename
        head, documentName = os.path.split(filename)
        documentName, ext = os.path.splitext(documentName)
        self._docName = documentName

    @staticmethod
    def readFile(world, filename):
        if os.path.exists(filename):
            try:
                f = open(filename, 'rU')
                documentRoot = IsolationPickle.load(f)
                f.close()

                document = Document(world, documentRoot)
                document._setFilename(filename)
                document._saveTime = datetime.now()
                return document
            except IOError:
                return None

    @staticmethod
    def readFromBytes(world, buf, documentName):
        documentRoot = IsolationPickle.loadFromBytes(buf)

        document = Document(world, documentRoot)
        document._docName = documentName
        return document

    @staticmethod
    def readFromInputStream(world, stream, documentName):
        documentRoot = IsolationPickle.loadFromInputStream(stream)

        document = Document(world, documentRoot)
        document._docName = documentName
        return document

    def onChangeHistoryChanged(self, history):
        if not self._bHasUnsavedData:
            self._bHasUnsavedData = True
 def setUp(self):
     self.ch = ChangeHistory()
class TestCase_DataModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        class TypedFieldTest(GUINode):
            x = TypedField(int, 0)
            y = TypedField(int, 1)
            z = TypedField([int, type(None)], None)
            w = TypedField(int).defaultValueFactory(lambda: 2)

            @x.on_change
            def x_changed(self, field, old_value, new_value):
                self.x_history.append(old_value)

            def __init__(self, **values):
                self.x_history = []
                super(TypedFieldTest, self).__init__(**values)

            def __py_evalmodel__(self, codeGen):
                x = self.x.__py_evalmodel__(codeGen)
                y = self.y.__py_evalmodel__(codeGen)
                return Py.Call(target=Py.Load(name='A'), args=[x, y])

        from BritefuryJ.LSpace.Layout import HAlignment

        class ListFieldTest(GUIObject):
            x = ListField()

            @x.on_change
            def x_changed(self, field, old_contents, new_contents):
                self.history.append(old_contents)

            def __init__(self, **values):
                self.history = []
                super(ListFieldTest, self).__init__(**values)

            def __setstate__(self, state):
                self.history = []
                super(ListFieldTest, self).__setstate__(state)

        class ChildFieldTest(GUINode):
            p = ChildField()
            q = ChildListField()

            def __py_evalmodel__(self, codeGen):
                p = self.p.__py_evalmodel__(codeGen)
                q = self.q.__py_evalmodel__(codeGen)
                return Py.Call(target=Py.Load(name='B'), args=[p, q])

        class EvalFieldTest(GUIObject):
            x = TypedEvalField(float, 0.0)
            y = TypedEvalField(float, 1.0)
            z = TypedEvalField(float).defaultValueFactory(lambda: 2.0)

            def __py_evalmodel__(self, codeGen):
                x = self.x.__py_evalmodel__(codeGen)
                y = self.y.__py_evalmodel__(codeGen)
                return Py.Call(target=Py.Load(name='C'), args=[x, y])

        class ExprFieldTest(GUIObject):
            x = ExprField()

            def __py_evalmodel__(self, codeGen):
                x = self.x.__py_evalmodel__(codeGen)
                return Py.Call(target=Py.Load(name='D'), args=[x])

        cls.TypedFieldTest = TypedFieldTest
        cls.ListFieldTest = ListFieldTest
        cls.ChildFieldTest = ChildFieldTest
        cls.EvalFieldTest = EvalFieldTest
        cls.ExprFieldTest = ExprFieldTest

        test_module = imp.new_module('GUIEditor_DataModel_Tests')
        sys.modules[test_module.__name__] = test_module
        cls.mod = test_module

        def moveClassToModule(mod, x):
            setattr(mod, x.__name__, x)
            x.__module__ = mod.__name__

        moveClassToModule(test_module, TypedFieldTest)
        moveClassToModule(test_module, ListFieldTest)
        moveClassToModule(test_module, ChildFieldTest)
        moveClassToModule(test_module, EvalFieldTest)
        moveClassToModule(test_module, ExprFieldTest)

    @classmethod
    def tearDownClass(cls):
        cls.TypedFieldTest = None
        cls.ListFieldTest = None
        cls.ChildFieldTest = None
        cls.EvalFieldTest = None
        cls.ExprFieldTest = None
        del sys.modules[cls.mod.__name__]
        cls.mod = None

    def setUp(self):
        self.ch = ChangeHistory()

    def tearDown(self):
        self.ch = None

    @staticmethod
    def buildFromState(cls, state):
        instance = cls.__new__(cls)
        instance.__setstate__(state)
        return instance

    def test_TypedField_constructor(self):
        a1 = self.TypedFieldTest()

        self.assertEqual(0, a1.x.value)
        self.assertEqual(1, a1.y.value)
        self.assertEqual(None, a1.z.value)
        self.assertEqual(2, a1.w.value)

        a2 = self.TypedFieldTest(x=10, y=20)

        self.assertEqual(10, a2.x.value)
        self.assertEqual(20, a2.y.value)

        self.assertRaises(TypeError, lambda: self.TypedFieldTest(a=1, b=2))

    def test_TypedField_change_listener(self):
        a = self.TypedFieldTest()

        self.assertEqual(0, a.x.value)
        self.assertEqual(1, a.y.value)
        self.assertEqual([], a.x_history)

        a.x.value = 10
        a.y.value = 20

        self.assertEqual(10, a.x.value)
        self.assertEqual(20, a.y.value)
        self.assertEqual([0], a.x_history)

        a.x.value = 5
        a.y.value = 6

        self.assertEqual(5, a.x.value)
        self.assertEqual(6, a.y.value)
        self.assertEqual([0, 10], a.x_history)

    def test_TypedField_changeHistory(self):
        a = self.TypedFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(a)

        self.assertIs(ChangeHistory.getChangeHistoryFor(a), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        a.x.value = 10
        a.y.value = 20

        self.assertEqual(10, a.x.value)
        self.assertEqual(20, a.y.value)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10, a.x.value)
        self.assertEqual(1, a.y.value)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(0, a.x.value)
        self.assertEqual(1, a.y.value)
        self.assertEqual(0, self.ch.getNumUndoChanges())

    def test_TypedField_serialisation(self):
        a = self.TypedFieldTest(x=10, y=20)

        a_io = pickle.loads(pickle.dumps(a))

        self.assertIsNot(a, a_io)

        self.assertEqual(10, a_io.x.value)
        self.assertEqual(20, a_io.y.value)

    def test_TypedField_clipboardCopy(self):
        a = self.TypedFieldTest(x=10, y=20)

        a_io = ClipboardCopier.instance.copy(a)

        self.assertIsNot(a, a_io)

        self.assertEqual(10, a_io.x.value)
        self.assertEqual(20, a_io.y.value)

    def test_TypedField_editor(self):
        a = self.TypedFieldTest(x=10, y=20)

        codeGen = Python2CodeGenerator('test')

        self.assertEqual(10, a.x.getValueForEditor())
        self.assertEqual(20, a.y.getValueForEditor())

        self.assertEqual(
            Py.IntLiteral(format='decimal', numType='int', value='10'),
            a.x.__py_evalmodel__(codeGen))
        self.assertEqual(
            Py.IntLiteral(format='decimal', numType='int', value='20'),
            a.y.__py_evalmodel__(codeGen))

        self.assertEqual(
            Py.Call(target=Py.Load(name='A'),
                    args=[
                        Py.IntLiteral(format='decimal',
                                      numType='int',
                                      value='10'),
                        Py.IntLiteral(format='decimal',
                                      numType='int',
                                      value='20')
                    ]), a.__py_evalmodel__(codeGen))

    def test_ListField_constructor(self):
        a1 = self.ListFieldTest()
        a2 = self.ListFieldTest(x=range(5))

        self.assertEqual([], a1.x.value)
        self.assertEqual(range(5), a2.x.value)

    def test_ListField_change_listener(self):
        a1 = self.ListFieldTest()

        self.assertEqual([], a1.x.value)
        self.assertEqual([], a1.history)

        a1.x.value.append(10)

        self.assertEqual([10], a1.x.value)
        self.assertEqual([[]], a1.history)

        a1.x.value.append(20)

        self.assertEqual([10, 20], a1.x.value)
        self.assertEqual([[], [10]], a1.history)

    def test_ListField_changeHistory(self):
        a = self.ListFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(a)

        self.assertIs(ChangeHistory.getChangeHistoryFor(a), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        a.x.value.append(10)
        a.x.value.append(20)

        self.assertEqual([10, 20], a.x.value)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual([10], a.x.value)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual([], a.x.value)
        self.assertEqual(0, self.ch.getNumUndoChanges())

    def test_ListField_serialisation(self):
        a = self.ListFieldTest(x=range(5))

        a_io = pickle.loads(pickle.dumps(a))

        self.assertIsNot(a, a_io)

        self.assertEqual(range(5), a_io.x.value)

    def test_ListField_clipboardCopy(self):
        a = self.ListFieldTest(x=range(5))

        a_io = ClipboardCopier.instance.copy(a)

        self.assertIsNot(a, a_io)

        self.assertEqual(range(5), a_io.x.value)

    def test_ListField_editor(self):
        a = self.ListFieldTest(x=[1, 2])

        codeGen = Python2CodeGenerator('test')

        self.assertEqual([1, 2], a.x.getValueForEditor())

        self.fail(
            'Test imcomplete; need to implement type-coercion based converter to transform Python objects into AST nodes that construct their literal values'
        )

    def test_ChildField_constructor(self):
        b1 = self.ChildFieldTest()
        a1 = self.TypedFieldTest()
        a2 = self.TypedFieldTest()

        self.assertIs(None, b1.p.node)
        self.assertEqual([], b1.q.nodes)

        b2 = self.ChildFieldTest(p=a1, q=[a2])

        self.assertIs(a1, b2.p.node)
        self.assertEqual([a2], b2.q.nodes)

        self.assertRaises(NodeAlreadyHasParentError,
                          lambda: self.ChildFieldTest(p=a1, q=[a2]))

    def test_ChildField_parentage(self):
        a1 = self.TypedFieldTest(x=10, y=20)
        a2 = self.TypedFieldTest(x=3, y=4)
        b = self.ChildFieldTest()

        self.assertIs(None, a1.parent)
        self.assertIs(None, a2.parent)

        b.p.node = a1

        self.assertIs(b, a1.parent)
        self.assertIs(None, a2.parent)

        b.q.nodes.append(a2)

        self.assertIs(b, a1.parent)
        self.assertIs(b, a2.parent)

    def test_ChildField_changeHistory(self):
        b = self.ChildFieldTest()
        a1 = self.TypedFieldTest()
        a2 = self.TypedFieldTest()
        a3 = self.TypedFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(b)

        self.assertIs(ChangeHistory.getChangeHistoryFor(b), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a1), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a2), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a3), None)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        b.p.node = a1
        b.q.nodes.append(a2)

        self.assertIs(ChangeHistory.getChangeHistoryFor(b), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a1), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a2), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(a3), None)

        self.assertIs(a1, b.p.node)
        self.assertEqual([a2], b.q.nodes[:])
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertIs(a1, b.p.node)
        self.assertEqual([], b.q.nodes[:])
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertIs(None, b.p.node)
        self.assertEqual([], b.q.nodes[:])
        self.assertEqual(0, self.ch.getNumUndoChanges())

    def test_ChildField_serialisation(self):
        a1 = self.TypedFieldTest(x=10, y=20)
        a2 = self.TypedFieldTest(x=3, y=4)
        b = self.ChildFieldTest(p=a1, q=[a2])

        b_io = pickle.loads(pickle.dumps(b))

        self.assertIsNot(b, b_io)

        self.assertIsInstance(b_io.p.node, self.TypedFieldTest)
        self.assertIsInstance(b_io.q.nodes[0], self.TypedFieldTest)

        self.assertEqual(10, b_io.p.node.x.value)
        self.assertEqual(3, b_io.q.nodes[0].x.value)

    def test_ChildField_clipboardCopy(self):
        a1 = self.TypedFieldTest(x=10, y=20)
        a2 = self.TypedFieldTest(x=3, y=4)
        b = self.ChildFieldTest(p=a1, q=[a2])

        b_io = ClipboardCopier.instance.copy(b)

        self.assertIsNot(b, b_io)

        self.assertIsInstance(b_io.p.node, self.TypedFieldTest)
        self.assertIsInstance(b_io.q.nodes[0], self.TypedFieldTest)

        self.assertEqual(10, b_io.p.node.x.value)
        self.assertEqual(3, b_io.q.nodes[0].x.value)

    def test_ChildField_editor(self):
        a1 = self.TypedFieldTest(x=10, y=20)
        a2 = self.TypedFieldTest(x=3, y=4)
        b = self.ChildFieldTest(p=a1, q=[a2])

        codeGen = Python2CodeGenerator('test')

        self.assertEqual(a1, b.p.getValueForEditor())
        self.assertEqual([a2], b.q.getValueForEditor())

        self.assertEqual(
            Py.Call(target=Py.Load(name='B'),
                    args=[
                        Py.Call(target=Py.Load(name='A'),
                                args=[
                                    Py.IntLiteral(format='decimal',
                                                  numType='int',
                                                  value='10'),
                                    Py.IntLiteral(format='decimal',
                                                  numType='int',
                                                  value='20')
                                ]),
                        Py.ListLiteral(values=[
                            Py.Call(target=Py.Load(name='A'),
                                    args=[
                                        Py.IntLiteral(format='decimal',
                                                      numType='int',
                                                      value='3'),
                                        Py.IntLiteral(format='decimal',
                                                      numType='int',
                                                      value='4')
                                    ])
                        ])
                    ]), b.__py_evalmodel__(codeGen))

    def test_EvalField_constructor(self):
        c1 = self.EvalFieldTest()

        self.assertEqual(0.0, c1.x.constantValue)
        self.assertEqual(1.0, c1.y.constantValue)
        self.assertEqual(2.0, c1.z.constantValue)

        c2 = self.EvalFieldTest(x=10.0, y=20.0)

        self.assertEqual(10.0, c2.x.constantValue)
        self.assertEqual(20.0, c2.y.constantValue)

    def test_EvalField_changeHistory(self):
        c = self.EvalFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(c)

        self.assertIs(ChangeHistory.getChangeHistoryFor(c), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        c.x.constantValue = 10.0
        c.y.constantValue = 20.0

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        x_expr = EmbeddedPython2Expr.fromText('a+b')
        y_expr = EmbeddedPython2Expr.fromText('c+d')

        self.assertIs(ChangeHistory.getChangeHistoryFor(x_expr), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(y_expr), None)

        c.x.expr = x_expr
        c.y.expr = y_expr

        self.assertIs(ChangeHistory.getChangeHistoryFor(x_expr), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(y_expr), self.ch)

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIs(x_expr, c.x.expr)
        self.assertIs(y_expr, c.y.expr)
        self.assertEqual(4, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIs(x_expr, c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(3, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(1.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(0.0, c.x.constantValue)
        self.assertEqual(1.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(0, self.ch.getNumUndoChanges())

    def test_EvalField_serialisation(self):
        c = self.EvalFieldTest()

        c.x.constantValue = 10.0
        c.y.constantValue = 20.0
        x_expr = EmbeddedPython2Expr.fromText('a+b')
        y_expr = EmbeddedPython2Expr.fromText('c+d')
        c.x.expr = x_expr
        c.y.expr = y_expr

        c_io = pickle.loads(pickle.dumps(c))

        self.assertEqual(10.0, c_io.x.constantValue)
        self.assertEqual(20.0, c_io.y.constantValue)
        self.assertEqual(x_expr, c_io.x.expr)
        self.assertEqual(y_expr, c_io.y.expr)

    def test_EvalField_clipboardCopy(self):
        c = self.EvalFieldTest()

        c.x.constantValue = 10.0
        c.y.constantValue = 20.0
        x_expr = EmbeddedPython2Expr.fromText('a+b')
        y_expr = EmbeddedPython2Expr.fromText('c+d')
        c.x.expr = x_expr
        c.y.expr = y_expr

        c_io = ClipboardCopier.instance.copy(c)

        self.assertIsNot(c.x.expr, c_io.x.expr)
        self.assertIsNot(c.y.expr, c_io.y.expr)
        self.assertEqual(10.0, c_io.x.constantValue)
        self.assertEqual(20.0, c_io.y.constantValue)
        self.assertEqual(x_expr, c_io.x.expr)
        self.assertEqual(y_expr, c_io.y.expr)

    def test_EvalField_editor(self):
        c = self.EvalFieldTest()

        codeGen = Python2CodeGenerator('test')

        c.x.constantValue = 10.0
        c.y.constantValue = 20.0

        self.assertEqual(10.0, c.x.getValueForEditor())
        self.assertEqual(20.0, c.y.getValueForEditor())

        self.assertEqual(
            Py.Call(target=Py.Load(name='C'),
                    args=[
                        Py.FloatLiteral(value='10.0'),
                        Py.FloatLiteral(value='20.0')
                    ]), c.__py_evalmodel__(codeGen))

        x_expr = EmbeddedPython2Expr.fromText('a+b')
        y_expr = EmbeddedPython2Expr.fromText('c+d')
        c.x.expr = x_expr
        c.y.expr = y_expr

        self.assertEqual(10.0, c.x.getValueForEditor())
        self.assertEqual(20.0, c.y.getValueForEditor())

        self.assertEqual(
            Py.Call(target=Py.Load(name='C'),
                    args=[x_expr.model, y_expr.model]),
            c.__py_evalmodel__(codeGen))

    def test_ExprField_changeHistory(self):
        d = self.ExprFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(d)

        self.assertIs(ChangeHistory.getChangeHistoryFor(d), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(d.x.expr), self.ch)

    def test_ExprField_serialisation(self):
        x_expr = EmbeddedPython2Expr.fromText('a+b')
        d = self.ExprFieldTest(x=x_expr)

        d_io = pickle.loads(pickle.dumps(d))

        self.assertEqual(x_expr, d_io.x.expr)

    def test_ExprField_py_evalmodel(self):
        x_expr = EmbeddedPython2Expr.fromText('a+b')
        d = self.ExprFieldTest(x=x_expr)

        codeGen = Python2CodeGenerator('test')

        self.assertEqual(
            Py.Call(target=Py.Load(name='D'), args=[x_expr.model]),
            d.__py_evalmodel__(codeGen))
    def test_EvalField_changeHistory(self):
        c = self.EvalFieldTest()

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        self.ch.track(c)

        self.assertIs(ChangeHistory.getChangeHistoryFor(c), self.ch)

        self.assertEqual(0, self.ch.getNumUndoChanges())
        self.assertEqual(0, self.ch.getNumRedoChanges())

        c.x.constantValue = 10.0
        c.y.constantValue = 20.0

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        x_expr = EmbeddedPython2Expr.fromText('a+b')
        y_expr = EmbeddedPython2Expr.fromText('c+d')

        self.assertIs(ChangeHistory.getChangeHistoryFor(x_expr), None)
        self.assertIs(ChangeHistory.getChangeHistoryFor(y_expr), None)

        c.x.expr = x_expr
        c.y.expr = y_expr

        self.assertIs(ChangeHistory.getChangeHistoryFor(x_expr), self.ch)
        self.assertIs(ChangeHistory.getChangeHistoryFor(y_expr), self.ch)

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIs(x_expr, c.x.expr)
        self.assertIs(y_expr, c.y.expr)
        self.assertEqual(4, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIs(x_expr, c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(3, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(20.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(2, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(10.0, c.x.constantValue)
        self.assertEqual(1.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(1, self.ch.getNumUndoChanges())

        self.ch.undo()

        self.assertEqual(0.0, c.x.constantValue)
        self.assertEqual(1.0, c.y.constantValue)
        self.assertIsNone(c.x.expr)
        self.assertIsNone(c.y.expr)
        self.assertEqual(0, self.ch.getNumUndoChanges())
Beispiel #14
0
class Test_LiveList(unittest.TestCase):
    def setUp(self):
        self.history = ChangeHistory()
        self.ls = LiveList()
        self.history.track(self.ls)
        self.prevxs = None
        self.newxs = None
        self.ls.changeListener = self._onChanged

    def tearDown(self):
        self.ls.changeListener = None
        self.history.stopTracking(self.ls)
        self.ls = None
        self.history = None
        self.prevxs = None
        self.newxs = None

    def _onChanged(self, oldContents, newContents):
        self.prevxs = oldContents
        self.newxs = newContents

    def _test_changes(self, expectedOldContents, expectedNewContents):
        self.assertEqual(self.prevxs, expectedOldContents)
        self.assertEqual(self.newxs, expectedNewContents)
        self.prevxs = None
        self.newxs = None

    def test_setitem(self):
        self.assertEqual(self.ls[:], [])

        _two = _Value(-2)
        self.ls.append(_two)
        self.assertEqual(self.ls[:], [_two])
        self.assertTrue(_two.isTracked())
        self._test_changes([], [_two])

        _one = _Value(-1)
        self.ls[0] = _one
        self.assertEqual(self.ls[:], [_one])
        self.assertFalse(_two.isTracked())
        self.assertTrue(_one.isTracked())
        self._test_changes([_two], [_one])

        _rng = [_Value(x) for x in xrange(0, 5)]
        self.ls[1:] = _rng
        self.assertEqual(self.ls[:], [_one] + _rng)
        self.assertFalse(_two.isTracked())
        self.assertTrue(_one.isTracked())
        for x in _rng:
            self.assertTrue(x.isTracked())
        self._test_changes([_one], [_one] + _rng)

        self.history.undo()
        self.assertEqual(self.ls[:], [_one])
        self.assertFalse(_two.isTracked())
        self.assertTrue(_one.isTracked())
        for x in _rng:
            self.assertFalse(x.isTracked())
        self._test_changes([_one] + _rng, [_one])

        self.history.undo()
        self.assertEqual(self.ls[:], [_two])
        self.assertFalse(_one.isTracked())
        self.assertTrue(_two.isTracked())
        self._test_changes([_one], [_two])

        self.history.redo()
        self.assertEqual(self.ls[:], [_one])
        self.assertFalse(_two.isTracked())
        self.assertTrue(_one.isTracked())
        for x in _rng:
            self.assertFalse(x.isTracked())
        self._test_changes([_two], [_one])

        self.history.redo()
        self.assertEqual(self.ls[:], [_one] + _rng)
        self.assertFalse(_two.isTracked())
        self.assertTrue(_one.isTracked())
        for x in _rng:
            self.assertTrue(x.isTracked())
        self._test_changes([_one], [_one] + _rng)

    def test_delitem(self):
        self.assertEqual(self.ls[:], [])

        _rng = [_Value(x) for x in xrange(0, 5)]
        self.ls[:] = _rng
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

        del self.ls[0]
        self.assertEqual(self.ls[:], _rng[1:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, True, True, True, True])
        self._test_changes(_rng, _rng[1:])

        del self.ls[1:3]
        self.assertEqual(self.ls[:], [_rng[1], _rng[4]])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, True, False, False, True])
        self._test_changes(_rng[1:], [_rng[1], _rng[4]])

        self.history.undo()
        self.assertEqual(self.ls[:], _rng[1:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, True, True, True, True])
        self._test_changes([_rng[1], _rng[4]], _rng[1:])

        self.history.undo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng[1:], _rng)

        self.history.redo()
        self.assertEqual(self.ls[:], _rng[1:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, True, True, True, True])
        self._test_changes(_rng, _rng[1:])

        self.history.redo()
        self.assertEqual(self.ls[:], [_rng[1], _rng[4]])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, True, False, False, True])
        self._test_changes(_rng[1:], [_rng[1], _rng[4]])

    def test_append(self):
        self.assertEqual(self.ls[:], [])

        v = _Value(2)
        self.ls.append(v)
        self.assertTrue(v.isTracked())

        self.assertEqual(self.ls[:], [_Value(2)])
        self._test_changes([], [v])

        self.history.undo()
        self.assertEqual(self.ls[:], [])
        self.assertFalse(v.isTracked())
        self._test_changes([v], [])

        self.history.redo()
        self.assertEqual(self.ls[:], [_Value(2)])
        self.assertTrue(v.isTracked())
        self._test_changes([], [v])

    def test_extend(self):
        _rng = [_Value(x) for x in xrange(0, 5)]
        self.assertEqual(self.ls[:], [])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, False, False, False, False])

        self.ls.extend(_rng)
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

        self.history.undo()
        self.assertEqual(self.ls[:], [])
        self.assertEqual([x.isTracked() for x in _rng],
                         [False, False, False, False, False])
        self._test_changes(_rng, [])

        self.history.redo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

    def test_insert(self):
        v = _Value(20)
        _rng = [_Value(x) for x in xrange(0, 5)]

        self.ls[:] = _rng
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self.assertFalse(v.isTracked())
        self._test_changes([], _rng)

        self.ls.insert(2, v)
        self.assertEqual(self.ls[:], _rng[:2] + [v] + _rng[2:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self.assertTrue(v.isTracked())
        self._test_changes(_rng, _rng[:2] + [v] + _rng[2:])

        self.history.undo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self.assertFalse(v.isTracked())
        self._test_changes(_rng[:2] + [v] + _rng[2:], _rng)

        self.history.redo()
        self.assertEqual(self.ls[:], _rng[:2] + [v] + _rng[2:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self.assertTrue(v.isTracked())
        self._test_changes(_rng, _rng[:2] + [v] + _rng[2:])

    def test_pop(self):
        _rng = [_Value(x) for x in xrange(0, 5)]

        self.ls[:] = _rng
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

        v = self.ls.pop()
        self.assertTrue(v is _rng[-1])
        self.assertEqual(self.ls[:], _rng[:-1])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, False])
        self._test_changes(_rng, _rng[:-1])

        self.history.undo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng[:-1], _rng)

        self.history.redo()
        self.assertEqual(self.ls[:], _rng[:-1])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, False])
        self._test_changes(_rng, _rng[:-1])

    def test_remove(self):
        _rng = [_Value(x) for x in xrange(0, 5)]

        self.ls[:] = _rng
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

        self.ls.remove(_Value(2))
        self.assertEqual(self.ls[:], _rng[:2] + _rng[3:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, False, True, True])
        self._test_changes(_rng, _rng[:2] + _rng[3:])

        self.history.undo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng[:2] + _rng[3:], _rng)

        self.history.redo()
        self.assertEqual(self.ls[:], _rng[:2] + _rng[3:])
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, False, True, True])
        self._test_changes(_rng, _rng[:2] + _rng[3:])

    def test_reverse(self):
        _rng = [_Value(x) for x in xrange(0, 5)]
        _rev = _rng[:]
        _rev.reverse()

        self.ls[:] = _rng
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _rng)

        self.ls.reverse()
        self.assertEqual(self.ls[:], _rev)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng, _rev)

        self.history.undo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rev, _rng)

        self.history.redo()
        self.assertEqual(self.ls[:], _rev)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng, _rev)

    def test_sort(self):
        _rng = [_Value(x) for x in xrange(0, 5)]

        _shuf = _rng[:]
        r = random.Random(12345)
        r.shuffle(_shuf)

        self.ls[:] = _shuf
        self.assertEqual(self.ls[:], _shuf)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes([], _shuf)

        self.ls.sort()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_shuf, _rng)

        self.history.undo()
        self.assertEqual(self.ls[:], _shuf)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_rng, _shuf)

        self.history.redo()
        self.assertEqual(self.ls[:], _rng)
        self.assertEqual([x.isTracked() for x in _rng],
                         [True, True, True, True, True])
        self._test_changes(_shuf, _rng)

    def test_eq(self):
        self.ls[:] = range(0, 5)

        self.assertTrue(self.ls == range(0, 5))
        self.assertTrue(self.ls == LiveList(range(0, 5)))
        self.assertFalse(self.ls == range(0, 6))
        self.assertFalse(self.ls == LiveList(range(0, 6)))

        self.assertTrue(self.ls != range(0, 6))
        self.assertTrue(self.ls != LiveList(range(0, 6)))
        self.assertFalse(self.ls != range(0, 5))
        self.assertFalse(self.ls != LiveList(range(0, 5)))

    def test_str(self):
        self.ls[:] = range(0, 5)

        self.assertEqual(str(self.ls), str(range(0, 5)))

    def test_repr(self):
        self.ls[:] = range(0, 5)

        self.assertEqual(repr(self.ls),
                         'LiveList( ' + repr(range(0, 5)) + ' )')