diff options
| author | Ivan Alejandro <ivanalejandro0@yahoo.com.ar> | 2013-06-25 16:53:36 -0300 | 
|---|---|---|
| committer | Ivan Alejandro <ivanalejandro0@yahoo.com.ar> | 2013-06-25 16:53:36 -0300 | 
| commit | 04a0fa945a0ec239960255bc2a0f2f01a5b4a224 (patch) | |
| tree | 607027375791754a79b99838de5ace879ae6cd21 | |
| parent | a5a51bcc1573d7b7cf281a4d8ac142705bd227d0 (diff) | |
| parent | 77d9434c4a92528e13b008a50dfbcb5f2f1456a4 (diff) | |
Merge remote-tracking branch 'chiiph/feature/add_abstractbootstrapper_test' into develop
| -rw-r--r-- | src/leap/services/abstractbootstrapper.py | 1 | ||||
| -rw-r--r-- | src/leap/services/tests/__init__.py | 0 | ||||
| -rw-r--r-- | src/leap/services/tests/test_abstractbootstrapper.py | 196 | ||||
| -rw-r--r-- | src/leap/util/keyring_helpers.py | 1 | ||||
| -rw-r--r-- | src/leap/util/pyside_tests_helper.py | 7 | 
5 files changed, 203 insertions, 2 deletions
| diff --git a/src/leap/services/abstractbootstrapper.py b/src/leap/services/abstractbootstrapper.py index f0937197..633d818d 100644 --- a/src/leap/services/abstractbootstrapper.py +++ b/src/leap/services/abstractbootstrapper.py @@ -157,3 +157,4 @@ class AbstractBootstrapper(QtCore.QObject):              d.addErrback(self._errback, signal=sig)              d.addCallback(self._gui_notify, signal=sig)          d.addErrback(self._gui_errback) +        return d diff --git a/src/leap/services/tests/__init__.py b/src/leap/services/tests/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/leap/services/tests/__init__.py diff --git a/src/leap/services/tests/test_abstractbootstrapper.py b/src/leap/services/tests/test_abstractbootstrapper.py new file mode 100644 index 00000000..a9ee220f --- /dev/null +++ b/src/leap/services/tests/test_abstractbootstrapper.py @@ -0,0 +1,196 @@ +## -*- coding: utf-8 -*- +# test_abstrctbootstrapper.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +""" +Tests for the Abstract Boostrapper functionality +""" + +import mock + +from PySide import QtCore + +from nose.twistedtools import deferred + +from leap.services.abstractbootstrapper import AbstractBootstrapper +from leap.util.pyside_tests_helper import UsesQApplication, BasicPySlotCase + + +class TesterBootstrapper(AbstractBootstrapper): +    test_signal1 = QtCore.Signal(dict) +    test_signal2 = QtCore.Signal(dict) +    test_signal3 = QtCore.Signal(dict) + +    ERROR_MSG = "This is a test error msg" + +    def _check_that_passes(self, *args): +        pass + +    def _second_check_that_passes(self, *args): +        pass + +    def _check_that_fails(self, *args): +        raise Exception(self.ERROR_MSG) + +    def run_checks_pass(self): +        cb_chain = [ +            (self._check_that_passes, self.test_signal1), +            (self._second_check_that_passes, self.test_signal2), +        ] +        return self.addCallbackChain(cb_chain) + +    def run_second_checks_pass(self): +        cb_chain = [ +            (self._check_that_passes, None), +        ] +        return self.addCallbackChain(cb_chain) + +    def run_checks_fail(self): +        cb_chain = [ +            (self._check_that_passes, self.test_signal1), +            (self._check_that_fails, self.test_signal2) +        ] +        return self.addCallbackChain(cb_chain) + +    def run_second_checks_fail(self): +        cb_chain = [ +            (self._check_that_passes, self.test_signal1), +            (self._check_that_fails, self.test_signal2), +            (self._second_check_that_passes, self.test_signal1) +        ] +        return self.addCallbackChain(cb_chain) + +    def run_third_checks_fail(self): +        cb_chain = [ +            (self._check_that_passes, self.test_signal1), +            (self._check_that_fails, None) +        ] +        return self.addCallbackChain(cb_chain) + + +class AbstractBootstrapperTest(UsesQApplication, BasicPySlotCase): +    def setUp(self): +        UsesQApplication.setUp(self) +        BasicPySlotCase.setUp(self) + +        self.tbt = TesterBootstrapper() +        self.called1 = self.called2 = 0 + +    @deferred() +    def test_all_checks_executed_once(self): +        self.tbt._check_that_passes = mock.MagicMock() +        self.tbt._second_check_that_passes = mock.MagicMock() + +        d = self.tbt.run_checks_pass() + +        def check(*args): +            self.tbt._check_that_passes.assert_called_once_with() +            self.tbt._second_check_that_passes.\ +                assert_called_once_with(None) + +        d.addCallback(check) +        return d + +    ####################################################################### +    # Dummy callbacks that test the arguments expected from a certain +    # signal and only allow being called once + +    def cb1(self, *args): +        if tuple(self.args1) == args: +            self.called1 += 1 +        else: +            raise ValueError('Invalid arguments for callback') + +    def cb2(self, *args): +        if tuple(self.args2) == args: +            self.called2 += 1 +        else: +            raise ValueError('Invalid arguments for callback') + +    # +    ####################################################################### + +    def _check_cb12_once(self, *args): +        self.assertEquals(self.called1, 1) +        self.assertEquals(self.called2, 1) + +    @deferred() +    def test_emits_correct(self): +        self.tbt.test_signal1.connect(self.cb1) +        self.tbt.test_signal2.connect(self.cb2) +        d = self.tbt.run_checks_pass() + +        self.args1 = [{ +            AbstractBootstrapper.PASSED_KEY: True, +            AbstractBootstrapper.ERROR_KEY: "" +        }] + +        self.args2 = self.args1 + +        d.addCallback(self._check_cb12_once) +        return d + +    @deferred() +    def test_emits_failed(self): +        self.tbt.test_signal1.connect(self.cb1) +        self.tbt.test_signal2.connect(self.cb2) +        d = self.tbt.run_checks_fail() + +        self.args1 = [{ +            AbstractBootstrapper.PASSED_KEY: True, +            AbstractBootstrapper.ERROR_KEY: "" +        }] + +        self.args2 = [{ +            AbstractBootstrapper.PASSED_KEY: False, +            AbstractBootstrapper.ERROR_KEY: +            TesterBootstrapper.ERROR_MSG +        }] + +        d.addCallback(self._check_cb12_once) +        return d + +    @deferred() +    def test_emits_failed_and_stops(self): +        self.tbt.test_signal1.connect(self.cb1) +        self.tbt.test_signal2.connect(self.cb2) +        self.tbt.test_signal3.connect(self.cb1) +        d = self.tbt.run_second_checks_fail() + +        self.args1 = [{ +            AbstractBootstrapper.PASSED_KEY: True, +            AbstractBootstrapper.ERROR_KEY: "" +        }] + +        self.args2 = [{ +            AbstractBootstrapper.PASSED_KEY: False, +            AbstractBootstrapper.ERROR_KEY: +            TesterBootstrapper.ERROR_MSG +        }] + +        d.addCallback(self._check_cb12_once) +        return d + +    @deferred() +    def test_failed_without_signal(self): +        d = self.tbt.run_third_checks_fail() +        return d + +    @deferred() +    def test_sucess_without_signal(self): +        d = self.tbt.run_second_checks_pass() +        return d diff --git a/src/leap/util/keyring_helpers.py b/src/leap/util/keyring_helpers.py index b3dd0175..b815d385 100644 --- a/src/leap/util/keyring_helpers.py +++ b/src/leap/util/keyring_helpers.py @@ -26,6 +26,7 @@ OBSOLETE_KEYRINGS = [      keyring.backends.file.PlaintextKeyring  ] +  def has_keyring():      """ diff --git a/src/leap/util/pyside_tests_helper.py b/src/leap/util/pyside_tests_helper.py index a010934a..5c0eb8d6 100644 --- a/src/leap/util/pyside_tests_helper.py +++ b/src/leap/util/pyside_tests_helper.py @@ -15,14 +15,17 @@ except ImportError:  else:      has_gui = True +  def adjust_filename(filename, orig_mod_filename):      dirpath = os.path.dirname(os.path.abspath(orig_mod_filename))      return os.path.join(dirpath, filename) +  class NoQtGuiError(Exception):      def __init__(self):          Exception.__init__(self, 'No QtGui found') +  class BasicPySlotCase(object):      '''Base class that tests python slots and signal emissions. @@ -75,7 +78,6 @@ if has_gui:              del self.app              super(UsesQApplication, self).tearDown() -      class TimedQApplication(unittest.TestCase):          '''Helper class with timed QApplication exec loop''' @@ -97,13 +99,14 @@ else:      class UsesQApplication(unittest.TestCase):          def setUp(self):              raise NoQtGuiError() +      class TimedQapplication(unittest.TestCase):          def setUp(self):              raise NoQtGuiError() -  _core_instance = None +  class UsesQCoreApplication(unittest.TestCase):      '''Helper class for test cases that require an QCoreApplication      Just connect or call self.exit_app_cb. When called, will ask | 
