Esempio n. 1
0
 def test_FunctionResultToUpcase(self):
     
     theString = types.String("This_Is_a_MiXed_StrIng")
     theFuncCall = types.FunctionCall(types.Symbol("upcase"), self.theEnv.modulesManager, [theString])
     theResult = self.theFunc.do(self.theEnv, theFuncCall)
     
     self.assertEqual(theResult.__class__, types.String)
     self.assertEqual(len(set(string.ascii_lowercase).intersection(set(theResult.evaluate()))), 0)
     self.assertEqual(theResult, self.theFunc.do(self.theEnv, theString))
    def test_FunctionCallAsArgument(self):
        if not self.theEnv.modulesManager.currentScope.functions.has("upcase"):
            self.skipTest("upcase not defined")

        self.assertTrue(
            self.forInput(
                types.FunctionCall("upcase", self.theEnv.modulesManager,
                                   [types.String("acqua")]),
                types.String("acqua")).expect(
                    types.Integer(cmp("acqua".upper(), "acqua"))))
Esempio n. 3
0
def analyzeFunction(theFunction, patternIndex, variables, inPatternVariables=None, fakeVariables = None, realToFakeMap = None, vIndex = None, fakeNames = None):
    '''
    Analyze a FunctionCall inside a Test-CE to replace variables name with fake names
    an bound locations to improve reuse of test-nodes (normalize variables names) 
    
    @param theFunction: a function call to replace
    @type theFunction: types.FunctionCall
    @param patternIndex: the index of the test-pattern in the chain of ce
    @type patternIndex: int
    @param variables: a dict of variable name => VariableReferences
    @type variables: dict
    @param fakeVariables: a dict of fake variables references or None (to make a new one)
    @type fakeVariables: dict
    @param realToFakeMap: a map of real variables names to fake ones
    @type realToFakeMap: dict
    @param vIndex: the index for fake variables name generation
    @type vIndex: int
    '''
    
    inPatternVariables = [] if inPatternVariables is None else inPatternVariables
    aNewFunctionCallArgs = []
    fakeVariables = {} if fakeVariables is None else fakeVariables
    fakeNames = {} if fakeNames is None else fakeNames
    realToFakeMap = {} if realToFakeMap is None else realToFakeMap
    vIndex = [] if vIndex is None else vIndex;
    
    if isinstance(theFunction, types.FunctionCall):
        
        assert isinstance(theFunction, types.FunctionCall)
        
        for aArg in theFunction.funcArgs:
            
            # globals are resolved at function-call execution time
            if isinstance(aArg, (types.SingleFieldVariable, types.MultiFieldVariable)):
                # i've already created a fake_var for this var?
                if not realToFakeMap.has_key(aArg.evaluate()) :
                
                    # where i found the variable first?
                    mainReference = getVar(aArg.evaluate(), variables, inPatternVariables)
                    
                    if mainReference is False:
                        raise MyClipsException("Variable %s found in the expression %s was referenced in CE #%d before being defined."%(
                                aArg.evaluate(),
                                theFunction.toClipsStr(),
                                patternIndex
                            ))
                    
                    varReference = VariableReference()
                    varReference.reference = mainReference
                    varReference.relPatternIndex = mainReference.patternIndex - patternIndex
                    
                    theFakeName = "%"+str(len(vIndex))
                    vIndex.append(None)
                    
                    theFakeVar = aArg.__class__(types.Symbol(theFakeName)) 
                    
                    fakeVariables[theFakeVar.evaluate()] = varReference
                    realToFakeMap[aArg.evaluate()] = theFakeVar.evaluate()
                    fakeNames[aArg.evaluate()] = theFakeVar 
                
                else:
                    theFakeVar = fakeNames[aArg.evaluate()]
                     
                
                # replace the variable name with a fake name
                #aArg.content = theFakeName
                aNewFunctionCallArgs.append(theFakeVar)
                
            elif isinstance(aArg, types.FunctionCall):
                
                # recursion: replace arguments inside the function call
                # fakeReferences are ignored because the dict is automatically
                # updated by the recursion.
                aInnerNewFunctionCall, _ = analyzeFunction(aArg, patternIndex, variables, inPatternVariables, fakeVariables, realToFakeMap, vIndex, fakeNames)
                
                # replace the old function call with a new one with fake variables
                #theFunction.funcArgs[iArg] = aInnerNewFunctionCall
                aNewFunctionCallArgs.append(aInnerNewFunctionCall)
                
            else:
                aNewFunctionCallArgs.append(aArg)
    
        # get the current scope and backup it
        _tmp_scope = theFunction.scope.modules.currentScope
        # then change it to the original function call scope
        theFunction.scope.modules.changeCurrentScope(theFunction.scope.moduleName)
        # create the new function call
        newFunctionCall = types.FunctionCall(theFunction.funcName, theFunction.scope.modules, aNewFunctionCallArgs)
        # then restore the previous scope
        theFunction.scope.modules.changeCurrentScope(_tmp_scope.moduleName)
    
        return (newFunctionCall, fakeVariables)
    
    else: raise TypeError("AnalyzeFunction require a FunctionCall as first argument")