#!/usr/bin/env python # For python 2.6-2.7 from __future__ import print_function from os.path import * import re # from parseBrackets import parseBrackets from parseDirectiveArgs import parseDirectiveArguments class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) assertVariants = 'Fail|Equal|True|False|LessThan|LessThanOrEqual|GreaterThan|GreaterThanOrEqual' assertVariants += '|IsMemberOf|Contains|Any|All|NotAll|None|IsPermutationOf' assertVariants += '|ExceptionRaised|SameShape|IsNaN|IsFinite' def cppSetLineAndFile(line, file): return "#line " + str(line) + ' "' + file + '"\n' def getSubroutineName(line): try: m = re.match('\s*subroutine\s+(\w*)\s*(\\([\w\s,]*\\))?\s*(!.*)*$', line, re.IGNORECASE) return m.groups()[0] except: raise MyError('Improper format in declaration of test procedure.') def parseArgsFirstRest(directiveName,line): """If the @-directive has more than one argument, parse into first and rest strings. Added for assertAssociated. """ argStr = ''; if directiveName != '': m = re.match('\s*'+directiveName+'\s*\\((.*\w.*)\\)\s*$',line,re.IGNORECASE) if m: argStr = m.groups()[0] else: return None else: argStr = line args = parseDirectiveArguments(argStr) if args == []: returnArgs = None elif len(args) == 1: returnArgs = [args[0]] else: returnArgs = [args[0],','.join(args[1:])] return returnArgs def parseArgsFirstSecondRest(directiveName,line): """If the @-directive must have at least two arguments, parse into first, second, and rest strings. Added for assertAssociated. """ args1 = parseArgsFirstRest(directiveName,line) returnArgs = None if args1 != None: if len(args1) == 1: returnArgs = args1 elif len(args1) == 2: args2 = parseArgsFirstRest('',args1[1]) returnArgs = [args1[0]] + args2 elif len(args1) == 3: print(-999,'parseArgsFirstSecondRest::error!') returnArgs = None return returnArgs def getSelfObjectName(line): m = re.match('\s*subroutine\s+\w*\s*\\(\s*(\w+)\s*(,\s*\w+\s*)*\\)\s*$', line, re.IGNORECASE) if m: return m.groups()[0] else: return m def getTypeName(line): m = re.match('\s*type(.*::\s*|\s+)(\w*)\s*$', line, re.IGNORECASE) return m.groups()[1] class Action(): def apply(self, line): m = self.match(line) if m: self.action(m, line) return m #------------------ class AtTest(Action): def __init__(self, parser): self.parser = parser self.keyword = '@test' def match(self, line): m = re.match('\s*'+self.keyword+'(\s*(\\(.*\\))?\s*$)', line, re.IGNORECASE) return m def action(self, m, line): options = re.match('\s*'+self.keyword+'\s*\\((.*)\\)\s*$', line, re.IGNORECASE) method = {} if options: npesOption = re.search('npes\s*=\s*\\[([0-9,\s]+)\\]', options.groups()[0], re.IGNORECASE) if npesOption: npesString = npesOption.groups()[0] npes = map(int, npesString.split(',')) method['npRequests'] = npes #ifdef is optional matchIfdef = re.match('.*ifdef\s*=\s*(\w+)', options.groups()[0], re.IGNORECASE) if matchIfdef: ifdef = matchIfdef.groups()[0] method['ifdef'] = ifdef matchIfndef = re.match('.*ifndef\s*=\s*(\w+)', options.groups()[0], re.IGNORECASE) if matchIfndef: ifndef = matchIfndef.groups()[0] method['ifndef'] = ifndef matchType = re.match('.*type\s*=\s*(\w+)', options.groups()[0], re.IGNORECASE) if matchType: print ('Type', matchType.groups()[0]) method['type'] = matchType.groups()[0] paramOption = re.search('testParameters\s*=\s*[{](.*)[}]', options.groups()[0], re.IGNORECASE) if paramOption: paramExpr = paramOption.groups()[0] method['testParameters'] = paramExpr casesOption = re.search('cases\s*=\s*(\\[[0-9,\s]+\\])', options.groups()[0], re.IGNORECASE) if casesOption: method['cases'] = casesOption.groups()[0] nextLine = self.parser.nextLine() method['name'] = getSubroutineName(nextLine) # save "self" name for use with @mpiAssert self.parser.currentSelfObjectName = getSelfObjectName(nextLine) # save "self" name for use with @mpiAssert dummyArgument = getSelfObjectName(nextLine) if dummyArgument: method['selfObjectName'] = dummyArgument self.parser.userTestMethods.append(method) self.parser.commentLine(line) self.parser.outputFile.write(nextLine) #------------------ # deprecated - should now just use @test class AtMpiTest(AtTest): def __init__(self, parser): self.parser = parser self.keyword = '@mpitest' class AtTestCase(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@testcase\s*(|\\(.*\\))\s*$', line, re.IGNORECASE) return m def action(self, m, line): options = re.match('\s*@testcase\s*\\((.*)\\)\s*$', line, re.IGNORECASE) if options: value = re.search('constructor\s*=\s*(\w*)', options.groups()[0], re.IGNORECASE) if value: self.parser.userTestCase['constructor'] = value.groups()[0] value = re.search('npes\s*=\s*\\[([0-9,\s]+)\\]', options.groups()[0], re.IGNORECASE) if value: npesString = value.groups()[0] npes = map(int,npesString.split(',')) self.parser.userTestCase['npRequests'] = npes value = re.search('cases\s*=\s*(\\[[0-9,\s]+\\])', options.groups()[0], re.IGNORECASE) if value: cases = value.groups()[0] self.parser.userTestCase['cases'] = cases value = re.search('testParameters\s*=\s*[{](.*)[}]', options.groups()[0], re.IGNORECASE) if value: paramExpr = value.groups()[0] self.parser.userTestCase['testParameters'] = paramExpr nextLine = self.parser.nextLine() self.parser.userTestCase['type']=getTypeName(nextLine) self.parser.commentLine(line) self.parser.outputFile.write(nextLine) class AtSuite(Action): def __init__(self, parser): self.parser = parser def match(self, line): nameRe = "'\w+'|" + """\w+""" m = re.match("\s*@suite\s*\\(\s*name\s*=\s*("+nameRe+")\s*\\)\s*$", line, re.IGNORECASE) return m def action(self, m, line): self.parser.suiteName=m.groups()[0][1:-1] self.parser.wrapModuleName = 'Wrap' + self.parser.suiteName class AtBegin(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*module\s+(\w*)\s*$', line, re.IGNORECASE) return m def action(self, m, line): self.parser.userModuleName = m.groups()[0] self.parser.wrapModuleName = 'Wrap' + self.parser.userModuleName if not self.parser.suiteName: self.parser.suiteName = self.parser.userModuleName + "_suite" self.parser.outputFile.write(line) class AtAssert(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@assert('+assertVariants+')\s*\\((.*\w.*)\\)\s*$', line, re.IGNORECASE) return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) p.outputFile.write(" call assert"+m.groups()[0]+"(" + m.groups()[1] + ", &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") p.outputFile.write(" if (anyExceptions()) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtAssertAssociated(Action): def __init__(self,parser): self.parser = parser def match(self, line): m = re.match('\s*@assertassociated\s*\\((.*\w.*)\\)\s*$', line, re.IGNORECASE) if not m: m = re.match( \ '\s*@assertassociated\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*),(.*\w*.*))\\)\s*$', \ line, re.IGNORECASE) # How to get both (a,b) and (a,b,c) to match? if not m: m = re.match( \ '\s*@assertassociated\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*))\\)\s*$', \ line, re.IGNORECASE) return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser # args = parseArgsFirstRest('@assertassociated',line) args = parseArgsFirstSecondRest('@assertassociated',line) # print(9000,line) # print(9001,args) p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) if len(args) > 1: if re.match('.*message=.*',args[1],re.IGNORECASE): p.outputFile.write(" call assertTrue(associated(" + args[0] + "), " + args[1] + ", &\n") elif len(args) > 2: p.outputFile.write(" call assertTrue(associated(" + args[0] + "," + args[1] + "), " + args[2] + ", &\n") else: p.outputFile.write(" call assertTrue(associated(" + args[0] + "," + args[1] + "), &\n") else: p.outputFile.write(" call assertTrue(associated(" + args[0] + "), &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") p.outputFile.write(" if (anyExceptions()) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtAssertNotAssociated(Action): def __init__(self,parser): self.parser = parser self.name='@assertnotassociated' def match(self, line): m = re.match('\s*@assert(not|un)associated\s*\\((.*\w.*)\\)\s*$', line, re.IGNORECASE) if m: self.name='@assert'+m.groups()[0]+'associated' else: self.name='@assertnotassociated' if not m: m = re.match( \ '\s*@assert(not|un)associated\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*),(.*\w*.*))\\)\s*$', \ line, re.IGNORECASE) # How to get both (a,b) and (a,b,c) to match? if not m: m = re.match( \ '\s*@assert(not|un)associated\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*))\\)\s*$', \ line, re.IGNORECASE) if m: self.name='@assert'+m.groups()[0]+'associated' else: self.name='@assertnotassociated' return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser #-- args = parseArgsFirstRest('@assertassociated',line) #ok args = parseArgsFirstSecondRest('@assertassociated',line) args = parseArgsFirstSecondRest(self.name,line) # print(9000,line) # print(9001,args) p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) if len(args) > 1: if re.match('.*message=.*',args[1],re.IGNORECASE): p.outputFile.write(" call assertFalse(associated(" + args[0] + "), " + args[1] + ", &\n") elif len(args) > 2: p.outputFile.write(" call assertFalse(associated(" + args[0] + "," + args[1] + "), " + args[2] + ", &\n") else: p.outputFile.write(" call assertFalse(associated(" + args[0] + "," + args[1] + "), &\n") else: p.outputFile.write(" call assertFalse(associated(" + args[0] + "), &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") p.outputFile.write(" if (anyExceptions()) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtAssertEqualUserDefined(Action): """Convenience directive replacing (a,b) with a call to assertTrue(a==b) and an error message, if none is provided when invoked. """ def __init__(self,parser): self.parser = parser def match(self, line): m = re.match( \ '\s*@assertequaluserdefined\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*),(.*\w*.*))\\)\s*$', \ line, re.IGNORECASE) # How to get both (a,b) and (a,b,c) to match? if not m: m = re.match( \ '\s*@assertequaluserdefined\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*))\\)\s*$', \ line, re.IGNORECASE) return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser args = parseArgsFirstSecondRest('@assertequaluserdefined',line) p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) if len(args) > 2: p.outputFile.write(" call assertTrue(" \ + args[0] + "==" + args[1] + ", " + args[2] + ", &\n") else: p.outputFile.write(" call assertTrue(" \ + args[0] + "==" + args[1] + ", &\n") if not re.match('.*message=.*',line,re.IGNORECASE): p.outputFile.write(" & message='<" + args[0] + "> not equal to <" + args[1] + ">', &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") p.outputFile.write(" if (anyExceptions()) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtAssertEquivalent(Action): """Convenience directive replacing (a,b) with a call to assertTrue(a.eqv.b) and an error message, if none is provided when invoked. """ def __init__(self,parser): self.parser = parser def match(self, line): m = re.match( \ '\s*@assertequivalent\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*),(.*\w*.*))\\)\s*$', \ line, re.IGNORECASE) # How to get both (a,b) and (a,b,c) to match? if not m: m = re.match( \ '\s*@assertequivalent\s*\\((\s*([^,]*\w.*),\s*([^,]*\w.*))\\)\s*$', \ line, re.IGNORECASE) return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser args = parseArgsFirstSecondRest('@assertequivalent',line) p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) if len(args) > 2: p.outputFile.write(" call assertTrue(" \ + args[0] + ".eqv." + args[1] + ", " + args[2] + ", &\n") else: p.outputFile.write(" call assertTrue(" \ + args[0] + ".eqv." + args[1] + ", &\n") if not re.match('.*message=.*',line,re.IGNORECASE): p.outputFile.write(" & message='<" + args[0] + "> not equal to <" + args[1] + ">', &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") p.outputFile.write(" if (anyExceptions()) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtMpiAssert(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@mpiassert('+assertVariants+')\s*\\((.*\w.*)\\)\s*$', line, re.IGNORECASE) return m def appendSourceLocation(self, fileHandle, fileName, lineNumber): fileHandle.write(" & location=SourceLocation( &\n") fileHandle.write(" & '" + str(basename(fileName)) + "', &\n") fileHandle.write(" & " + str(lineNumber) + ")") def action(self, m, line): p = self.parser p.outputFile.write(cppSetLineAndFile(p.currentLineNumber, p.fileName)) p.outputFile.write(" call assert"+m.groups()[0]+"(" + m.groups()[1] + ", &\n") self.appendSourceLocation(p.outputFile, p.fileName, p.currentLineNumber) p.outputFile.write(" )\n") # 'this' object may not exist if test is commented out. if hasattr(p,'currentSelfObjectName'): p.outputFile.write(" if (anyExceptions("+p.currentSelfObjectName+"%context)) return\n") p.outputFile.write(cppSetLineAndFile(p.currentLineNumber+1, p.fileName)) class AtBefore(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@before\s*$', line, re.IGNORECASE) return m def action(self, m, line): nextLine = self.parser.nextLine() self.parser.userTestCase['setUp'] = getSubroutineName(nextLine) self.parser.commentLine(line) self.parser.outputFile.write(nextLine) class AtAfter(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@after\s*$', line, re.IGNORECASE) return m def action(self, m, line): nextLine = self.parser.nextLine() self.parser.userTestCase['tearDown'] = getSubroutineName(nextLine) self.parser.commentLine(line) self.parser.outputFile.write(nextLine) class AtTestParameter(Action): def __init__(self, parser): self.parser = parser def match(self, line): m = re.match('\s*@testParameter\s*(|.*)$', line, re.IGNORECASE) return m def action(self, m, line): options = re.match('\s*@testParameter\s*\\((.*)\\)\s*$', line, re.IGNORECASE) self.parser.commentLine(line) nextLine = self.parser.nextLine() if not 'testParameterType' in self.parser.userTestCase: self.parser.userTestCase['testParameterType'] = getTypeName(nextLine) self.parser.outputFile.write(nextLine) if options: value = re.search('constructor\s*=\s*(\w*)', options.groups()[0], re.IGNORECASE) if value: self.parser.userTestCase['testParameterConstructor'] = value.groups()[0] else: self.parser.userTestCase['testParameterConstructor'] = self.parser.userTestCase['testParameterType'] class Parser(): def __init__(self, inputFileName, outputFileName): def getBaseName(fileName): from os.path import basename, splitext base = basename(fileName) return splitext(base)[0] self.fileName = inputFileName self.inputFile = open(inputFileName, 'r') self.outputFile = open(outputFileName, 'w') self.defaultSuiteName = getBaseName(inputFileName) + "_suite" self.suiteName = '' self.currentLineNumber = 0 self.userModuleName = '' # if any self.userTestCase = {} self.userTestCase['setUpMethod'] = '' self.userTestCase['tearDownMethod'] = '' self.userTestCase['defaultTestParameterNpes'] = [] # is MPI if not empty self.userTestCase['defaultTestParametersExpr'] = '' self.userTestCase['defaultTestParameterCases'] = [] self.userTestMethods = [] # each entry is a dictionary self.wrapModuleName = "Wrap" + getBaseName(inputFileName) self.currentLineNumber = 0 self.actions=[] self.actions.append(AtTest(self)) self.actions.append(AtMpiTest(self)) self.actions.append(AtTestCase(self)) self.actions.append(AtSuite(self)) self.actions.append(AtBegin(self)) self.actions.append(AtAssert(self)) self.actions.append(AtAssertAssociated(self)) # self.actions.append(AtAssertAssociatedWith(self)) self.actions.append(AtAssertNotAssociated(self)) # self.actions.append(AtAssertNotAssociatedWith(self)) self.actions.append(AtAssertEqualUserDefined(self)) self.actions.append(AtAssertEquivalent(self)) self.actions.append(AtMpiAssert(self)) self.actions.append(AtBefore(self)) self.actions.append(AtAfter(self)) self.actions.append(AtTestParameter(self)) def commentLine(self, line): self.outputFile.write(re.sub('@','!@',line)) def run(self): def parse(line): for action in self.actions: if (action.apply(line)): return self.outputFile.write(line) while True: line = self.nextLine() if not line: break parse(line) if (not self.suiteName): self.suiteName = self.defaultSuiteName if ('testParameterType' in self.userTestCase and (not 'constructor' in self.userTestCase)): self.userTestCase['constructor'] = self.userTestCase['testParameterType'] self.makeWrapperModule() def isComment(self, line): return re.match('\s*(!.*|)$', line) def nextLine(self): while True: self.currentLineNumber += 1 line = self.inputFile.readline() if not line: break if (self.isComment(line)): self.outputFile.write(line) pass else: break return line def printHeader(self): self.outputFile.write('\n') self.outputFile.write('module ' + self.wrapModuleName + '\n') self.outputFile.write(' use pFUnit_mod\n') if (self.userModuleName): self.outputFile.write(' use ' + self.userModuleName + '\n') self.outputFile.write(' implicit none\n') self.outputFile.write(' private\n\n') def printTail(self): self.outputFile.write('\n') self.outputFile.write('end module ' + self.wrapModuleName + '\n\n') def printWrapUserTestCase(self): self.outputFile.write(' public :: WrapUserTestCase\n') self.outputFile.write(' public :: makeCustomTest\n') self.outputFile.write(' type, extends(' + self.userTestCase['type'] + ') :: WrapUserTestCase\n') self.outputFile.write(' procedure(userTestMethod), nopass, pointer :: testMethodPtr\n') self.outputFile.write(' contains\n') self.outputFile.write(' procedure :: runMethod\n') self.outputFile.write(' end type WrapUserTestCase\n\n') self.outputFile.write(' abstract interface\n') self.outputFile.write(' subroutine userTestMethod(this)\n') if self.userModuleName: self.outputFile.write(' use ' + self.userModuleName + '\n') if 'type' in self.userTestCase: self.outputFile.write(' class (' + self.userTestCase['type'] + '), intent(inout) :: this\n') self.outputFile.write(' end subroutine userTestMethod\n') self.outputFile.write(' end interface\n\n') def printRunMethod(self): self.outputFile.write(' subroutine runMethod(this)\n') self.outputFile.write(' class (WrapUserTestCase), intent(inout) :: this\n\n') self.outputFile.write(' call this%testMethodPtr(this)\n') self.outputFile.write(' end subroutine runMethod\n\n') def printParameterHeader(self, type): self.outputFile.write(' type (' + type + '), allocatable :: testParameters(:)\n') self.outputFile.write(' type (' + type + ') :: testParameter\n') self.outputFile.write(' integer :: iParam \n') self.outputFile.write(' integer, allocatable :: cases(:) \n') self.outputFile.write(' \n') def printMakeSuite(self): self.outputFile.write('function ' + self.suiteName + '() result(suite)\n') self.outputFile.write(' use pFUnit_mod\n') if (self.userModuleName): self.outputFile.write(' use ' + self.userModuleName + '\n') self.outputFile.write(' use '+ self.wrapModuleName + '\n') self.outputFile.write(' type (TestSuite) :: suite\n\n') if not self.userModuleName: for testMethod in self.userTestMethods: if ('ifdef' in testMethod): self.outputFile.write('#ifdef ' + testMethod['ifdef'] + '\n') elif ('ifndef' in testMethod): self.outputFile.write('#ifndef ' + testMethod['ifndef'] + '\n') self.outputFile.write(' external ' + testMethod['name'] + '\n') if ('ifdef' in testMethod or 'ifndef' in testMethod): self.outputFile.write('#endif\n') self.outputFile.write('\n') if 'setUp' in self.userTestCase: self.outputFile.write(' external ' + self.userTestCase['setUp'] + '\n') if 'tearDown' in self.userTestCase: self.outputFile.write(' external ' + self.userTestCase['tearDown'] + '\n') self.outputFile.write('\n') if 'testParameterType' in self.userTestCase: type = self.userTestCase['testParameterType'] self.printParameterHeader(type) self.outputFile.write(" suite = newTestSuite('" + self.suiteName + "')\n\n") for testMethod in self.userTestMethods: if ('ifdef' in testMethod): self.outputFile.write('#ifdef ' + testMethod['ifdef'] + '\n') elif ('ifndef' in testMethod): self.outputFile.write('#ifndef ' + testMethod['ifndef'] + '\n') if 'type' in self.userTestCase: self.addUserTestMethod(testMethod) else: if 'npRequests' in testMethod: self.addMpiTestMethod(testMethod) else: # vanilla self.addSimpleTestMethod(testMethod) self.outputFile.write('\n') if ('ifdef' in testMethod or 'ifndef' in testMethod): self.outputFile.write('#endif\n') self.outputFile.write('\nend function ' + self.suiteName + '\n\n') def addSimpleTestMethod(self, testMethod): args = "'" + testMethod['name'] + "', " + testMethod['name'] if 'setUp' in testMethod: args += ', ' + testMethod['setUp'] elif 'setUp' in self.userTestCase: args += ', ' + self.userTestCase['setUp'] if 'tearDown' in testMethod: args += ', ' + testMethod['tearDown'] elif 'tearDown' in self.userTestCase: args += ', ' + self.userTestCase['tearDown'] if 'type' in testMethod: type = testMethod['type'] else: type = 'newTestMethod' self.outputFile.write(' call suite%addTest(' + type + '(' + args + '))\n') def addMpiTestMethod(self, testMethod): for npes in testMethod['npRequests']: args = "'" + testMethod['name'] + "', " + testMethod['name'] + ", " + str(npes) if 'setUp' in testMethod: args += ', ' + testMethod['setUp'] elif 'setUp' in self.userTestCase: args += ', ' + self.userTestCase['setUp'] if 'tearDown' in testMethod: args += ', ' + testMethod['tearDown'] elif 'tearDown' in self.userTestCase: args += ', ' + self.userTestCase['tearDown'] if 'type' in testMethod: type = testMethod['type'] else: type = 'newMpiTestMethod' self.outputFile.write(' call suite%addTest(' + type + '(' + args + '))\n') def addUserTestMethod(self, testMethod): args = "'" + testMethod['name'] + "', " + testMethod['name'] if 'npRequests' in testMethod: npRequests = testMethod['npRequests'] else: if 'npRequests' in self.userTestCase: npRequests = self.userTestCase['npRequests'] else: npRequests = [1] if 'cases' in testMethod: cases = testMethod['cases'] elif 'cases' in self.userTestCase: cases = self.userTestCase['cases'] testParameterArg = '' # unless if 'cases' in locals(): testParameterArg = ', testParameter' self.outputFile.write(' cases = ' + testMethod['cases'] + '\n') self.outputFile.write(' testParameters = [(' + self.userTestCase['testParameterConstructor'] + '(cases(iCase)), iCase = 1, size(cases))]\n\n') if 'testParameterType' in self.userTestCase: if 'testParameters' in testMethod: testParameters = testMethod['testParameters'] elif 'testParameters' in self.userTestCase: testParameters = self.userTestCase['testParameters'] isMpiTestCase = 'npRequests' in self.userTestCase isMpiTestCase = isMpiTestCase or any('npRequests' in testMethod for testMethod in self.userTestMethods) if 'testParameters' in locals(): testParameterArg = ', testParameter' self.outputFile.write(' testParameters = ' + testParameters + '\n\n') elif isMpiTestCase: testParameterArg = ', testParameter' for npes in npRequests: if 'testParameters' in locals() or 'cases' in locals(): self.outputFile.write(' do iParam = 1, size(testParameters)\n') self.outputFile.write(' testParameter = testParameters(iParam)\n') if isMpiTestCase: self.outputFile.write(' call testParameter%setNumProcessesRequested(' + str(npes) + ')\n') self.outputFile.write(' call suite%addTest(makeCustomTest(' + args + testParameterArg + '))\n') if 'cases' in locals() or 'testParameters' in locals(): self.outputFile.write(' end do\n') def printMakeCustomTest(self, isMpiTestCase): args = 'methodName, testMethod' declareArgs = '#ifdef INTEL_13\n' declareArgs += ' use pfunit_mod, only: testCase\n' declareArgs += '#endif\n' declareArgs += ' type (WrapUserTestCase) :: aTest\n' declareArgs += '#ifdef INTEL_13\n' declareArgs += ' target :: aTest\n' declareArgs += ' class (WrapUserTestCase), pointer :: p\n' declareArgs += '#endif\n' declareArgs += ' character(len=*), intent(in) :: methodName\n' declareArgs += ' procedure(userTestMethod) :: testMethod\n' if 'testParameterType' in self.userTestCase: args += ', testParameter' declareArgs += ' type (' + self.userTestCase['testParameterType'] + '), intent(in) :: testParameter\n' self.outputFile.write(' function makeCustomTest(' + args + ') result(aTest)\n') self.outputFile.write(declareArgs) if 'constructor' in self.userTestCase: if 'testParameterType' in self.userTestCase: constructor = self.userTestCase['constructor'] + '(testParameter)' else: constructor = self.userTestCase['constructor'] + '()' self.outputFile.write(' aTest%' + self.userTestCase['type'] + ' = ' + constructor + '\n\n') self.outputFile.write(' aTest%testMethodPtr => testMethod\n') self.outputFile.write('#ifdef INTEL_13\n') self.outputFile.write(' p => aTest\n') self.outputFile.write(' call p%setName(methodName)\n') self.outputFile.write('#else\n') self.outputFile.write(' call aTest%setName(methodName)\n') self.outputFile.write('#endif\n') if 'testParameterType' in self.userTestCase: self.outputFile.write(' call aTest%setTestParameter(testParameter)\n') self.outputFile.write(' end function makeCustomTest\n') def makeWrapperModule(self): #----------------------------------------------------------- # ! Start here self.printHeader() if 'type' in self.userTestCase: self.printWrapUserTestCase() self.outputFile.write('contains\n\n') if 'type' in self.userTestCase: self.printRunMethod() if 'type' in self.userTestCase: isMpiTestCase = 'npRequests' in self.userTestCase isMpiTestCase = isMpiTestCase or any('npRequests' in testMethod for testMethod in self.userTestMethods) if isMpiTestCase and not 'testParameterType' in self.userTestCase: self.userTestCase['testParameterType'] = 'MpiTestParameter' self.printMakeCustomTest(isMpiTestCase) self.printTail() self.printMakeSuite() def final(self): self.inputFile.close() self.outputFile.close() if __name__ == "__main__": import sys print("Processing file", sys.argv[1]) p = Parser(sys.argv[1], sys.argv[2]) p.run() p.final() print(" ... Done. Results in", sys.argv[2])