def test_dsl_factory(self): factory = DSLFactory() factory2 = DSLFactory() # test of singleton factory behavior self.assertIs(factory, factory2) a = factory.from_file( "/home/robolab/robocomp/components/euroage-tv/components/tvGames/gamestatemachine.smdsl" ) # test for cached query b = factory.from_file( "/home/robolab/robocomp/components/euroage-tv/components/tvGames/gamestatemachine.smdsl" ) self.assertIs(a, b) c = factory.from_file( "/home/robolab/robocomp/interfaces/IDSLs/JointMotor.idsl") # test for cached query d = factory.from_file( "/home/robolab/robocomp/interfaces/IDSLs/JointMotor.idsl") self.assertIs(c, d) e = factory.from_file( "/home/robolab/robocomp/tools/robocompdsl/component_generation_test/customStateMachinePython/test.cdsl" ) # test for cached query f = factory.from_file( "/home/robolab/robocomp/tools/robocompdsl/component_generation_test/customStateMachinePython/test.cdsl" ) self.assertIs(e, f)
class DSLFactoryTestCase(unittest.TestCase): def setUp(self): self.maxDiff = None self.factory = DSLFactory() def assertNestedDictEqual(self, first, second, ignored_keys=None, msg=None): if ignored_keys is not None: first = copy.deepcopy(first) second = copy.deepcopy(second) for key in ignored_keys: if key in first: del first[key] if key in second: del second[key] j1 = json.dumps(first, sort_keys=True, indent=4) j2 = json.dumps(second, sort_keys=True, indent=4) self.maxDiff = None # with open('last_json1.txt', 'w') as outfile: # json.dump(first, outfile, sort_keys=True, indent=4) # with open('last_json2.txt', 'w') as outfile: # json.dump(second, outfile, sort_keys=True, indent=4) self.assertEqual(j1, j2, msg) def test_factory_singleton(self): factory2 = DSLFactory() self.assertIs(self.factory, factory2) def test_factory_smdsl(self): a = self.factory.from_file(os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl")) self.assertDictEqual(a, { 'machine': { 'name': 'application_machine', 'default': False, 'contents': { 'states': None, 'finalstate': 'app_end', 'initialstate': 'game_machine', 'transitions': [ {'src': 'game_machine', 'dests': ['app_end']}] } }, 'substates': [ { 'parallel': False, 'parent': 'game_machine', 'contents': { 'states': [ 'session_init', 'game_start_wait', 'game_init', 'game_loop', 'game_pause', 'game_resume', 'game_reset', 'game_end', 'game_won', 'game_lost', 'session_end'], 'finalstate': None, 'initialstate': 'session_start_wait', 'transitions': [ {'src': 'session_start_wait', 'dests': ['session_init']}, {'src': 'session_init', 'dests': ['game_start_wait']}, {'src': 'game_start_wait', 'dests': ['game_start_wait']}, {'src': 'game_start_wait', 'dests': ['game_init']}, {'src': 'game_start_wait', 'dests': ['session_end']}, {'src': 'session_end', 'dests': ['session_start_wait']}, {'src': 'game_init', 'dests': ['game_loop']}, {'src': 'game_loop', 'dests': ['game_loop', 'game_pause', 'game_won', 'game_lost', 'game_end']}, {'src': 'game_pause', 'dests': ['game_loop']}, {'src': 'game_pause', 'dests': ['game_reset']}, {'src': 'game_pause', 'dests': ['game_resume']}, {'src': 'game_pause', 'dests': ['game_end']}, {'src': 'game_resume', 'dests': ['game_loop']}, {'src': 'game_end', 'dests': ['game_lost']}, {'src': 'game_end', 'dests': ['game_won']}, {'src': 'game_lost', 'dests': ['game_start_wait']}, {'src': 'game_won', 'dests': ['game_start_wait']}, {'src': 'game_reset', 'dests': ['game_start_wait']} ] } }, { 'parallel': False, 'parent': 'session_init', 'contents': { 'states': [ 'player_acquisition_loop'], 'finalstate': 'player_acquisition_ended', 'initialstate': 'player_acquisition_init', 'transitions': [ {'src': 'player_acquisition_init', 'dests': ['player_acquisition_loop']}, {'src': 'player_acquisition_loop', 'dests': ['player_acquisition_loop']}, {'src': 'player_acquisition_loop', 'dests': ['player_acquisition_ended']} ] } } ], 'filename': os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl") }) # Test for cached query b = self.factory.from_file(os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl")) self.assertIs(a, b) def test_factory_idsl(self): c = self.factory.from_file("JointMotor.idsl") ref = OrderedDict({ 'name': 'RoboCompJointMotor', 'imports': [], 'recursive_imports': [], 'interfaces':[ {'name': 'JointMotor', 'methods': OrderedDict([ ('getAllMotorParams',{'name': 'getAllMotorParams', 'decorator': '', 'return': 'MotorParamsList', 'params': [], 'throws': 'nothing'}), ('getAllMotorState', {'name': 'getAllMotorState', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'out', 'type': 'MotorStateMap', 'name': 'mstateMap'}], 'throws': ['UnknownMotorException']}), ('getBusParams', {'name': 'getBusParams', 'decorator': '', 'return': 'BusParams', 'params': [], 'throws': 'nothing'}), ('getMotorParams', {'name': 'getMotorParams', 'decorator': '', 'return': 'MotorParams', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'motor'}], 'throws': ['UnknownMotorException']}), ('getMotorState', {'name': 'getMotorState', 'decorator': '', 'return': 'MotorState', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'motor'}], 'throws': ['UnknownMotorException']}), ('getMotorStateMap', {'name': 'getMotorStateMap', 'decorator': '', 'return': 'MotorStateMap', 'params': [{'decorator': 'none', 'type': 'MotorList', 'name': 'mList'}], 'throws': ['UnknownMotorException']}), ('setPosition', {'name': 'setPosition', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalPosition', 'name': 'goal'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException', ',', 'CollisionException']}), ('setSyncPosition', {'name': 'setSyncPosition', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalPositionList', 'name': 'listGoals'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setSyncVelocity', {'name': 'setSyncVelocity', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalVelocityList', 'name': 'listGoals'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setSyncZeroPos', {'name': 'setSyncZeroPos', 'decorator': '', 'return': 'void', 'params': [], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setVelocity', {'name': 'setVelocity', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalVelocity', 'name': 'goal'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setZeroPos', {'name': 'setZeroPos', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'name'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']})])}, {'name': 'JointMotorPublish', 'methods': OrderedDict([ ('motorStates', {'name': 'motorStates', 'decorator': '', 'return': 'void', 'params': [ {'decorator': 'none', 'type': 'MotorStateMap', 'name': 'mstateMap'} ], 'throws': 'nothing' }) ]) } ], 'types': [ {'type': 'exception', 'name': 'HardwareFailedException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'OutOfRangeException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'UnknownMotorException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'CollisionException', 'content': '\n string what;\n '}, {'type': 'struct', 'name': 'MotorState', 'structIdentifiers': [{'type': 'float', 'identifier': 'pos'}, {'type': 'float', 'identifier': 'vel'}, {'type': 'float', 'identifier': 'power'}, {'type': 'string', 'identifier': 'timeStamp'}, {'type': 'int', 'identifier': 'p'}, {'type': 'int', 'identifier': 'v'}, {'type': 'bool', 'identifier': 'isMoving'}, {'type': 'int', 'identifier': 'temperature'}]}, {'type': 'dictionary', 'content': 'string,MotorState', 'name': 'MotorStateMap'}, {'type': 'struct', 'name': 'MotorParams', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'byte', 'identifier': 'busId'}, {'type': 'float', 'identifier': 'minPos'}, {'type': 'float', 'identifier': 'maxPos'}, {'type': 'float', 'identifier': 'maxVelocity'}, {'type': 'float', 'identifier': 'zeroPos'}, {'type': 'float', 'identifier': 'stepsRange'}, {'type': 'float', 'identifier': 'maxDegrees'}, {'type': 'bool', 'identifier': 'invertedSign'}, {'type': 'float', 'identifier': 'offset'}, {'type': 'float', 'identifier': 'unitsRange'}]}, {'type': 'sequence', 'typeSequence': 'MotorParams', 'name': 'MotorParamsList'}, {'type': 'struct', 'name': 'BusParams', 'structIdentifiers': [{'type': 'string', 'identifier': 'handler'}, {'type': 'string', 'identifier': 'device'}, {'type': 'int', 'identifier': 'numMotors'}, {'type': 'int', 'identifier': 'baudRate'}, {'type': 'int', 'identifier': 'basicPeriod'}]}, {'type': 'struct', 'name': 'MotorGoalPosition', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'float', 'identifier': 'position'}, {'type': 'float', 'identifier': 'maxSpeed'}]}, {'type': 'sequence', 'typeSequence': 'MotorGoalPosition', 'name': 'MotorGoalPositionList'}, {'type': 'struct', 'name': 'MotorGoalVelocity', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'float', 'identifier': 'velocity'}, {'type': 'float', 'identifier': 'maxAcc'}]}, {'type': 'sequence', 'typeSequence': 'MotorGoalVelocity', 'name': 'MotorGoalVelocityList'}, {'type': 'sequence', 'typeSequence': 'string', 'name': 'MotorList'}], 'sequences': [ {'name': 'RoboCompJointMotor/MotorParamsList', 'type': 'sequence', 'typeSequence': 'MotorParams'}, {'name': 'RoboCompJointMotor/MotorGoalPositionList', 'type': 'sequence', 'typeSequence': 'MotorGoalPosition'}, {'name': 'RoboCompJointMotor/MotorGoalVelocityList', 'type': 'sequence', 'typeSequence': 'MotorGoalVelocity'}, {'name': 'RoboCompJointMotor/MotorList', 'type': 'sequence', 'typeSequence': 'string'} ], 'simpleSequences': [ {'name': 'RoboCompJointMotor', 'strName': 'MotorParamsList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalPositionList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalVelocityList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorList'} ], 'structs': [ {'name': 'RoboCompJointMotor/MotorState', 'type': 'struct', 'structIdentifiers': [ ['float', 'pos'], ['float', 'vel'], ['float', 'power'], ['string', 'timeStamp'], ['int', 'p'], ['int', 'v'], ['bool', 'isMoving'], ['int', 'temperature'] ] }, {'name': 'RoboCompJointMotor/MotorParams', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['byte', 'busId'], ['float', 'minPos'], ['float', 'maxPos'], ['float', 'maxVelocity'], ['float', 'zeroPos'], ['float', 'stepsRange'], ['float', 'maxDegrees'], ['bool', 'invertedSign'], ['float', 'offset'], ['float', 'unitsRange'] ] }, {'name': 'RoboCompJointMotor/BusParams', 'type': 'struct', 'structIdentifiers': [ ['string', 'handler'], ['string', 'device'], ['int', 'numMotors'], ['int', 'baudRate'], ['int', 'basicPeriod'] ] }, {'name': 'RoboCompJointMotor/MotorGoalPosition', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['float', 'position'], ['float', 'maxSpeed'] ] }, {'name': 'RoboCompJointMotor/MotorGoalVelocity', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['float', 'velocity'], ['float', 'maxAcc'] ] } ], 'simpleStructs': [ {'name': 'RoboCompJointMotor', 'strName': 'MotorState'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorParams'}, {'name': 'RoboCompJointMotor', 'strName': 'BusParams'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalPosition'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalVelocity'} ], 'filename': '/opt/robocomp/interfaces/IDSLs/JointMotor.idsl' }) self.assertNestedDictEqual(c, ref, ignored_keys=['filename']) # test for cached query d = self.factory.from_file("JointMotor.idsl") self.assertIs(c, d) def test_factory_cdsl(self): # TODO: Use a better cdsl example than this g = self.factory.from_file(os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")) ref = cf.ComponentFacade({ 'options': [], 'name': 'testcomp', 'imports': [], 'recursiveImports': [], 'language': 'cpp', 'statemachine_path': 'gamestatemachine.smdsl', 'statemachine_visual': False, 'innermodelviewer': False, 'gui': ['Qt', 'QWidget'], 'rosInterfaces': [], 'iceInterfaces': [], 'implements': [], 'requires': [], 'publishes': [], 'subscribesTo': [], 'usingROS': False, 'dsr': False, 'filename': os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")}) self.assertEqual(g, ref) # test for cached query h = self.factory.from_file(os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")) self.assertIs(g, h) def test_factory_cdsl_with_options(self): # TODO: Use a better cdsl example than this g = self.factory.from_file(os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")) ref = cf.ComponentFacade({ 'options': ['agmagent', 'innermodelviewer'], 'name': 'testcomp', 'imports': ['AGMCommonBehavior.idsl', 'AGMExecutive.idsl', 'AGMExecutiveTopic.idsl', 'AGMWorldModel.idsl'], 'recursiveImports': ['Planning.idsl'], 'language': 'cpp', 'statemachine_path': None, 'statemachine_visual': False, 'innermodelviewer': True, 'gui': ['Qt', 'QWidget'], 'rosInterfaces': [], 'iceInterfaces': [['AGMCommonBehavior', 'ice'], ['AGMExecutive', 'ice'], ['AGMExecutiveTopic', 'ice'], ['AGMWorldModel', 'ice']], 'implements': [['AGMCommonBehavior','ice']], 'requires': [['AGMExecutive', 'ice']], 'publishes': [], 'subscribesTo': [['AGMExecutiveTopic', 'ice']], 'usingROS': False, 'dsr': False, 'filename': os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")}) self.assertEqual(g, ref) # test for cached query h = self.factory.from_file(os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")) self.assertIs(g, h) # def test_factory_jcdsl(self): # # TODO: Use a better cdsl example than this # g = self.factory.from_file(os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")) # self.assertCountEqual(g, { # 'options': ['agmagent', 'innermodelviewer'], # 'name': 'testcomp', # 'imports': ['AGMCommonBehavior.idsl', # 'AGMExecutive.idsl', # 'AGMExecutiveTopic.idsl', # 'AGMWorldModel.idsl'], # 'recursiveImports': ['Planning.idsl'], # 'language': 'cpp', # 'statemachine': None, # 'statemachine_visual': False, # 'innermodelviewer': True, # 'gui': ['Qt', 'QWidget'], # 'rosInterfaces': [], # 'iceInterfaces': ['AGMCommonBehavior', # 'AGMExecutive', # 'AGMExecutiveTopic', # 'AGMWorldModel'], # 'implements': ['AGMCommonBehavior'], # 'requires': ['AGMExecutive'], # 'publishes': [], # 'subscribesTo': ['AGMExecutiveTopic'], # 'usingROS': False, # 'filename': os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")}) # # test for cached query # h = self.factory.from_file(os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")) # self.assertIs(g, h) def test_factory_special_cases(self): # valid idsl without path a = self.factory.from_file("JointMotor.idsl") b = self.factory.from_file("JointMotor.idsl") self.assertEqual(a,b) # Not valid idsl without path self.assertRaises(IOError, self.factory.from_file,"NotAnIdsl.idsl") # None as path self.assertEqual(self.factory.from_file(None), None) # invalid dsl type from file extension self.assertRaises(ValueError, self.factory.from_string,"asdafafsdfasfsdfasdff", "ppsl") # invalid dsl type from file extension self.assertRaises(ParseException, self.factory.from_string, "this is not a valid string for the parser", "idsl") def assertFilesSame(self, sFName1, sFName2): text1 = open(os.path.join(self.tempdir, sFName1), 'rb').read() text2 = open(os.path.join(self.tempdir, sFName2), 'rb').read() self.assertEqual(text1, text2)