Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcharles <iso.swiffer@gmail.com>2009-04-15 15:22:45 (GMT)
committer Vincent Vinet <vince.vinet@gmail.com>2009-04-16 15:29:14 (GMT)
commit78de92cde03264725093868231bdb539feb4f56b (patch)
tree6da8245abeabb699e7cc06ee965ee8ea6ef3468b
parent8ab1e32a479c018766f330ecf71670ef71492300 (diff)
Added ClickAction and TypeTextAction + support for initial state
-rw-r--r--src/sugar/tutorius/actions.py53
-rw-r--r--src/sugar/tutorius/core.py20
-rw-r--r--src/sugar/tutorius/tests/coretests.py129
3 files changed, 200 insertions, 2 deletions
diff --git a/src/sugar/tutorius/actions.py b/src/sugar/tutorius/actions.py
index 2c76bd7..ad91fb4 100644
--- a/src/sugar/tutorius/actions.py
+++ b/src/sugar/tutorius/actions.py
@@ -250,3 +250,56 @@ class DisableWidgetAction(Action):
"""Action undo"""
if self._widget:
self._widget.set_sensitive(True)
+
+class TypeTextAction(Action):
+ """
+ Simulate a user typing text in a widget
+ Work on any widget that implements a insert_text method
+
+ @param widget The treehish representation of the widget
+ @param text the text that is typed
+ """
+ def __init__(self, widget, text):
+ Action.__init__(self)
+
+ self._widget = widget
+ self._text = text
+
+ def do(self, **kwargs):
+ """
+ Type the text
+ """
+ widget = gtkutils.find_widget(ObjectStore().activity, self._widget)
+ if hasattr(widget, "insert_text"):
+ widget.insert_text(self._text, -1)
+
+ def undo(self):
+ """
+ no undo
+ """
+ pass
+
+class ClickAction(Action):
+ """
+ Action that simulate a click on a widget
+ Work on any widget that implements a clicked() method
+
+ @param widget The threehish representation of the widget
+ """
+ def __init__(self, widget):
+ Action.__init__(self)
+ self._widget = widget
+
+ def do(self):
+ """
+ click the widget
+ """
+ widget = gtkutils.find_widget(ObjectStore().activity, self._widget)
+ if hasattr(widget, "clicked"):
+ widget.clicked()
+
+ def undo(self):
+ """
+ No undo
+ """
+ pass
diff --git a/src/sugar/tutorius/core.py b/src/sugar/tutorius/core.py
index 901820f..f290f1e 100644
--- a/src/sugar/tutorius/core.py
+++ b/src/sugar/tutorius/core.py
@@ -24,6 +24,7 @@ This module contains the core classes for tutorius
import gtk
import logging
import copy
+import os
from sugar.tutorius.dialog import TutoriusDialog
from sugar.tutorius.gtkutils import find_widget
@@ -36,12 +37,13 @@ class Tutorial (object):
Tutorial Class, used to run through the FSM.
"""
- def __init__(self, name, fsm):
+ def __init__(self, name, fsm,filename= None):
"""
Creates an unattached tutorial.
"""
object.__init__(self)
self.name = name
+ self.activity_init_state_filename = filename
self.state_machine = fsm
self.state_machine.set_tutorial(self)
@@ -64,6 +66,7 @@ class Tutorial (object):
self.activity = activity
ObjectStore().activity = activity
ObjectStore().tutorial = self
+ self._prepare_activity()
self.state_machine.set_state("INIT")
def detach(self):
@@ -97,6 +100,21 @@ class Tutorial (object):
#Swith to the next state pointed by the eventfilter
self.set_state(eventfilter.get_next_state())
+
+ def _prepare_activity(self):
+ """
+ Prepare the activity for the tutorial by loading the saved state and
+ emitting gtk signals
+ """
+ #Load the saved activity if any
+ if self.activity_init_state_filename is not None:
+ #For now the file will be saved in the data folder
+ #of the activity root directory
+ filename = os.getenv("SUGAR_ACTIVITY_ROOT") + "/data/" +\
+ self.activity_init_state_filename
+ if os.path.exists(filename):
+ self.activity.read_file(filename)
+
class State(object):
"""
diff --git a/src/sugar/tutorius/tests/coretests.py b/src/sugar/tutorius/tests/coretests.py
index f9125ce..5f91a64 100644
--- a/src/sugar/tutorius/tests/coretests.py
+++ b/src/sugar/tutorius/tests/coretests.py
@@ -29,7 +29,7 @@ and event filters. Those are in their separate test module
import unittest
import logging
-from sugar.tutorius.actions import Action
+from sugar.tutorius.actions import Action, ClickAction, TypeTextAction
from sugar.tutorius.core import *
from sugar.tutorius.filters import *
@@ -64,6 +64,44 @@ class TrueWhileActiveAction(Action):
def undo(self):
self.active = False
+
+class ClickableWidget():
+ """
+ This class fakes a widget with a clicked() method
+ """
+ def __init__(self):
+ self.click_count = 0
+
+ def clicked(self):
+ self.click_count += 1
+
+class FakeTextEntry():
+ """
+ This class fakes a widget with an insert_text() method
+ """
+ def __init__(self):
+ self.text_lines = []
+ self.last_entered_line = ""
+ self.displayed_text = ""
+
+ def insert_text(self, text, index):
+ self.last_entered_line = text
+ self.text_lines.append(text)
+ self.displayed_text = self.displayed_text[0:index] + text + self.displayed_text[index+1:]
+
+class FakeParentWidget():
+ """
+ This class fakes a widet container, it implements the get_children() method
+ """
+ def __init__(self):
+ self._children = []
+
+ def add_child(self, child):
+ self._children.append(child)
+
+ def get_children(self):
+ return self._children
+
@@ -103,7 +141,96 @@ class FakeEventFilter(TriggerEventFilter):
self.tutorial.set_state(event_filter.get_next_state())
+class ClickActionTests(unittest.TestCase):
+ """
+ Test class for click action
+ """
+ def test_do_action(self):
+ activity = FakeParentWidget()
+ widget = ClickableWidget()
+ activity.add_child(widget)
+ ObjectStore().activity = activity
+
+ action = ClickAction("0.0")
+
+ assert widget == ObjectStore().activity.get_children()[0],\
+ "The clickable widget isn't reachable from the object store \
+ the test cannot pass"
+
+ action.do()
+
+ assert widget.click_count == 1, "clicked() should have been called by do()"
+
+ action.do()
+
+ assert widget.click_count == 2, "clicked() should have been called by do()"
+ def test_undo(self):
+ activity = FakeParentWidget()
+ widget = ClickableWidget()
+ activity.add_child(widget)
+ ObjectStore().activity = activity
+
+ action = ClickAction("0.0")
+
+ assert widget == ObjectStore().activity.get_children()[0],\
+ "The clickable widget isn't reachable from the object store \
+ the test cannot pass"
+
+ action.undo()
+
+ #There is no undo for this action so the test should not fail
+ assert True
+
+
+
+class TypeTextActionTests(unittest.TestCase):
+ """
+ Test class for type text action
+ """
+ def test_do_action(self):
+ activity = FakeParentWidget()
+ widget = FakeTextEntry()
+ activity.add_child(widget)
+ ObjectStore().activity = activity
+
+ test_text = "This is text"
+
+
+ action = TypeTextAction("0.0", test_text)
+
+ assert widget == ObjectStore().activity.get_children()[0],\
+ "The clickable widget isn't reachable from the object store \
+ the test cannot pass"
+
+ action.do()
+
+ assert widget.last_entered_line == test_text, "insert_text() should have been called by do()"
+
+ action.do()
+
+ assert widget.last_entered_line == test_text, "insert_text() should have been called by do()"
+ assert len(widget.text_lines) == 2, "insert_text() should have been called twice"
+
+ def test_undo(self):
+ activity = FakeParentWidget()
+ widget = FakeTextEntry()
+ activity.add_child(widget)
+ ObjectStore().activity = activity
+
+ test_text = "This is text"
+
+
+ action = TypeTextAction("0.0", test_text)
+
+ assert widget == ObjectStore().activity.get_children()[0],\
+ "The clickable widget isn't reachable from the object store \
+ the test cannot pass"
+
+ action.undo()
+
+ #There is no undo for this action so the test should not fail
+ assert True
# State testing class
class StateTest(unittest.TestCase):