# 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 twisted.trial.unittest import TestCase
from elisa.core.components.input_provider import PushInputProvider, \
                                                 PollInputProvider
from elisa.core.input_manager import InputManager


class TestInputManager(TestCase):

    def test_registering_unregister_push(self):
        """
        Check if registering and unregistering a PushInputProvider calls the
        right methods
        """
        
        class SimplePushProvider(PushInputProvider):
            bound = False
            input_manager = None

            def bind(self):
                self.bound = True

            def unbind(self):
                self.bound = False

        s_provider = SimplePushProvider()

        i_manager = InputManager()

        i_manager.register_component(s_provider)

        self.assertTrue(s_provider.bound)
        self.assertEquals(s_provider.input_manager, i_manager)

        i_manager.unregister_component(s_provider)
        self.assertFalse(s_provider.bound)

    def test_register_unregister_poll(self):
        """
        Check if registering and unregistering a PollInputProvider works as
        expected
        """

        class SimplePollProvider(PollInputProvider):
            bound = False
            input_manager = None

            def bind(self):
                self.bound = True

            def unbind(self):
                self.bound = False

        s_provider = SimplePollProvider()

        i_manager = InputManager()

        i_manager.register_component(s_provider)

        # should not be bound!
        self.assertFalse(s_provider.bound)
        self.assertEquals(s_provider.input_manager, None)

        i_manager.unregister_component(s_provider)
        self.assertFalse(s_provider.bound)


    def test_event_processing(self):
        """
        Test if an input event gets forwarded correctly
        """

        input_manager = InputManager()

        def callback(obj, event):
            self.assertEquals(obj, input_manager)
            self.assertEquals(event, '42')
            callback.called = True

        callback.called = False

        input_manager.connect('input_event', callback)
        input_manager.process_event('42')

        self.assertTrue(callback.called)

        
    def test_poll_processing(self):
        """
        test if a polled input events gets triggered correctly
        """

        class SimplePollProvider(PollInputProvider):
            def get_input_events(self):
                return ('pocahontas',)

        input_manager = InputManager()
        
        # tweak the provider:
        def event_call(event):
            self.assertEquals(event, 'pocahontas')
            event_call.called = True

        event_call.called = False

        input_manager.process_event = event_call

        simple = SimplePollProvider()
        input_manager.register_component(simple)

        input_manager._poll_events()

        self.assertTrue(event_call.called)
        return input_manager.clean()

    def test_processing_breaks(self):
        """
        test what happens, when the signal chain breaks
        """

        def call1(obj, data):
            call1.called = True

        call1.called = False

        def callfails(obj, data):
            callfails.called = True
            raise Exception("No way, dude!")

        callfails.called = False

        def call2(obj, data):
            call2.called = True

        call2.called = False
        
        input_manager = InputManager()
        input_manager.connect('input_event', call1)
        input_manager.connect('input_event', callfails)
        input_manager.connect('input_event', call2)

        input_manager.process_event('yep')

        self.assertTrue(call1.called)
        self.assertTrue(callfails.called)
        self.assertTrue(call2.called)
