Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius
diff options
context:
space:
mode:
authormike <michael.jmontcalm@gmail.com>2009-10-03 14:43:29 (GMT)
committer mike <michael.jmontcalm@gmail.com>2009-10-03 14:43:29 (GMT)
commitc5a4e544e1abf11ffa8378a4a03df92e40137cff (patch)
tree603a64adb1dd28d8aa8f2fb03746a496f447f3d7 /tutorius
parentcf40c1951f4f0f26090226fb4969ca147341a031 (diff)
LP 439980 : Redoing addon list comparison, adding comments
Diffstat (limited to 'tutorius')
-rw-r--r--tutorius/core.py61
-rw-r--r--tutorius/properties.py62
2 files changed, 101 insertions, 22 deletions
diff --git a/tutorius/core.py b/tutorius/core.py
index 41089f1..ff592ad 100644
--- a/tutorius/core.py
+++ b/tutorius/core.py
@@ -261,8 +261,15 @@ class State(object):
def is_identical(self, otherState):
"""
- Compares two states and tells whether they contain the same states and
-
+ Compares two states and tells whether they contain the same states with the
+ same actions and event filters.
+
+ @param otherState The other State that we wish to match
+ @returns True if every action in this state has a matching action in the
+ other state with the same properties and values AND if every
+ event filters in this state has a matching filter in the
+ other state having the same properties and values AND if both
+ states have the same name.
` """
if not isinstance(otherState, State):
return False
@@ -272,27 +279,38 @@ class State(object):
# Do they have the same actions?
if len(self._actions) != len(otherState._actions):
return False
+
+ if len(self._event_filters) != len(otherState._event_filters):
+ return False
+
for act in self._actions:
found = False
+ # For each action in the other state, try to match it with this one.
for otherAct in otherState._actions:
if act.is_identical(otherAct):
found = True
break
if found == False:
+ # If we arrive here, then we could not find an action with the
+ # same values in the other state. We know they're not identical
return False
# Do they have the same event filters?
- if len(self._actions) != len(otherState._actions):
- return False
for event in self._event_filters:
found = False
+ # For every event filter in the other state, try to match it with
+ # the current filter. We just need to find one with the right
+ # properties and values.
for otherEvent in otherState._event_filters:
if event.is_identical(otherEvent):
found = True
break
- if found == False:
+ if found == False:
+ # We could not find the given event filter in the other state.
return False
+ # If nothing failed up to now, then every actions and every filters can
+ # be found in the other state
return True
class FiniteStateMachine(State):
@@ -568,20 +586,25 @@ class FiniteStateMachine(State):
Compares the elements of two FSM to ensure and returns true if they have the
same set of states, containing the same actions and the same event filters.
- @returns True if the two FSMs have the same content false otherwise
+ @returns True if the two FSMs have the same content, False otherwise
"""
if not isinstance(otherFSM, FiniteStateMachine):
return False
+ # Make sure they share the same name
if not (self.name == otherFSM.name) or \
not (self.start_state_name == otherFSM.start_state_name):
return False
-
+
+ # Ensure they have the same number of FSM-level actions
if len(self._actions) != len(otherFSM._actions):
return False
+
# Test that we have all the same FSM level actions
for act in self._actions:
found = False
+ # For every action in the other FSM, try to match it with the
+ # current one.
for otherAct in otherFSM._actions:
if act.is_identical(otherAct):
found = True
@@ -589,16 +612,26 @@ class FiniteStateMachine(State):
if found == False:
return False
+ # Make sure we have the same number of states in both FSMs
if len(self._states) != len(otherFSM._states):
return False
- for state in self._states.itervalues():
- found = False
- for otherState in otherFSM._states.itervalues():
- if state.is_identical(otherState):
- found = True
- break
- if found == False:
+ # For each state, try to find a corresponding state in the other FSM
+ for state_name in self._states.keys():
+ state = self._states[state_name]
+ other_state = None
+ try:
+ # Attempt to use this key in the other FSM. If it's not present
+ # the dictionary will throw an exception and we'll know we have
+ # at least one different state in the other FSM
+ other_state = otherFSM._states[state_name]
+ except:
+ return False
+ # If two states with the same name exist, then we want to make sure
+ # they are also identical
+ if not state.is_identical(other_state):
return False
+ # If we made it here, then all the states in this FSM could be matched to an
+ # identical state in the other FSM.
return True
diff --git a/tutorius/properties.py b/tutorius/properties.py
index 6d30a8d..7bfbad0 100644
--- a/tutorius/properties.py
+++ b/tutorius/properties.py
@@ -96,25 +96,40 @@ class TPropContainer(object):
return object.__getattribute__(self, "_props").keys()
def is_identical(self, otherContainer):
+ """
+ Compare this property container to the other one and returns True only if
+ the every property of the first one can be found in the other container, with
+ the same name and the same value.
+
+ This is an approximation of identity because we are really looking to see
+ if this container is at least a subset of the other.
+
+ @param otherContainer The other container that we wish to test for equality.
+ @returns True if every property in the first container can be found with the same
+ value and the same name in the second container.
+ """
+ # For every property in this container
for prop in self._props.keys():
found = False
+ # Try to match it with another property present in the other container
for otherProp in otherContainer._props.keys():
+ # If we were able to match the name, then we look up the value
if prop == otherProp:
this_type = getattr(type(self), prop).type
other_type = getattr(type(otherContainer), prop).type
if this_type != other_type:
return False
+
+ # If this is an addon list, then we need to make sure that
+ # every element of the list is also present in the other list
if this_type == "addonlist":
- for inner_cont in self._props[prop]:
- inner_found = False
- for other_inner in otherContainer._props[prop]:
- if inner_cont.is_identical(other_inner):
- inner_found = True
- break
- if inner_found == False:
- return False
+ if not self._are_lists_identical(self._props[prop], otherContainer._props[prop]):
+ return False
found = True
break
+
+ # If this is just an embedded / decorated container, then we want to
+ # make sure the sub component are identical.
elif this_type == "addon":
if not self._props[prop].is_identical(otherContainer._props[prop]):
return False
@@ -124,10 +139,41 @@ class TPropContainer(object):
if self._props[prop]== otherContainer._props[prop]:
found = True
break
+ # If we arrive here, then we couldn't find any property in the second
+ # container that matched the current one. We know that the two containers are
+ # not equal.
if found == False:
return False
return True
+ def _are_lists_identical(self, myList, otherList):
+ """
+ Compares two lists of property containers to see if they are identical (
+ they have the same properties
+
+ @param myList The first list of properties containers
+ @param otherList The second list of properties containers
+ @return True if all of the properties inside the list are identical. False otherwise.
+ """
+ # For each property in the first list,
+ for container in myList:
+ found = False
+ # Attempt to match it with every property in the other list
+ for other_container in otherList:
+ # If the containers are identical,
+ if container.is_identical(other_container):
+ # We found a matching container. We don't need to search in the
+ # second list anymore, so we break
+ found = True
+ break
+ # In the case the property was not found inside the second list
+ if found == False:
+ # We know right away that the two lists are not identical
+ return False
+ # If we were able to match each property in the first list, then we
+ # can say the lists are equal.
+ return True
+
class TutoriusProperty(object):
"""
The base class for all actions' properties. The interface is the following :