From 2bda2c8c50797a6214126edc5afdc3fc5d8e9969 Mon Sep 17 00:00:00 2001 From: Vincent Vinet Date: Sun, 06 Dec 2009 19:43:16 +0000 Subject: improve coverage report and cleanup old stuff --- (limited to 'tests') diff --git a/tests/coretests.py b/tests/coretests.py deleted file mode 100644 index 1cc5431..0000000 --- a/tests/coretests.py +++ /dev/null @@ -1,629 +0,0 @@ -# Copyright (C) 2009, Tutorius.org -# Copyright (C) 2009, Michael Janelle-Montcalm -# -# 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. - -Usage of actions and event filters is tested, but not the concrete actions -and event filters. Those are in their separate test module - -""" - -import unittest - -from copy import deepcopy -import logging -from sugar.tutorius.actions import * -from sugar.tutorius.addon import * -from sugar.tutorius.core import * -from sugar.tutorius.filters import * - -from actiontests import CountAction, FakeEventFilter - -# 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 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. - """ - def __init__(self, start_name="INIT", fsm=None): - Tutorial.__init__(self, start_name, fsm) - self.activity = activity.Activity() - -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): - Action.__init__(self) - self.active = False - - def do(self): - self.active = True - - def undo(self): - self.active = False - -# 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 = addon.create('TriggerEventFilter') - - state = State("event_test", event_filter_list=[(event_filter, "second_state")]) - 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 - - def test_add_action(self): - """ - Tests on manipulating the actions inside a state. - """ - state = State("INIT") - - act1 = CountAction() - act2 = CountAction() - act3 = CountAction() - - # Try to add the actions - assert state.add_action(act1), "Could not add the first action" - assert state.add_action(act2), "Could not add the second action" - assert state.add_action(act3), "Could not add the third action" - - # Fetch the associated actions - actions = state.get_action_list() - - # Make sure all the actions are present in the state - assert act1 in actions and act2 in actions and act3 in actions, \ - "The actions were not properly inserted in the state" - - # Clear the list - state.clear_actions() - - # Make sure the list of actions is empty now - assert len(state.get_action_list()) == 0, "Clearing of actions failed" - - def test_add_event_filter(self): - state = State("INIT") - - event1 = addon.create('TriggerEventFilter') - event2 = addon.create('TriggerEventFilter') - - # Insert the event filters - assert state.add_event_filter(event1, "s"), "Could not add event filter 1" - - # Make sure we cannot insert an event twice - assert state.add_event_filter(event1, "s") == False, "Could add twice the event filter" - assert state.add_event_filter(event2, "t") == False, "Could add event filter 2" - - # Get the list of event filters - event_filters = map(lambda x: x[0],state.get_event_filter_list()) - - #even if we added only the event 1, they are equivalent - assert event1 in event_filters and event2 in event_filters, \ - "The event filters were not all added inside the state" - - # Clear the list - state.clear_event_filters() - - assert len(state.get_event_filter_list()) == 0, \ - "Could not clear the event filter list properly" - - def test_eq_simple(self): - """ - Two empty states with the same name must be identical - """ - st1 = State("Identical") - st2 = State("Identical") - - assert st1 == st2, "Empty states with the same name should be identical" - - def test_eq(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", object_id="0.0.0.1.1.2.3.1", event_name="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, "nextState") - - # Build the second state - st2.add_action(act2) - st2.add_action(act3) - st2.add_event_filter(event1, "nextState") - - # Make sure that they are identical for now - assert st1 == st2, "States should be considered as identical" - assert st2 == 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 not (st1 == st2), "Action was changed and states should be different" - assert not (st2 == st1), "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 not (st1 == non_state), "Passing a non-State object should fail for identity" - - st2.name = "Not identical anymore" - assert not(st1 == st2), "Different state names should give different states" - st2.name = "Identical" - - st3 = deepcopy(st1) - st3.add_action(addon.create("BubbleMessage", message="Hi!", position=[128,264])) - - assert not (st1 == st3), "States having a different number of actions should be different" - - st4 = deepcopy(st1) - st4.add_event_filter(addon.create("GtkWidgetEventFilter", object_id="0.0.1.1.2.2.3", event_name="clicked"), "next_state") - - assert not (st1 == st4), "States having a different number of events should be different" - - st5 = deepcopy(st1) - st5._event_filters = [] - - st5.add_event_filter(addon.create("GtkWidgetEventFilter", object_id="0.1.2.3.4.1.2", event_name="pressed"), "other_state") - - assert not (st1 == st5), "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 - State Machine. - """ - - def test_sample_usage(self): - act_init = TrueWhileActiveAction() - act_second = TrueWhileActiveAction() - - event_init = FakeEventFilter() - - content = { - "INIT": State("INIT", action_list=[act_init],event_filter_list=[(event_init,"SECOND")]), - "SECOND": State("SECOND", action_list=[act_second]) - } - - fsm = FiniteStateMachine("SampleUsage", state_dict=content) - - assert fsm is not None, "Unable to create FSM" - - tut = Tutorial("SampleUsageTutorial", fsm) - - tut.attach(None) - event_init.set_tutorial(tut) - - assert fsm.current_state.name == "INIT", "Unable to set state to initial state" - - assert act_init.active, "FSM did not call the state's action DO properly" - - # Trigger the event of the INIT state - event_init.do_callback() - - assert act_init.active == False, "FSM did not teardown INIT properly" - - assert fsm.current_state.name == "SECOND", "FSM did not switch to SECOND state" - - assert act_second.active == True, "FSM did not setup SECOND properly" - - tut.detach() - - 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. - """ - st1 = State("FakeState") - - fsm = FiniteStateMachine("StateInsertTest") - - fsm.add_state(st1) - - inserted_state = fsm.get_state_by_name(st1.name) - - assert inserted_state is st1, "Inserting, then fetching a state did not work" - - # Make sure we cannot insert it twice - try : - fsm.add_state(st1) - assert False, "No error raised on addition of an already present state" - except KeyError: - pass - - def test_state_find_by_name(self): - """ - Tests the interface for fetching a state by name. - - Basic functionnality - - Non-existent state - """ - - st1 = State("INIT") - - st2 = State("second") - - fsm = FiniteStateMachine("StateFindTest") - - fsm.add_state(st1) - fsm.add_state(st2) - - # Test the fetch by name - fetched_st1 = fsm.get_state_by_name(st1.name) - - assert fetched_st1 is st1, "Fetched state is not the same as the inserted one" - - fetched_st2 = fsm.get_state_by_name(st2.name) - - assert fetched_st2 is st2, "Fetched state is not the same as the inserted one" - - try: - fsm.get_state_by_name("no such state") - assert False, "Did not get a KeyError on non-existing key search" - except KeyError: - pass - except Exception: - assert False, "Did not get the right error on non-existing key search" - - def test_state_removal(self): - """ - This test removes a state from the FSM. It also verifies that the links - from other states going into the removed state are gone. - """ - st1 = State("INIT", event_filter_list=[(addon.create('TriggerEventFilter'), "second")]) - st2 = State("second", event_filter_list=[(addon.create('TriggerEventFilter'), "third")]) - st3 = State("third", event_filter_list=[(addon.create('TriggerEventFilter'), "second")]) - - fsm = FiniteStateMachine("StateRemovalTest") - - fsm.add_state(st1) - fsm.add_state(st2) - fsm.add_state(st3) - - # First tests - Removing a non-existing state and make sure we get a - # KeyError - try: - fsm.remove_state("Non-existing") - assert False, "Removing a non-existing state did not throw a KeyError" - except KeyError: - pass - except Exception: - assert False, "Removing a non-existing state dit not throw the right kind of exception" - - # Now try removing the second state - fsm.remove_state("second") - - # Make sure it cannot be fetched - try : - fetched_state = fsm.get_state_by_name("second") - assert False, "The supposedly removed state is still present in the FSM" - except KeyError: - pass - - # Make sure that there is no link to the removed state in the rest - # of the FSM - assert "second" not in fsm.get_following_states("INIT"), \ - "The link to second from INIT still exists after removal" - - assert "second" not in fsm.get_following_states("third"), \ - "The link to second from third still exists after removal" - - def test_set_same_state(self): - fsm = FiniteStateMachine("Set same state") - - st1 = State("INIT") - st1.add_action(CountAction()) - - fsm.add_state(st1) - - tut = SimpleTutorial() - - fsm.set_tutorial(tut) - - fsm.set_state("INIT") - - assert fsm.get_state_by_name("INIT").get_action_list()[0].do_count == 1, \ - "The action was not triggered on 'INIT'" - - fsm.set_state("INIT") - - do_count = fsm.get_state_by_name("INIT").get_action_list()[0].do_count - assert fsm.get_state_by_name("INIT").get_action_list()[0].do_count == 1, \ - "The action was triggered a second time, do_count = %d"%do_count - - 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", message="Hi!", position=[132,312])) - - fsm.add_state(st1) - fsm.add_state(st2) - fsm.add_state(st3) - - assert str(fsm) == "INIT, Final State, Other State, " - - def test_eq_(self): - fsm = FiniteStateMachine("Identity test") - - non_fsm_object = object() - - assert not (fsm == non_fsm_object), "Testing with non FSM object should not give identity" - - # Compare FSMs - act1 = CountAction() - - fsm.add_action(act1) - - fsm2 = deepcopy(fsm) - - assert fsm == fsm2 - - act2 = CountAction() - fsm2.add_action(act2) - - assert not(fsm == fsm2), \ - "FSMs having a different number of actions should be different" - - fsm3 = FiniteStateMachine("Identity test") - - act3 = addon.create("BubbleMessage", message="Hi!", position=[123,312]) - fsm3.add_action(act3) - - assert not(fsm3 == fsm), \ - "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 = deepcopy(fsm) - - assert fsm == fsm4 - - st3 = State("Last State") - - fsm4.add_state(st3) - - assert not (fsm == fsm4), "FSMs having a different number of states should not be identical" - - fsm4.remove_state("OtherState") - - assert not (fsm == fsm4), "FSMs having different states should be different" - - fsm4.remove_state("Last State") - - st5 = State("OtherState") - st5.add_action(CountAction()) - - fsm4.add_state(st5) - - assert not(fsm == fsm4), "FSMs having states with same name but different content should be different" - -class FSMExplorationTests(unittest.TestCase): - def setUp(self): - self.buildFSM() - - def buildFSM(self): - """ - Create a sample FSM to play with in the rest of the tests. - """ - st1 = State("INIT") - st1.add_action(CountAction()) - st1.add_event_filter(addon.create('TriggerEventFilter'), "Second") - st1.add_event_filter(addon.create('TriggerEventFilter'), "Third") - - st2 = State("Second") - st2.add_action(TrueWhileActiveAction()) - st2.add_event_filter(addon.create('TriggerEventFilter'), "Third") - st2.add_event_filter(addon.create('TriggerEventFilter'), "Fourth") - - st3 = State("Third") - st3.add_action(CountAction()) - st3.add_action(TrueWhileActiveAction()) - - self.fsm = FiniteStateMachine("ExplorationTestingMachine") - self.fsm.add_state(st1) - self.fsm.add_state(st2) - self.fsm.add_state(st3) - - def validate_following_states(self, in_name, out_name_list): - nextStates = self.fsm.get_following_states(in_name) - assert list(nextStates).sort() == list(out_name_list).sort(), \ - "The following states for %s are wrong : got %s"%\ - (in_name, str(nextStates)) - - def validate_previous_states(self, in_name, out_name_list): - prevStates = self.fsm.get_previous_states(in_name) - assert list(prevStates).sort() == list(out_name_list).sort(), \ - "The following states for %s are wrong : got %s"%\ - (in_name, str(prevStates)) - - def test_get_following_states(self): - self.validate_following_states("INIT", ('Second', 'Third')) - - self.validate_following_states("Second", ("Third", "Fourth")) - - self.validate_following_states("Third", ()) - - def test_get_previous_states(self): - self.validate_previous_states("INIT", ()) - - self.validate_previous_states("Second", ("INIT")) - - self.validate_previous_states("Third", ("INIT", "Second")) - - self.validate_previous_states("Fourth", ("Second")) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/skip b/tests/skip index 028ecaf..3868383 100644 --- a/tests/skip +++ b/tests/skip @@ -2,4 +2,3 @@ utils.py run-tests.py overlaytests.py viewer.py -coretests.py -- cgit v0.9.1