Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar-toolkit/src/sugar/tutorius/tests
diff options
context:
space:
mode:
Diffstat (limited to 'sugar-toolkit/src/sugar/tutorius/tests')
-rw-r--r--sugar-toolkit/src/sugar/tutorius/tests/.coverage1
-rw-r--r--sugar-toolkit/src/sugar/tutorius/tests/coretests.py197
-rw-r--r--sugar-toolkit/src/sugar/tutorius/tests/coretests.pycbin0 -> 8818 bytes
-rw-r--r--sugar-toolkit/src/sugar/tutorius/tests/overlaytests.py115
-rw-r--r--sugar-toolkit/src/sugar/tutorius/tests/overlaytests.pycbin0 -> 4563 bytes
-rwxr-xr-xsugar-toolkit/src/sugar/tutorius/tests/run-tests.py12
6 files changed, 325 insertions, 0 deletions
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/.coverage b/sugar-toolkit/src/sugar/tutorius/tests/.coverage
new file mode 100644
index 0000000..eb89cb2
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/.coverage
@@ -0,0 +1 @@
+{0 \ No newline at end of file
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/coretests.py b/sugar-toolkit/src/sugar/tutorius/tests/coretests.py
new file mode 100644
index 0000000..ed5a7c0
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/coretests.py
@@ -0,0 +1,197 @@
+# Copyright (C) 2009, Tutorius.org
+# Copyright (C) 2009, Michael Janelle-Montcalm <michael.jmontcalm@gmail.com>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+Core Tests
+
+This module contains all the tests that pertain to the usage of the Tutorius
+Core. This means that the Event Filters, the Finite State Machine and all the
+related elements and interfaces are tested here.
+
+"""
+
+import unittest
+
+import logging
+from sugar.tutorius.actions import Action, OnceWrapper
+from sugar.tutorius.core import *
+from sugar.tutorius.filters import *
+
+# Helper classes to help testing
+class SimpleTutorial(Tutorial):
+ """
+ Fake tutorial
+ """
+ def __init__(self, start_name="INIT"):
+ #Tutorial.__init__(self, "Simple Tutorial", None)
+ self.current_state_name = start_name
+ self.activity = "TODO : This should be an activity"
+
+ def set_state(self, name):
+ self.current_state_name = name
+
+class TrueWhileActiveAction(Action):
+ """
+ This action's active member is set to True after a do and to False after
+ an undo.
+
+ Used to verify that a State correctly triggers the do and undo actions.
+ """
+ def __init__(self):
+ self.active = False
+
+ def do(self):
+ self.active = True
+
+ def undo(self):
+ self.active = False
+
+
+class CountAction(Action):
+ """
+ This action counts how many times it's do and undo methods get called
+ """
+ def __init__(self):
+ self.do_count = 0
+ self.undo_count = 0
+
+ def do(self):
+ self.do_count += 1
+
+ def undo(self):
+ self.undo_count += 1
+
+class TriggerEventFilter(EventFilter):
+ """
+ This event filter can be triggered by simply calling its execute function.
+
+ Used to fake events and see the effect on the FSM.
+ """
+ def __init__(self, next_state):
+ EventFilter.__init__(self, next_state)
+ self.toggle_on_callback = False
+
+ def install_handlers(self, callback, **kwargs):
+ """
+ Forsakes the incoming callback function and just set the inner one.
+ """
+ self._callback = self._inner_cb
+
+ def _inner_cb(self, event_filter):
+ self.toggle_on_callback = not self.toggle_on_callback
+
+class OnceWrapperTests(unittest.TestCase):
+ def test_onceaction_toggle(self):
+ """
+ Validate that the OnceWrapper wrapper works properly using the
+ CountAction
+ """
+ act = CountAction()
+ wrap = OnceWrapper(act)
+
+ assert act.do_count == 0, "do() should not have been called in __init__()"
+ assert act.undo_count == 0, "undo() should not have been called in __init__()"
+
+ wrap.undo()
+
+ assert act.undo_count == 0, "undo() should not be called if do() has not been called"
+
+ wrap.do()
+ assert act.do_count == 1, "do() should have been called once"
+
+ wrap.do()
+ assert act.do_count == 1, "do() should have been called only once"
+
+ wrap.undo()
+ assert act.undo_count == 1, "undo() should have been called once"
+
+ wrap.undo()
+ assert act.undo_count == 1, "undo() should have been called only once"
+
+
+# State testing class
+class StateTest(unittest.TestCase):
+ """
+ This class has to test the State interface as well as the expected
+ functionality.
+ """
+
+ def test_action_toggle(self):
+ """
+ Validate that the actions are properly done on setup and undone on
+ teardown.
+
+ Pretty awesome.
+ """
+ act = TrueWhileActiveAction()
+
+ state = State("action_test", action_list=[act])
+
+ assert act.active == False, "Action is not initialized properly"
+
+ state.setup()
+
+ assert act.active == True, "Action was not triggered properly"
+
+ state.teardown()
+
+ assert act.active == False, "Action was not undone properly"
+
+ def test_event_filter(self):
+ """
+ Tests the fact that the event filters are correctly installed on setup
+ and uninstalled on teardown.
+ """
+ event_filter = TriggerEventFilter("second_state")
+
+ state = State("event_test", event_filter_list=[event_filter])
+ state.set_tutorial(SimpleTutorial())
+
+ assert event_filter.toggle_on_callback == False, "Wrong init of event_filter"
+ assert event_filter._callback == None, "Event filter has a registered callback before installing handlers"
+
+ state.setup()
+
+ assert event_filter._callback != None, "Event filter did not register callback!"
+
+ # 'Trigger' the event - This is more like a EventFilter test.
+ event_filter.do_callback()
+
+ assert event_filter.toggle_on_callback == True, "Event filter did not execute callback"
+
+ state.teardown()
+
+ assert event_filter._callback == None, "Event filter did not remove callback properly"
+
+ def test_warning_set_tutorial_twice(self):
+ """
+ Calls set_tutorial twice and expects a warning on the second.
+ """
+ state = State("start_state")
+ tut = SimpleTutorial("First")
+ tut2 = SimpleTutorial("Second")
+
+ state.set_tutorial(tut)
+
+ try:
+ state.set_tutorial(tut2)
+ assert False, "No RuntimeWarning was raised on second set_tutorial"
+ except :
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/coretests.pyc b/sugar-toolkit/src/sugar/tutorius/tests/coretests.pyc
new file mode 100644
index 0000000..5adf79e
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/coretests.pyc
Binary files differ
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.py b/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.py
new file mode 100644
index 0000000..b5fd209
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.py
@@ -0,0 +1,115 @@
+# Copyright (C) 2009, Tutorius.org
+# Copyright (C) 2009, Simon Poirier <simpoir@gmail.com>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+GUI Tests
+
+This module contains all the tests that pertain to the usage of the Tutorius
+overlay mechanism used to display objects on top of the application.
+"""
+
+import unittest
+
+import logging
+import gtk, gobject
+from sugar.tutorius.actions import Action, BubbleMessage
+import sugar.tutorius.overlayer as overlayer
+
+class CanvasDrawable(object):
+ def __init__(self):
+ self._no_expose = False
+ self.exposition_count = 0
+ def _set_no_expose(self, value):
+ self._no_expose = value
+ def draw_with_context(self, context):
+ self.exposition_count += 1
+ no_expose = property(fset=_set_no_expose)
+
+
+class OverlayerTest(unittest.TestCase):
+ def test_cairodrawable_iface(self):
+ """
+ Quickly validates that all our cairo widgets have a minimal interface
+ implemented.
+ """
+ drawables = [overlayer.TextBubble]
+ for widget in drawables:
+ for attr in filter(lambda s:s[0]!='_', dir(CanvasDrawable)):
+ assert hasattr(widget, attr), \
+ "%s not implementing CanvasDrawable iface"%widget.__name__
+
+
+ def test_drawn(self):
+ """
+ Ensures a cairo widget draw method is called at least once in
+ a real gui app.
+ """
+ win = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
+
+ btn = gtk.Button()
+ btn.show()
+ overlay = overlayer.Overlayer(btn)
+ win.add(overlay)
+ # let's also try to draw substitute button label
+ lbl = overlayer.TextBubble("test!")
+ assert lbl.label == 'test!', \
+ "label property mismatch"
+ btn.show()
+ lbl.show()
+ btn.add(lbl)
+
+ lbl.no_expose = True
+ assert lbl.no_expose, "wrong no_expose evaluation"
+ lbl.no_expose = False
+ assert not lbl.no_expose, "wrong no_expose evaluation"
+
+
+ widget = overlayer.TextBubble("testing msg!", tailpos=(10,-20))
+ widget.exposition_count = 0
+ # override draw method
+ def counter(ctx, self=widget):
+ self.exposition_count += 1
+ self.real_exposer(ctx)
+ widget.real_exposer = widget.draw_with_context
+ widget.draw_with_context = counter
+ # centering allows to test the blending with the label
+ overlay.put(widget, 50, 50)
+ widget.show()
+ assert widget.no_expose, \
+ "Overlay should overide exposition handling of widget"
+ assert not lbl.no_expose, \
+ "Non-overlayed cairo should expose as usual"
+
+ # force widget realization
+ # the child is flagged to be redrawn, the overlay should redraw too.
+ win.set_default_size(100, 100)
+ win.show()
+
+ while gtk.events_pending():
+ gtk.main_iteration(block=False)
+ # visual validation: there should be 2 visible bubbles, one as label,
+ # one as overlay
+ import time
+ time.sleep(1)
+ # as x11 events are asynchronous, wait a bit before assuming it went
+ # wrong.
+ while gtk.events_pending():
+ gtk.main_iteration(block=False)
+ assert widget.exposition_count>0, "overlay widget should expose"
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.pyc b/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.pyc
new file mode 100644
index 0000000..8d7d533
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/overlaytests.pyc
Binary files differ
diff --git a/sugar-toolkit/src/sugar/tutorius/tests/run-tests.py b/sugar-toolkit/src/sugar/tutorius/tests/run-tests.py
new file mode 100755
index 0000000..74efd64
--- /dev/null
+++ b/sugar-toolkit/src/sugar/tutorius/tests/run-tests.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+# This is a dumb script to run tests on the sugar-jhbuild installed files
+# The path added is the default path for the jhbuild build
+
+import os, sys
+sys.path.insert(0,
+ os.path.abspath("../../../../../../install/lib/python2.5/site-packages/")
+)
+import unittest
+from coretests import *
+
+unittest.main()