From bbb31f8213d61b7c91d8b17c543d12491dd2df1b Mon Sep 17 00:00:00 2001 From: rcoh Date: Sun, 26 Dec 2010 14:38:25 -0500 Subject: 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. --- behaviors/AllPixelsLeft.py | 1 - tests/TestConfigLoaders.py | 10 ++++++++-- tests/testdata/aParent.xml | 4 ++++ tests/testdata/compositeTEST.xml | 3 +++ tests/testdata/compositeTESTout.xml | 13 +++++++++++++ tests/testdata/compositeTRUTH.xml | 3 +++ tests/testdata/inheritanceTEST.xml | 3 +++ tests/testdata/inheritanceTESTout.xml | 4 ++++ tests/testdata/inheritanceTRUTH.xml | 4 ++++ tests/testdata/override.xml | 5 +++++ util/Config.py | 25 ++++++++++++++++++++++--- 11 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 tests/testdata/aParent.xml create mode 100644 tests/testdata/compositeTESTout.xml create mode 100644 tests/testdata/inheritanceTEST.xml create mode 100644 tests/testdata/inheritanceTESTout.xml create mode 100644 tests/testdata/inheritanceTRUTH.xml 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 @@ + + 1 + 2 + 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 @@ this blah + + appenedA + \ 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 @@ + + + overide parameter + + + taht + this +blah + + + appenedA + + \ 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 @@ this blah + + appenedA + \ 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 @@ + + tests/testdata/aParent.xml + 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 @@ + + 1 + 2 + \ 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 @@ + + 1 + 2 + \ 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 @@ blah + + + appenedA + + 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 -- cgit v1.2.3