#!/usr/bin/env python
# vim: sw=4

# Canvas items should be able to be constructed like diacanvas.CanvasBox()

import diacanvas as dia
import unittest
import sys, gobject, weakref, gc

class CanvasTestCase(unittest.TestCase):

    def testConstruction(self):
	c = dia.Canvas()
	self.failUnless(sys.getrefcount(c) == 3)
	# One for the wrapper object
	self.failUnless(c.__grefcount__ == 1)
	w_c = weakref.ref(c)
	self.failUnless(isinstance(c, dia.Canvas))
	self.failUnless(isinstance(c.root, dia.CanvasGroup))
	del c
	gc.collect()
	self.failIf(w_c(), 'Canvas not freed')

    def testConstruction_2(self):
        c = dia.Canvas()
	self.failUnless(sys.getrefcount(c) == 3)
	self.failUnless(c.__grefcount__ == 1)
	i = dia.CanvasBox()
	self.failUnless(isinstance(i, dia.CanvasBox))
	self.failUnless(sys.getrefcount(i) == 3)
	self.failUnless(i.__grefcount__ == 1)
	w_c = weakref.ref(c)
	w_i = weakref.ref(i)
	i.set(parent=c.root)
	# Only the refcount of the GObject increments ;-)
	self.failUnless(sys.getrefcount(i) == 3)
	self.failUnless(i.__grefcount__ == 2)
	self.failIf(i.parent != c.root)
	self.failIf(c.root.children[0] != i)
	self.failUnless(sys.getrefcount(c) == 3)
	self.failUnless(c.__grefcount__ == 1)
	#self.failUnless(i.parent is None)
	#self.failUnless(len(c.root.children) == 0)
	del c, i
	# HELP: We should do gc.collect() three times!?!
	gc.collect()
	gc.collect()
	gc.collect()
	self.failIf(w_c(), 'Canvas not freed')
	self.failIf(w_i(), 'CanvasItem not freed: %s/%s' % (w_i() and sys.getrefcount(w_i()), w_i() and w_i().__grefcount__))

    def testRemoveItem(self):
        c = dia.Canvas()
	i = dia.CanvasBox()
	w_c = weakref.ref(c)
	w_i = weakref.ref(i)
	i.set(parent=c.root)
	self.failUnless(isinstance(i, dia.CanvasBox))
	self.failUnless(i.__grefcount__ == 2) # parent + wrapper
	self.failUnless(len(c.root.children) == 1)
	self.failIf(i.parent != c.root)
	self.failIf(c.root.children[0] != i)
	c.root.remove(i)
	self.failUnless(len(c.root.children) == 0)
	self.failUnless(sys.getrefcount(i) == 3)
	self.failUnless(i.__grefcount__ == 1)
	del c, i
	gc.collect()
	self.failIf(w_c(), 'Canvas not freed')
	self.failIf(w_i(), 'CanvasItem not freed')

    def testConnection(self):
	c = dia.Canvas()
	b1 = dia.CanvasBox()
	b2 = dia.CanvasBox()
	l = dia.CanvasLine()
	b1.set(parent=c.root)
	self.failUnless(sys.getrefcount(b1) == 3)
	self.failUnless(b1.__grefcount__ == 2)
	c.root.add(b2)
	self.failUnless(sys.getrefcount(b2) == 3)
	self.failUnless(b2.__grefcount__ == 2)
	c.root.add(l)
	self.failUnless(sys.getrefcount(l) == 3)
	self.failUnless(l.__grefcount__ == 2)
	b1.connect_handle(l.handles[0])
	self.failUnless(sys.getrefcount(b1) == 3)
	self.failUnless(b1.__grefcount__ == 2)
	self.failUnless(sys.getrefcount(l) == 3)
	self.failUnless(l.__grefcount__ == 2)
	b2.connect_handle(l.handles[-1])
	self.failUnless(sys.getrefcount(b2) == 3)
	self.failUnless(b2.__grefcount__ == 2)
	self.failUnless(sys.getrefcount(l) == 3)
	self.failUnless(l.__grefcount__ == 2)
	del c, b1, b2, l
	gc.collect()

    def testConstraint(self):
	c = dia.Canvas()
	con = dia.Constraint()
	v = dia.Variable()
	w_c = weakref.ref(c)
	w_con = weakref.ref(con)
	w_v = weakref.ref(v)
	con.add(v, 1.0)
	c.add_constraint(con)
	del con
	gc.collect()
	self.failUnless(w_con(), 'Constraint shouldn\'t be freed')
	del v
	gc.collect()
	self.failUnless(w_v(), 'Variable shouldn\'t be freed')
	del c
	gc.collect()
	gc.collect()
	gc.collect()
	self.failIf(w_c(), 'Canvas not freed')
	self.failIf(w_con(), 'Constraint not freed')
	self.failIf(w_v(), 'Variable not freed')

if __name__ == '__main__':
    unittest.main()
