Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormike <michael.jmontcalm@gmail.com>2009-11-19 16:15:52 (GMT)
committer mike <michael.jmontcalm@gmail.com>2009-11-19 16:15:52 (GMT)
commit0a427dbd5acbcfee8874c30fb0a1c16473f1b93d (patch)
treef0eb125ce460835cd356575dacc49acd21548d4a
parent88b3f3099252353e22c536a68e15e2a2f9b10334 (diff)
LP 448319 : Adding tests for translator, properties, constraints and probes, fixing Probe Proxy's uninstalltranslator_merge
-rw-r--r--tests/constraintstests.py42
-rw-r--r--tests/probetests.py47
-rw-r--r--tests/propertiestests.py56
-rw-r--r--tests/translatortests.py131
-rw-r--r--tutorius/TProbe.py8
5 files changed, 262 insertions, 22 deletions
diff --git a/tests/constraintstests.py b/tests/constraintstests.py
index 4e19a92..a5ccf26 100644
--- a/tests/constraintstests.py
+++ b/tests/constraintstests.py
@@ -240,5 +240,47 @@ class FileConstraintTest(unittest.TestCase):
except FileConstraintError:
pass
+class ResourceConstraintTest(unittest.TestCase):
+ def test_valid_names(self):
+ name1 = "file_" + unicode(uuid.uuid1()) + ".png"
+ name2 = unicode(uuid.uuid1()) + "_" + unicode(uuid.uuid1()) + ".extension"
+ name3 = "/home/user/.sugar/_random/new_image1231_" + unicode(uuid.uuid1()).upper() + ".mp3"
+ name4 = "a_" + unicode(uuid.uuid1())
+ name5 = ""
+
+ cons = ResourceConstraint()
+
+ # All of those names should pass without exceptions
+ cons.validate(name1)
+ cons.validate(name2)
+ cons.validate(name3)
+ cons.validate(name4)
+ cons.validate(name5)
+
+ def test_invalid_names(self):
+ bad_name1 = ".jpg"
+ bad_name2 = "_.jpg"
+ bad_name3 = "_" + unicode(uuid.uuid1())
+
+ cons = ResourceConstraint()
+
+ try:
+ cons.validate(bad_name1)
+ assert False, "%s should not be a valid resource name" % bad_name1
+ except ResourceConstraintError:
+ pass
+
+ try:
+ cons.validate(bad_name2)
+ assert False, "%s should not be a valid resource name" % bad_name2
+ except ResourceConstraintError:
+ pass
+
+ try:
+ cons.validate(bad_name3)
+ assert False, "%s should not be a valid resource name" % bad_name3
+ except ResourceConstraintError:
+ pass
+
if __name__ == "__main__":
unittest.main()
diff --git a/tests/probetests.py b/tests/probetests.py
index 59072e5..bdb9bc9 100644
--- a/tests/probetests.py
+++ b/tests/probetests.py
@@ -90,21 +90,23 @@ class MockProbeProxy(object):
self.MockCB = None
self.MockAlive = True
self.MockEventAddr = None
+ self.MockAddressCallback = None
def isAlive(self):
return self.MockAlive
- def install(self, action, block=False):
+ def install(self, action, callback, block=False):
self.MockAction = action
+ self.MockAddressCallback_install = callback
self.MockActionUpdate = None
return None
- def update(self, action, newaction, block=False):
- self.MockAction = action
+ def update(self, action_address, newaction, block=False):
+ self.MockActionAddress = action_address
self.MockActionUpdate = newaction
return None
- def uninstall(self, action, block=False):
+ def uninstall(self, action_address, block=False):
self.MockAction = None
self.MockActionUpdate = None
return None
@@ -114,7 +116,7 @@ class MockProbeProxy(object):
if not block:
raise RuntimeError("This function does not allow non-blocking mode yet")
- self.MockEvent= event
+ self.MockEvent = event
self.MockCB = callback
return str(id(event))
@@ -343,29 +345,32 @@ class ProbeManagerTest(unittest.TestCase):
act2 = self.probeManager.get_registered_probes_list("act2")[0][1]
ad1 = MockAddon()
+ ad1_address = "Address1"
+ def callback(value):
+ pass
#ErrorCase: install, update, uninstall without currentActivity
#Action functions should do a warning if there is no activity
- self.assertRaises(RuntimeWarning, self.probeManager.install, ad1)
- self.assertRaises(RuntimeWarning, self.probeManager.update, ad1, ad1)
- self.assertRaises(RuntimeWarning, self.probeManager.uninstall, ad1)
+ self.assertRaises(RuntimeWarning, self.probeManager.install, ad1, callback)
+ self.assertRaises(RuntimeWarning, self.probeManager.update, ad1_address, ad1)
+ self.assertRaises(RuntimeWarning, self.probeManager.uninstall, ad1_address)
assert act1.MockAction is None, "Action should not be installed on inactive proxy"
assert act2.MockAction is None, "Action should not be installed on inactive proxy"
self.probeManager.currentActivity = "act1"
- self.probeManager.install(ad1)
+ self.probeManager.install(ad1, callback)
assert act1.MockAction == ad1, "Action should have been installed"
assert act2.MockAction is None, "Action should not be installed on inactive proxy"
- self.probeManager.update(ad1, ad1)
+ self.probeManager.update(ad1_address, ad1)
assert act1.MockActionUpdate == ad1, "Action should have been updated"
assert act2.MockActionUpdate is None, "Should not update on inactive"
self.probeManager.currentActivity = "act2"
- self.probeManager.uninstall(ad1)
- assert act1.MockAction == ad1, "Action should still be installed"
+ self.probeManager.uninstall(ad1_address)
+ assert act1.MockActionAddress == ad1_address, "Action should still be installed"
self.probeManager.currentActivity = "act1"
- self.probeManager.uninstall(ad1)
+ self.probeManager.uninstall(ad1_address)
assert act1.MockAction is None, "Action should be uninstalled"
def test_events(self):
@@ -398,7 +403,6 @@ class ProbeManagerTest(unittest.TestCase):
assert act1.MockEventAddr == "SomeAddress", "Unsubscribe should have been called"
assert act2.MockEventAddr is None, "Unsubscribe should not have been called"
-
class ProbeProxyTest(unittest.TestCase):
def setUp(self):
dbus.SessionBus = MockSessionBus
@@ -422,29 +426,34 @@ class ProbeProxyTest(unittest.TestCase):
action.i, action.s = 5, "action"
action2 = MockAddon()
action2.i, action2.s = 10, "action2"
+ action2_address = "Addr2"
#Check if the installed action is the good one
address = "Addr1"
+
+ def callback(value):
+ pass
+
#Set the return value of probe install
self.mockObj.MockRet["install"] = address
- self.probeProxy.install(action, block=True)
+ self.probeProxy.install(action, callback, block=True)
assert pickle.loads(self.mockObj.MockCall["install"]["args"][0]) == action, "1 argument, the action"
#ErrorCase: Update should fail on noninstalled actions
- self.assertRaises(RuntimeWarning, self.probeProxy.update, action2, action2, block=True)
+ self.assertRaises(RuntimeWarning, self.probeProxy.update, action2_address, action2, block=True)
#Test the update
- self.probeProxy.update(action, action2, block=True)
+ self.probeProxy.update(address, action2, block=True)
args = self.mockObj.MockCall["update"]["args"]
assert args[0] == address, "arg 1 should be the action address"
assert pickle.loads(args[1]) == action2._props, "arg2 should be the new action properties"
#ErrorCase: Uninstall on not installed action (silent fail)
#Test the uninstall
- self.probeProxy.uninstall(action2, block=True)
+ self.probeProxy.uninstall(action2_address, block=True)
assert not "uninstall" in self.mockObj.MockCall, "Uninstall should not be called if action is not installed"
- self.probeProxy.uninstall(action, block=True)
+ self.probeProxy.uninstall(address, block=True)
assert self.mockObj.MockCall["uninstall"]["args"][0] == address, "1 argument, the action address"
def test_events(self):
diff --git a/tests/propertiestests.py b/tests/propertiestests.py
index 2494ea6..cb8e884 100644
--- a/tests/propertiestests.py
+++ b/tests/propertiestests.py
@@ -540,6 +540,62 @@ class TFilePropertyTest(unittest.TestCase):
except FileConstraintError:
pass
+class TResourcePropertyTest(unittest.TestCase):
+ def test_valid_names(self):
+ class klass1(TPropContainer):
+ res = TResourceProperty()
+
+ name1 = "file_" + unicode(uuid.uuid1()) + ".png"
+ name2 = unicode(uuid.uuid1()) + "_" + unicode(uuid.uuid1()) + ".extension"
+ name3 = "/home/user/.sugar/_random/new_image1231_" + unicode(uuid.uuid1()).upper() + ".mp3"
+ name4 = "a_" + unicode(uuid.uuid1())
+ name5 = ""
+
+ obj1 = klass1()
+
+ obj1.res = name1
+ assert obj1.res == name1, "Could not assign the valid name correctly : %s" % name1
+
+ obj1.res = name2
+ assert obj1.res == name2, "Could not assign the valid name correctly : %s" % name2
+
+ obj1.res = name3
+ assert obj1.res == name3, "Could not assign the valid name correctly : %s" % name3
+
+ obj1.res = name4
+ assert obj1.res == name4, "Could not assign the valid name correctly : %s" % name4
+
+ obj1.res = name5
+ assert obj1.res == name5, "Could not assign the valid name correctly : %s" % name5
+
+ def test_invalid_names(self):
+ class klass1(TPropContainer):
+ res = TResourceProperty()
+
+ bad_name1 = ".jpg"
+ bad_name2 = "_.jpg"
+ bad_name3 = "_" + unicode(uuid.uuid1())
+
+ obj1 = klass1()
+
+ try:
+ obj1.res = bad_name1
+ assert False, "A invalid name was accepted : %s" % bad_name1
+ except ResourceConstraintError:
+ pass
+
+ try:
+ obj1.res = bad_name2
+ assert False, "A invalid name was accepted : %s" % bad_name2
+ except ResourceConstraintError:
+ pass
+
+ try:
+ obj1.res = bad_name3
+ assert False, "A invalid name was accepted : %s" % bad_name3
+ except ResourceConstraintError:
+ pass
+
class TAddonPropertyTest(unittest.TestCase):
def test_wrong_value(self):
class klass1(TPropContainer):
diff --git a/tests/translatortests.py b/tests/translatortests.py
new file mode 100644
index 0000000..3b5ca6f
--- /dev/null
+++ b/tests/translatortests.py
@@ -0,0 +1,131 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# 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
+
+import unittest
+import os
+import uuid
+
+from sugar.tutorius.translator import *
+from sugar.tutorius.properties import *
+from sugar.tutorius.tutorial import *
+from sugar.tutorius.vault import Vault
+from sugar.tutorius import addon
+
+##############################################################################
+## Helper classes
+class ResourceAction(TPropContainer):
+ resource = TResourceProperty()
+
+ def __init__(self):
+ TPropContainer.__init__(self)
+
+class NestedResource(TPropContainer):
+ nested = TAddonProperty()
+
+ def __init__(self):
+ TPropContainer.__init__(self)
+ self.nested = ResourceAction()
+
+class ListResources(TPropContainer):
+ nested_list = TAddonListProperty()
+
+ def __init__(self):
+ TPropContainer.__init__(self)
+ self.nested_list = [ResourceAction(), ResourceAction()]
+
+##
+##############################################################################
+
+class ResourceTranslatorTests(unittest.TestCase):
+ temp_path = "/tmp/"
+ file_name = "file.txt"
+
+ def setUp(self):
+ # Generate a tutorial ID
+ self.tutorial_id = unicode(uuid.uuid1())
+
+ # Create a dummy fsm
+ self.fsm = Tutorial("TestTutorial1")
+ # Add a few states
+ act1 = addon.create('BubbleMessage', message="Hi", position=[300, 450])
+ ev1 = addon.create('GtkWidgetEventFilter', "0.12.31.2.2", "clicked")
+ act2 = addon.create('BubbleMessage', message="Second message", position=[250, 150], tail_pos=[1,2])
+ self.fsm.add_action("INIT", act1)
+ st2 = self.fsm.add_state((act2,))
+ self.fsm.add_transition("INIT",(ev1, st2))
+
+ # Create a dummy metadata dictionnary
+ self.test_metadata_dict = {}
+ self.test_metadata_dict['name'] = 'TestTutorial1'
+ self.test_metadata_dict['guid'] = unicode(self.tutorial_id)
+ self.test_metadata_dict['version'] = '1'
+ self.test_metadata_dict['description'] = 'This is a test tutorial 1'
+ self.test_metadata_dict['rating'] = '3.5'
+ self.test_metadata_dict['category'] = 'Test'
+ self.test_metadata_dict['publish_state'] = 'false'
+ activities_dict = {}
+ activities_dict['org.laptop.tutoriusactivity'] = '1'
+ activities_dict['org.laptop,writus'] = '1'
+ self.test_metadata_dict['activities'] = activities_dict
+
+ Vault.saveTutorial(self.fsm, self.test_metadata_dict)
+
+ try:
+ os.mkdir(self.temp_path)
+ except:
+ pass
+ abs_file_path = os.path.join(self.temp_path, self.file_name)
+ new_file = file(abs_file_path, "w")
+
+ # Add the resource in the Vault
+ self.res_name = Vault.add_resource(self.tutorial_id, abs_file_path)
+
+ # Use a dummy prob manager - we shouldn't be using it
+ self.prob_man = object()
+
+ self.translator = ResourceTranslator(self.prob_man, self.tutorial_id)
+
+ def tearDown(self):
+ Vault.deleteTutorial(self.tutorial_id)
+
+ os.unlink(os.path.join(self.temp_path, self.file_name))
+
+ def test_translate(self):
+ # Create an action with a resource property
+ res_action = ResourceAction()
+ res_action.resource = self.res_name
+
+ self.translator.translate(res_action)
+
+ assert getattr(res_action, "resource").type == "file", "Resource was not converted to file"
+
+ assert res_action.resource.default == Vault.get_resource_path(self.tutorial_id, self.res_name), "Transformed resource path is not the same as the one given by the vault"
+
+ def test_recursive_translate(self):
+ nested_action = NestedResource()
+
+ self.translator.translate(nested_action)
+
+ assert getattr(getattr(nested_action, "nested"), "resource").type == "file", "Nested resource was not converted properly"
+
+ def test_list_translate(self):
+ list_action = ListResources()
+
+ self.translator.translate(list_action)
+
+ for container in list_action.nested_list:
+ assert getattr(container, "resource").type == "file", "Element of list was not converted properly"
+
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index b4b1826..d29ddda 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -336,9 +336,11 @@ class ProbeProxy:
@param action Action to uninstall
@param block Force a synchroneous dbus call if True
"""
- for (action, action_address) in self._actions.items():
- remote_call(self._probe.uninstall,(action_address,), block=block)
- del self._actions[action]
+ for (this_action, this_address) in self._actions.items():
+ if this_address == action_address:
+ remote_call(self._probe.uninstall,(action_address,), block=block)
+ del self._actions[this_action]
+ break
def __update_event(self, event, callback, address):
LOGGER.debug("ProbeProxy :: Registered event %s with address %s", str(hash(event)), str(address))