aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar rcoh <rcoh@mit.edu>2010-12-26 14:38:25 -0500
committerGravatar rcoh <rcoh@mit.edu>2010-12-26 14:38:25 -0500
commitbbb31f8213d61b7c91d8b17c543d12491dd2df1b (patch)
tree587be5cb3b64fb5797dc311ac082e3e7503635c2
parentb09a41f0891c041ad4fcecca59d03f52fe9ee9e8 (diff)
a bugfix in APL. Support and a unit test for behavior inheritance. It now happens automatically
when the config is loaded. Simply use Config.loadConfigFile(fileName) to leverage the functionality.
-rw-r--r--behaviors/AllPixelsLeft.py1
-rw-r--r--tests/TestConfigLoaders.py10
-rw-r--r--tests/testdata/aParent.xml4
-rw-r--r--tests/testdata/compositeTEST.xml3
-rw-r--r--tests/testdata/compositeTESTout.xml13
-rw-r--r--tests/testdata/compositeTRUTH.xml3
-rw-r--r--tests/testdata/inheritanceTEST.xml3
-rw-r--r--tests/testdata/inheritanceTESTout.xml4
-rw-r--r--tests/testdata/inheritanceTRUTH.xml4
-rw-r--r--tests/testdata/override.xml5
-rw-r--r--util/Config.py25
11 files changed, 69 insertions, 6 deletions
diff --git a/behaviors/AllPixelsLeft.py b/behaviors/AllPixelsLeft.py
index 0c66f2f..e1f4080 100644
--- a/behaviors/AllPixelsLeft.py
+++ b/behaviors/AllPixelsLeft.py
@@ -5,6 +5,5 @@ class AllPixelsLeft(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
for sensory in sensorInputs:
xLoc = sensory['Location'][0]
- if type(xLoc) == type(tuple()):
sensory['Location'] = '[{x}<' + str(xLoc) + ']'
return (sensorInputs, recursiveInputs)
diff --git a/tests/TestConfigLoaders.py b/tests/TestConfigLoaders.py
index 73b4987..17fc2d9 100644
--- a/tests/TestConfigLoaders.py
+++ b/tests/TestConfigLoaders.py
@@ -18,8 +18,14 @@ class TestConfigLoaders(unittest.TestCase):
result = Config.compositeXMLTrees(parent,overrider)
result = ElementTree(result)
- result.write('tests/testdata/compositeTEST.xml')
- assert filecmp.cmp('tests/testdata/compositeTEST.xml','tests/testdata/compositeTRUTH.xml')
+ result.write('tests/testdata/compositeTESTout.xml')
+ assert filecmp.cmp('tests/testdata/compositeTESTout.xml','tests/testdata/compositeTRUTH.xml')
+ def test_inheritance(self):
+ result = Config.loadConfigFile('tests/testdata/inheritanceTEST.xml')
+
+ result.write('tests/testdata/inheritanceTESTout.xml')
+ assert filecmp.cmp('tests/testdata/inheritanceTESTout.xml',\
+ 'tests/testdata/inheritanceTRUTH.xml')
if __name__ == '__main__':
unittest.main()
diff --git a/tests/testdata/aParent.xml b/tests/testdata/aParent.xml
new file mode 100644
index 0000000..b07c192
--- /dev/null
+++ b/tests/testdata/aParent.xml
@@ -0,0 +1,4 @@
+<A>
+ <param1>1</param1>
+ <param2>2</param2>
+</A>
diff --git a/tests/testdata/compositeTEST.xml b/tests/testdata/compositeTEST.xml
index ded1666..435b75a 100644
--- a/tests/testdata/compositeTEST.xml
+++ b/tests/testdata/compositeTEST.xml
@@ -7,4 +7,7 @@
<that>this</that>
<SomeNewParam>blah</SomeNewParam>
</B>
+<A>
+ <someparam>appenedA</someparam>
+ </A>
</Override> \ No newline at end of file
diff --git a/tests/testdata/compositeTESTout.xml b/tests/testdata/compositeTESTout.xml
new file mode 100644
index 0000000..435b75a
--- /dev/null
+++ b/tests/testdata/compositeTESTout.xml
@@ -0,0 +1,13 @@
+<Override>
+<A>
+ <override>overide parameter</override>
+</A>
+<B OverrideBehavior="Merge">
+ <this>taht</this>
+ <that>this</that>
+<SomeNewParam>blah</SomeNewParam>
+</B>
+<A>
+ <someparam>appenedA</someparam>
+ </A>
+</Override> \ No newline at end of file
diff --git a/tests/testdata/compositeTRUTH.xml b/tests/testdata/compositeTRUTH.xml
index ded1666..435b75a 100644
--- a/tests/testdata/compositeTRUTH.xml
+++ b/tests/testdata/compositeTRUTH.xml
@@ -7,4 +7,7 @@
<that>this</that>
<SomeNewParam>blah</SomeNewParam>
</B>
+<A>
+ <someparam>appenedA</someparam>
+ </A>
</Override> \ No newline at end of file
diff --git a/tests/testdata/inheritanceTEST.xml b/tests/testdata/inheritanceTEST.xml
new file mode 100644
index 0000000..c2efd71
--- /dev/null
+++ b/tests/testdata/inheritanceTEST.xml
@@ -0,0 +1,3 @@
+<A>
+ <InheritsFrom>tests/testdata/aParent.xml</InheritsFrom>
+</A>
diff --git a/tests/testdata/inheritanceTESTout.xml b/tests/testdata/inheritanceTESTout.xml
new file mode 100644
index 0000000..ffa6667
--- /dev/null
+++ b/tests/testdata/inheritanceTESTout.xml
@@ -0,0 +1,4 @@
+<A>
+ <param1>1</param1>
+ <param2>2</param2>
+</A> \ No newline at end of file
diff --git a/tests/testdata/inheritanceTRUTH.xml b/tests/testdata/inheritanceTRUTH.xml
new file mode 100644
index 0000000..ffa6667
--- /dev/null
+++ b/tests/testdata/inheritanceTRUTH.xml
@@ -0,0 +1,4 @@
+<A>
+ <param1>1</param1>
+ <param2>2</param2>
+</A> \ No newline at end of file
diff --git a/tests/testdata/override.xml b/tests/testdata/override.xml
index 5d703ed..1108fb0 100644
--- a/tests/testdata/override.xml
+++ b/tests/testdata/override.xml
@@ -5,4 +5,9 @@
<B OverrideBehavior="Merge">
<SomeNewParam>blah</SomeNewParam>
</B>
+<APPEND>
+ <A>
+ <someparam>appenedA</someparam>
+ </A>
+</APPEND>
</Override>
diff --git a/util/Config.py b/util/Config.py
index 36ff104..33e6fee 100644
--- a/util/Config.py
+++ b/util/Config.py
@@ -8,23 +8,28 @@ def loadParamRequirementDict(className):
if not className in classArgsMem: #WOO CACHING
classArgsMem[className] = fileToDict(CONFIG_PATH + className)
return classArgsMem[className]
+#Loads a config file. If its an xml file, inheritances are automatically resolved.
def loadConfigFile(fileName): #TODO: error handling etc.
#try:
- fileName = CONFIG_PATH + fileName
+ #fileName = CONFIG_PATH + fileName
if '.params' in fileName:
return fileToDict(fileName)
if '.xml' in fileName:
config = ElementTree() #use .fromstring, and resolve xincludes
config.parse(fileName)
+ config = ElementTree(resolveConfigInheritance(config.getroot()))
return config
#except:
return None
+#Takes an Element or an ElementTree. If it is a tree, it returns its root. Otherwise, just returns
+#it
def getElement(el):
if xml.etree.ElementTree.iselement(el):
return el
elif el.__class__ == ElementTree:
return el.getroot()
-def compositeXMLTrees(parentTree, overridingTree):
+def compositeXMLTrees(parentTree, overridingTree): #TODO: break up into sub-methods, change it to
+#use .find()
#type checking -- convert ElementTrees to their root elements
parentTree = getElement(parentTree)
overridingTree = getElement(overridingTree)
@@ -45,12 +50,18 @@ def compositeXMLTrees(parentTree, overridingTree):
if Strings.OVERRIDE_BEHAVIOR in interEl.attrib:
mode = interEl.attrib[Strings.OVERRIDE_BEHAVIOR]
if mode != 'Replace' and mode != 'Merge':
- print 'Bad Mode. Replacing'
+ print 'Bad Mode. Choosing to replace.'
mode = 'Replace'
if mode == 'Replace':
pass #we don't need to do anything
if mode == 'Merge':
interEl = compositeXMLTrees(item, interEl)
+ for item in overrideItems: #resolve appendages
+ if item.tag == 'APPEND':
+ children = item.getchildren()
+ for child in children:
+ overrideItems.insert(-1, child)
+ overrideItems.remove(item)
return overridingTree
def findElementsByTag(tag, eList):
return [el for el in eList if el.tag == tag]
@@ -89,3 +100,11 @@ def generateArgDict(parentNode, recurse=False):
if len(args.keys()) == 1 and recurse:
return args[args.keys()[0]]
return args
+
+def resolveConfigInheritance(el):
+ parentClass = el.find('InheritsFrom')
+ if parentClass != None:
+ parentTree = loadConfigFile(parentClass.text)
+ el = compositeXMLTrees(el, parentTree)
+ el.remove(parentClass) #get rid of the inheritance flag
+ return el