FunctionResolver { public FunctionBuilder resolve(FunctionSignature unresolvedSignature) { PriorityQueue<Map.Entry<Integer, FunctionSignature>> functionMatchQueue = new PriorityQueue<>( Map.Entry.comparingByKey()); for (FunctionSignature functionSignature : functionBundle.keySet()) { functionMatchQueue.add( new AbstractMap.SimpleEntry<>(unresolvedSignature.match(functionSignature), functionSignature)); } Map.Entry<Integer, FunctionSignature> bestMatchEntry = functionMatchQueue.peek(); if (FunctionSignature.NOT_MATCH.equals(bestMatchEntry.getKey())) { throw new ExpressionEvaluationException( String.format("%s function expected %s, but get %s", functionName, formatFunctions(functionBundle.keySet()), unresolvedSignature.formatTypes() )); } else { return functionBundle.get(bestMatchEntry.getValue()); } }  FunctionBuilder resolve(FunctionSignature unresolvedSignature);  }
@Test void resolve_function_signature_exactly_match() { when(functionSignature.match(exactlyMatchFS)).thenReturn(WideningTypeRule.TYPE_EQUAL); FunctionResolver resolver = new FunctionResolver(functionName, ImmutableMap.of(exactlyMatchFS, exactlyMatchBuilder)); assertEquals(exactlyMatchBuilder, resolver.resolve(functionSignature)); }
@Test void resolve_function_signature_best_match() { when(functionSignature.match(bestMatchFS)).thenReturn(1); when(functionSignature.match(leastMatchFS)).thenReturn(2); FunctionResolver resolver = new FunctionResolver(functionName, ImmutableMap.of(bestMatchFS, bestMatchBuilder, leastMatchFS, leastMatchBuilder)); assertEquals(bestMatchBuilder, resolver.resolve(functionSignature)); }
@Test void resolve_function_not_match() { when(functionSignature.match(notMatchFS)).thenReturn(WideningTypeRule.IMPOSSIBLE_WIDENING); when(notMatchFS.formatTypes()).thenReturn("[INTEGER,INTEGER]"); when(functionSignature.formatTypes()).thenReturn("[BOOLEAN,BOOLEAN]"); FunctionResolver resolver = new FunctionResolver(functionName, ImmutableMap.of(notMatchFS, notMatchBuilder)); ExpressionEvaluationException exception = assertThrows(ExpressionEvaluationException.class, () -> resolver.resolve(functionSignature)); assertEquals("add function expected {[INTEGER,INTEGER]}, but get [BOOLEAN,BOOLEAN]", exception.getMessage()); }