From 2c29c0111ee94d69d038c22294dfdd1549fdbed3 Mon Sep 17 00:00:00 2001 From: mike Date: Sun, 04 Oct 2009 21:36:50 +0000 Subject: LP 439980 : Adding tests for the is_identical function in the Core, on the FSM and the State --- (limited to 'tests/coretests.py') diff --git a/tests/coretests.py b/tests/coretests.py index f90374f..10cc716 100644 --- a/tests/coretests.py +++ b/tests/coretests.py @@ -28,6 +28,7 @@ and event filters. Those are in their separate test module import unittest +import copy import logging from sugar.tutorius.actions import * from sugar.tutorius.addon import * @@ -49,6 +50,28 @@ class SimpleTutorial(Tutorial): def set_state(self, name): self.current_state_name = name +class TutorialTest(unittest.TestCase): + """Tests the tutorial functions that are not covered elsewhere.""" + def test_detach(self): + class Activity(object): + name = "this" + + activity1 = Activity() + activity2 = Activity() + + fsm = FiniteStateMachine("Sample example") + + tutorial = Tutorial("Test tutorial", fsm) + + assert tutorial.activity == None, "There is a default activity in the tutorial" + + tutorial.attach(activity1) + + assert tutorial.activity == activity1, "Activity should have been associated to this tutorial" + + tutorial.attach(activity2) + assert tutorial.activity == activity2, "Activity should have been changed to activity2" + class TutorialWithFSM(Tutorial): """ Fake tutorial, but associated with a FSM. @@ -201,7 +224,79 @@ class StateTest(unittest.TestCase): assert len(state.get_event_filter_list()) == 0, \ "Could not clear the event filter list properly" + + def test_is_identical_simple(self): + """ + Two empty states with the same name must be identical + """ + st1 = State("Identical") + st2 = State("Identical") + + assert st1.is_identical(st2), "Empty states with the same name should be identical" + + def test_is_identical(self): + """ + Test whether two states share the same set of actions and event filters. + """ + st1 = State("Identical") + st2 = State("Identical") + + non_state = object() + + act1 = addon.create("BubbleMessage", message="Hi", position=[132,450]) + act2 = addon.create("BubbleMessage", message="Hi", position=[132,450]) + + event1 = addon.create("GtkWidgetEventFilter", "nextState", "0.0.0.1.1.2.3.1", "clicked") + + act3 = addon.create("DialogMessage", message="Hello again.", position=[200, 400]) + + # Build the first state + st1.add_action(act1) + st1.add_action(act3) + st1.add_event_filter(event1) + + # Build the second state + st2.add_action(act2) + st2.add_action(act3) + st2.add_event_filter(event1) + + # Make sure that they are identical for now + assert st1.is_identical(st2), "States should be considered as identical" + assert st2.is_identical(st1), "States should be considered as identical" + + # Modify the second bubble message action + act2.message = "New message" + + # Since one action changed in the second state, this should indicate that the states + # are not identical anymore + assert st1.is_identical(st2) == False, "Action was changed and states should be different" + assert st2.is_identical(st1) == False, "Action was changed and states should be different" + + # Make sure that trying to find identity with something else than a State object fails properly + assert st1.is_identical(non_state) == False, "Passing a non-State object should fail for identity" + + st2.name = "Not identical anymore" + assert st1.is_identical(st2) == False, "Different state names should give different states" + st2.name = "Identical" + + st3 = copy.deepcopy(st1) + st3.add_action(addon.create("BubbleMessage", "Hi!", [128,264])) + + assert st1.is_identical(st3) == False, "States having a different number of actions should be different" + + st4 = copy.deepcopy(st1) + st4.add_event_filter(addon.create("GtkWidgetEventFilter", "next_state", "0.0.1.1.2.2.3", "clicked")) + + assert st1.is_identical(st4) == False, "States having a different number of events should be different" + + st5 = copy.deepcopy(st1) + st5._event_filters = [] + st5.add_event_filter(addon.create("GtkWidgetEventFilter", "other_state", "0.1.2.3.4.1.2", "pressed")) + + #import rpdb2; rpdb2.start_embedded_debugger('pass') + assert st1.is_identical(st5) == False, "States having the same number of event filters but those being different should be different" + class FSMTest(unittest.TestCase): """ This class needs to text the interface and functionality of the Finite @@ -246,6 +341,7 @@ class FSMTest(unittest.TestCase): assert act_second.active == False, "FSM did not teardown SECOND properly" + def test_state_insert(self): """ This is a simple test to insert, then find a state. @@ -369,6 +465,112 @@ class FSMTest(unittest.TestCase): undo_count = fsm.get_state_by_name("INIT").get_action_list()[0].undo_count assert fsm.get_state_by_name("INIT").get_action_list()[0].undo_count == 0,\ "The action has been undone unappropriately, undo_count = %d"%undo_count + + def test_setup(self): + fsm = FiniteStateMachine("New state machine") + + try: + fsm.setup() + assert False, "fsm should throw an exception when trying to setup and not bound to a tutorial" + except UnboundLocalError: + pass + + def test_setup_actions(self): + tut = SimpleTutorial() + + states_dict = {"INIT": State("INIT")} + fsm = FiniteStateMachine("New FSM", state_dict=states_dict) + + act = CountAction() + fsm.add_action(act) + + fsm.set_tutorial(tut) + + fsm.setup() + + # Let's also test the current state name + assert fsm.get_current_state_name() == "INIT", "Initial state should be INIT" + + assert act.do_count == 1, "Action should have been called during setup" + + fsm._fsm_has_finished = True + + fsm.teardown() + + assert act.undo_count == 1, "Action should have been undone" + + def test_string_rep(self): + fsm = FiniteStateMachine("Testing machine") + + st1 = State("INIT") + st2 = State("Other State") + st3 = State("Final State") + + st1.add_action(addon.create("BubbleMessage", "Hi!", [132,312])) + + fsm.add_state(st1) + fsm.add_state(st2) + fsm.add_state(st3) + + assert str(fsm) == "INIT, Final State, Other State, " + + def test_is_identical(self): + fsm = FiniteStateMachine("Identity test") + + non_fsm_object = object() + + assert fsm.is_identical(non_fsm_object) == False, "Testing with non FSM object should not give identity" + + # Compare FSMs + act1 = CountAction() + + fsm.add_action(act1) + + fsm2 = copy.deepcopy(fsm) + + assert fsm.is_identical(fsm2) + + act2 = CountAction() + fsm2.add_action(act2) + + assert fsm.is_identical(fsm2) == False, "FSMs having a different number of actions should be different" + + fsm3 = FiniteStateMachine("Identity test") + + act3 = addon.create("BubbleMessage", "Hi!", [123,312]) + fsm3.add_action(act3) + + assert fsm3.is_identical(fsm) == False, "Actions having the same number of actions but different ones should be different" + + st1 = State("INIT") + + st2 = State("OtherState") + + fsm.add_state(st1) + fsm.add_state(st2) + + fsm4 = copy.deepcopy(fsm) + + assert fsm.is_identical(fsm4) + + st3 = State("Last State") + + fsm4.add_state(st3) + + assert fsm.is_identical(fsm4) == False, "FSMs having a different number of states should not be identical" + + fsm4.remove_state("OtherState") + + assert fsm.is_identical(fsm4) == False, "FSMs having different states should be different" + + fsm4.remove_state("Last State") + + st5 = State("OtherState") + st5.add_action(CountAction()) + + fsm4.add_state(st5) + + assert fsm.is_identical(fsm4) == False, "FSMs having states with same name but different content should be different" class FSMExplorationTests(unittest.TestCase): def setUp(self): @@ -425,6 +627,34 @@ class FSMExplorationTests(unittest.TestCase): self.validate_previous_states("Fourth", ("Second")) + def test_is_identical(self): + otherFSM = copy.deepcopy(self.fsm) + + assert self.fsm.is_identical(otherFSM), "Copied FSM was different" + + # Change the name of the second FSM + otherFSM.name = "OtherName" + + assert self.fsm.is_identical(otherFSM) == False, "Name change should make the FSMs different" + + otherFSM.name = self.fsm.name + + # Add an extra state to the second FSM + new_state = State("New State!") + + act1 = addon.create("BubbleMessage", message="This will make the second FSM different", position=[100, 0]) + new_state.add_action(act1) + + otherFSM.add_state(new_state) + + assert self.fsm.is_identical(otherFSM) == False, "The second FSM has an extra state and should not be identical" + + otherFSM.remove_state("New State!") + + # Test difference with one FSM having an FSM-level action + otherFSM.add_action(act1) + + assert self.fsm.is_identical(otherFSM) == False, "The second FSM has an FSM-level action and should be different" if __name__ == "__main__": unittest.main() -- cgit v0.9.1