# Copyright (C) 2009, Tutorius.org # Copyright (C) 2009, Erick Lavoie # # 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 """ Tutorial Tests """ # TODO: Add tests for 47, 52, 55, 109, 132, 175, 209, 229, 233, 271, 274, 292, 295, 318, 337, 375, 394, 411, 428, 446, 480, 491, 624, 637, 698 import unittest from sugar.tutorius.tutorial import * # The following tests are organized around 4 classes: # # Black box tests: # Those tests should limit themselves to exercise the # interface of the object so everything should be tested # only through the interface the object offers. This will # ease test maintenance since we anticipate most changes # will be about the implementation of an object and not # its interface. # # Tests definitions are written assuming the previous tests # did complete correctly so the number of things to assert # is minimal. # # Basic interface cases: # Test the interface of the object for trivial cases # just to assert that the functionality this object # offers really works # # Limit cases: # Test edge cases that cover more obscure usage # scenarios but that should be valid nonetheless # # Error cases: # Test wrong inputs to make sure that the object is hard # to misuse and do generate proper errors # # White box tests: # Those should be used only for really important algorithms # to make sure they behave correctly in every cases, otherwise # the tests will break each time we change something in the # implementation from sugar.tutorius.properties import * class MockAction(TPropContainer): i = TIntProperty(0, 0, 9) class MockEvent(TPropContainer): i = TIntProperty(0, 0, 9) class StateTest(unittest.TestCase): """Test basic functionalities of states used by tutorials""" def setUp(self): self.state = State("State1") self.action = MockAction() self.event = MockEvent() def tearDown(self): pass ######################### Basic interface cases ######################### #### Action def test_add_dummy_action(self): action_name = self.state.add_action("action1") assert action_name assert len(self.state.get_action_dict()) == 1 assert self.state.get_action_dict().has_key(action_name) assert self.state.get_action_dict()[action_name] == "action1" def test_add_generate_unique_action_names(self): action_name1 = self.state.add_action("action1") action_name2 = self.state.add_action("action2") assert action_name1 and action_name2 assert action_name1 != action_name2 def test_update_dummy_action(self): action_name = self.state.add_action(self.action) assert self.action.i == 0 prop = self.action.get_properties_dict_copy() prop["i"] = 2 self.state.update_action(action_name, prop) assert len(self.state.get_action_dict()) == 1 assert self.state.get_action_dict().has_key(action_name) assert self.state.get_action_dict()[action_name].get_properties_dict_copy() == prop def test_delete_dummy_action(self): action_name = self.state.add_action("action1") assert len(self.state.get_action_dict()) == 1 assert self.state.get_action_dict().has_key(action_name) assert self.state.get_action_dict()[action_name] == "action1" self.state.delete_action(action_name) assert len(self.state.get_action_dict()) == 0 def test_delete_all_dummy_actions(self): action_name = self.state.add_action("action1") assert len(self.state.get_action_dict()) == 1 assert self.state.get_action_dict().has_key(action_name) assert self.state.get_action_dict()[action_name] == "action1" self.state.delete_actions() assert len(self.state.get_action_dict()) == 0 #### Transition def test_add_dummy_transition(self): transition_name = self.state.add_transition("transition1") assert len(self.state.get_transition_dict()) == 1 assert self.state.get_transition_dict().has_key(transition_name) assert self.state.get_transition_dict()[transition_name] == "transition1" def test_add_generate_unique_transition_names(self): transition_name1 = self.state.add_transition("transition1") transition_name2 = self.state.add_transition("transition2") assert transition_name1 != transition_name2 def test_update_dummy_transition(self): transition_name = self.state.add_transition((self.event, Tutorial.END)) assert self.event.i == 0 prop = self.event.get_properties_dict_copy() prop["i"] = 2 self.state.update_transition(transition_name, prop) assert len(self.state.get_transition_dict()) == 1 assert self.state.get_transition_dict().has_key(transition_name) assert self.state.get_transition_dict()[transition_name][0].get_properties_dict_copy() == prop assert self.state.get_transition_dict()[transition_name][1] == Tutorial.END # Now update only the transition self.state.update_transition(transition_name, new_state=Tutorial.INIT) assert self.state.get_transition_dict()[transition_name][0].get_properties_dict_copy() == prop assert self.state.get_transition_dict()[transition_name][1] == Tutorial.INIT def test_delete_dummy_transition(self): transition_name = self.state.add_transition("transition1") assert len(self.state.get_transition_dict()) == 1 assert self.state.get_transition_dict().has_key(transition_name) assert self.state.get_transition_dict()[transition_name] == "transition1" self.state.delete_transition(transition_name) assert len(self.state.get_transition_dict()) == 0 def test_delete_all_dummy_transitions(self): transition_name = self.state.add_transition("transition1") assert len(self.state.get_transition_dict()) == 1 assert self.state.get_transition_dict().has_key(transition_name) assert self.state.get_transition_dict()[transition_name] == "transition1" self.state.delete_transitions() assert len(self.state.get_transition_dict()) == 0 ######################### Limit cases ################################### #### Action #### Transition ######################### Error cases ################################### #### Action def test_update_unknown_action(self): try: self.state.update_action("unknown_name", "action") assert False except LookupError: pass def test_delete_unknown_action(self): try: self.state.delete_action("unknown_name") assert False except LookupError: pass #### Transition def test_add_existing_transition(self): self.state.add_transition("transition") try: self.state.add_transition("transition") assert False except TransitionAlreadyExists: pass class TutorialTest(unittest.TestCase): """Test tutorial functionality""" def setUp(self): self.tutorial = Tutorial("Tutorial Test") self.action = MockAction() self.event = MockEvent() def tearDown(self): pass ######################### Basic interface cases ######################### #### Tutorial def test_default_initial_value_in_tutorial(self): assert len(self.tutorial.get_state_dict()) == 2 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END]) assert len(self.tutorial.get_action_dict()) == 0 assert len(self.tutorial.get_transition_dict()) == 1 assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {} assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END] assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT] assert self.tutorial.get_following_states_dict(Tutorial.END) == {} #### State def test_add_default_state(self): state_name = self.tutorial.add_state() assert state_name assert len(self.tutorial.get_state_dict()) == 3 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name]) assert len(self.tutorial.get_action_dict()) == 0 assert len(self.tutorial.get_transition_dict()) == 1 def test_add_state_with_action(self): state_name = self.tutorial.add_state(action_list=["action1"]) assert state_name assert len(self.tutorial.get_state_dict()) == 3 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name]) assert len(self.tutorial.get_action_dict()) == 1 assert len(self.tutorial.get_transition_dict()) == 1 def test_add_state_with_transition(self): state_name = self.tutorial.add_state(transition_list=[("event1",Tutorial.END)]) assert state_name assert len(self.tutorial.get_state_dict()) == 3 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name]) assert len(self.tutorial.get_action_dict()) == 0 assert len(self.tutorial.get_transition_dict()) == 2 def test_add_generate_unique_state_names(self): state_name1 = self.tutorial.add_state() state_name2 = self.tutorial.add_state() assert state_name1 and state_name2 assert state_name1 != state_name2 def test_delete_lone_state(self): state_name1 = self.tutorial.add_state() self.tutorial.delete_state(state_name1) assert len(self.tutorial.get_state_dict()) == 2 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END]) assert len(self.tutorial.get_action_dict()) == 0 assert len(self.tutorial.get_transition_dict()) == 1 assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {} assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END] assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT] assert self.tutorial.get_following_states_dict(Tutorial.END) == {} def test_delete_linked_state(self): state_name1 = self.tutorial.add_state() self.tutorial.update_transition(Tutorial.INITIAL_TRANSITION_NAME, \ None, state_name1) transition_name1 = self.tutorial.add_transition(state_name1,("event1", Tutorial.END)) self.tutorial.delete_state(state_name1) assert len(self.tutorial.get_state_dict()) == 2 assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END]) assert len(self.tutorial.get_action_dict()) == 0 assert len(self.tutorial.get_transition_dict()) == 1 assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {} assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END] assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT] assert self.tutorial.get_following_states_dict(Tutorial.END) == {} #### Action def test_add_dummy_action(self): state_name = self.tutorial.add_state() action_name = self.tutorial.add_action(state_name,"action1") assert action_name assert len(self.tutorial.get_action_dict()) == 1 assert self.tutorial.get_action_dict().has_key(action_name) assert self.tutorial.get_action_dict()[action_name] == "action1" def test_add_generate_unique_action_names(self): state_name = self.tutorial.add_state() action_name1 = self.tutorial.add_action(state_name,"action1") action_name2 = self.tutorial.add_action(state_name,"action2") assert action_name1 and action_name2 assert action_name1 != action_name2 def test_update_dummy_action(self): state_name = self.tutorial.add_state() action_name = self.tutorial.add_action(state_name,self.action) prop = self.action.get_properties_dict_copy() prop["i"] = 2 self.tutorial.update_action(action_name, prop) assert len(self.tutorial.get_action_dict()) == 1 assert self.tutorial.get_action_dict().has_key(action_name) assert self.tutorial.get_action_dict()[action_name].get_properties_dict_copy() == prop def test_delete_dummy_action(self): state_name = self.tutorial.add_state() action_name = self.tutorial.add_action(state_name,"action1") assert len(self.tutorial.get_action_dict()) == 1 assert self.tutorial.get_action_dict().has_key(action_name) assert self.tutorial.get_action_dict()[action_name] == "action1" self.tutorial.delete_action(action_name) assert len(self.tutorial.get_action_dict()) == 0 #### Transition def test_add_dummy_transition(self): state_name = self.tutorial.add_state() transition_name = self.tutorial.add_transition(state_name,"transition1") assert len(self.tutorial.get_transition_dict()) == 2 assert self.tutorial.get_transition_dict().has_key(transition_name) assert self.tutorial.get_transition_dict()[transition_name] == "transition1" def test_add_generate_unique_transition_names(self): state_name = self.tutorial.add_state() transition_name1 = self.tutorial.add_transition(state_name,"transition1") transition_name2 = self.tutorial.add_transition(state_name,"transition2") assert transition_name1 and transition_name2 assert transition_name1 != transition_name2 def test_update_dummy_transition(self): state_name = self.tutorial.add_state() transition_name = self.tutorial.add_transition(state_name,(self.event, Tutorial.END)) prop = self.event.get_properties_dict_copy() prop["i"] = 2 self.tutorial.update_transition(transition_name, prop) assert len(self.tutorial.get_transition_dict()) == 2 assert self.tutorial.get_transition_dict().has_key(transition_name) assert self.tutorial.get_transition_dict()[transition_name][0].get_properties_dict_copy() == prop assert self.tutorial.get_transition_dict()[transition_name][1] == Tutorial.END # Now update only the transition self.tutorial.update_transition(transition_name, new_state=Tutorial.INIT) assert self.tutorial.get_transition_dict()[transition_name][0].get_properties_dict_copy() == prop assert self.tutorial.get_transition_dict()[transition_name][1] == Tutorial.INIT def test_delete_dummy_transition(self): state_name = self.tutorial.add_state() transition_name = self.tutorial.add_transition(state_name,"transition1") assert len(self.tutorial.get_transition_dict()) == 2 assert self.tutorial.get_transition_dict().has_key(transition_name) assert self.tutorial.get_transition_dict()[transition_name] == "transition1" self.tutorial.delete_transition(transition_name) assert len(self.tutorial.get_transition_dict()) == 1 ######################### Limit cases ################################### #### Tutorial #### State #### Action #### Transition ######################### Error cases ################################### #### Tutorial #### State #### Action def test_update_unknown_action(self): lookup_error = None try: self.tutorial.update_action("unknown_name", "action") except LookupError, e: lookup_error = e assert lookup_error def test_delete_unknown_action(self): lookup_error = None try: self.tutorial.delete_action("unknown_name") except LookupError, e: lookup_error = e assert lookup_error #### Transition def test_add_existing_transition(self): self.tutorial.add_transition(Tutorial.INIT,("event","transition")) transition_exists_error = None try: self.tutorial.add_transition(Tutorial.INIT,("event","transition")) except TransitionAlreadyExists, e: transition_exists_error = e assert transition_exists_error if __name__ == "__main__": unittest.main()