# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.

from elisa.plugins.pigment.graph import node
from elisa.plugins.pigment.graph.node import Node
from elisa.plugins.pigment.graph.group import Group

from twisted.trial.unittest import TestCase

import weakref
import gc
import gobject

class GenericTestNode(object):
    """
    These are tests that all classes inheriting from Node should pass.
    You should reimplement this class for anything that inherits from Node.

    @cvar tested_class:  a class inheriting from Node to be tested
    @type tested_class:  C{type}
    """

    tested_class = None

    def _create_instance(self):
        return self.tested_class()

    def test_cycle(self):
        """
        Tests that a node isn't in any reference cycle after clean() has been
        called.
        """
        reenable_gc = False
        if gc.isenabled():
            gc.disable()
            reenable_gc = True
        node = self._create_instance()
        node_ref = weakref.ref(node)

        group = Group()
        group.add(node)
        group.remove(node)

        node.clean()
        del node

        self.assertTrue(node_ref() is None)

        if reenable_gc:
            gc.enable()

    def _hook_clean(self):
        self._old_clean = Node.clean
        def clean(node):
            node.is_clean = True
            return self._old_clean(node)
        Node.clean = clean

    def _unhook_clean(self):
        Node.clean = self._old_clean

    def test_clean(self):
        """ Test that Node.clean() is called from tested_class.clean(). """
        self._hook_clean()
        node = self._create_instance()
        node.is_clean = False
        node.clean()
        self.assertTrue(node.is_clean)
        self._unhook_clean()

class GenericTestNodeImpl(GenericTestNode, TestCase):
    tested_class = Node

