public Token<? extends Number> evaluate(BiFunction<Number, Number, Token<? extends Number>> function, Pair<Token<? extends Number>, Token<? extends Number>> p) { if (p == null || p.getKey() == null || p.getValue() == null) { throw new IllegalArgumentException(); } final Number l = p.getKey().getValue(); final Number r = p.getValue().getValue(); return function.apply(l == null ? 0 : l, r == null ? 0 : r); }
@Override @SuppressWarnings("unchecked") public void exitNotFunc(StellarParser.NotFuncContext ctx) { final FrameContext.Context context = getArgContext(); expression.tokenDeque.push(new Token<>((tokenDeque, state) -> { Token<Boolean> arg = (Token<Boolean>) popDeque(tokenDeque); Boolean v = Optional.ofNullable(ConversionUtils.convert(arg.getValue(), Boolean.class)).orElse(false); tokenDeque.push(new Token<>(!v, Boolean.class, context)); }, DeferredFunction.class, context)); }
@Test public void evaluateIntegerShouldReturnIntegerAdd() throws Exception { Token<Integer> l = mock(Token.class); when(l.getValue()).thenReturn(1); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.addition(null), p); assertTrue(evaluated.getValue() instanceof Integer); assertEquals(3, evaluated.getValue()); }
@Test public void evaluateFloatsShouldReturnFloatAdd() throws Exception { Token<Float> l = mock(Token.class); when(l.getValue()).thenReturn(1F); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.addition(null), p); assertTrue(evaluated.getValue() instanceof Float); assertEquals(3F, evaluated.getValue()); }
@Test public void evaluateFloatsShouldReturnFloatMul() throws Exception { Token<Float> l = mock(Token.class); when(l.getValue()).thenReturn(1F); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.multiplication(null), p); assertTrue(evaluated.getValue() instanceof Float); assertEquals(2F, evaluated.getValue()); }
@Test public void evaluateIntegerShouldReturnIntegerMul() throws Exception { Token<Integer> l = mock(Token.class); when(l.getValue()).thenReturn(1); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.multiplication(null), p); assertTrue(evaluated.getValue() instanceof Integer); assertEquals(2, evaluated.getValue()); }
@Test public void evaluateDoubleShouldReturnDoubleSub() throws Exception { Token<Integer> l = mock(Token.class); when(l.getValue()).thenReturn(1); Token<Double> r = mock(Token.class); when(r.getValue()).thenReturn(2D); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.subtraction(null), p); assertTrue(evaluated.getValue() instanceof Double); assertEquals(-1.0D, evaluated.getValue()); }
@Test public void evaluateIntegerShouldReturnIntegerDiv() throws Exception { Token<Integer> l = mock(Token.class); when(l.getValue()).thenReturn(1); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.division(null), p); assertTrue(evaluated.getValue() instanceof Integer); assertEquals(1 / 2, evaluated.getValue()); }
@Test public void evaluateIntegerShouldReturnIntegerWhenLeftsValueIsNull() throws Exception { Token<Integer> l = mock(Token.class); when(l.getValue()).thenReturn(null); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.addition(null), p); assertTrue(evaluated.getValue() instanceof Integer); assertEquals(2, evaluated.getValue()); }
@Test public void evaluateLongsShouldReturnLongMul() throws Exception { Token<Long> l = mock(Token.class); when(l.getValue()).thenReturn(1L); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.multiplication(null), p); assertTrue(evaluated.getValue() instanceof Long); assertEquals(2L, evaluated.getValue()); }
@Test public void evaluateLongsShouldReturnLongDiv() throws Exception { Token<Long> l = mock(Token.class); when(l.getValue()).thenReturn(1L); Token<Integer> r = mock(Token.class); when(r.getValue()).thenReturn(2); Pair<Token<? extends Number>, Token<? extends Number>> p = Pair.of(l, r); Token<? extends Number> evaluated = evaluator.evaluate(ArithmeticEvaluator.ArithmeticEvaluatorFunctions.division(null), p); assertTrue(evaluated.getValue() instanceof Long); assertEquals(0L, evaluated.getValue()); }
@Test public void eqTestForTwoLongs() throws Exception { Token<Long> left = mock(Token.class); when(left.getValue()).thenReturn(1L); Token<Long> right = mock(Token.class); when(right.getValue()).thenReturn(1L); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); when(op.EQ()).thenReturn(mock(TerminalNode.class)); assertTrue(evaluator.evaluate(left, right, op)); }
@Test public void leftNotNullAndRightNullShouldBeFalse() throws Exception { Token<Double> left = mock(Token.class); when(left.getValue()).thenReturn(1D); Token<Long> right = mock(Token.class); when(right.getValue()).thenReturn(null); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); when(op.EQ()).thenReturn(mock(TerminalNode.class)); boolean evaluated = evaluator.evaluate(left, right, op); assertFalse(evaluated); }
@Test public void eqTestForTwoFloats() throws Exception { Token<Float> left = mock(Token.class); when(left.getValue()).thenReturn(1F); Token<Float> right = mock(Token.class); when(right.getValue()).thenReturn(1F); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); when(op.EQ()).thenReturn(mock(TerminalNode.class)); assertTrue(evaluator.evaluate(left, right, op)); }
@Test public void eqTestForTwoIntegers() throws Exception { Token<Integer> left = mock(Token.class); when(left.getValue()).thenReturn(1); Token<Integer> right = mock(Token.class); when(right.getValue()).thenReturn(1); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); when(op.EQ()).thenReturn(mock(TerminalNode.class)); assertTrue(evaluator.evaluate(left, right, op)); }
@Test @SuppressWarnings("unchecked") public void nonSupportedOperatorThrowsExceptionNumbericComparison() throws Exception { Token<Long> left = mock(Token.class); when(left.getValue()).thenReturn(1L); Token<Long> right = mock(Token.class); when(right.getValue()).thenReturn(0L); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); exception.expect(ParseException.class); exception.expectMessage("Unsupported operator: " + op); evaluator.evaluate(left, right, op); }
@Test public void evaluateNotEqShouldProperlyCallEqualityOperatorsEvaluator() throws Exception { Token<Double> left = mock(Token.class); when(left.getValue()).thenReturn(1D); Token<Double> right = mock(Token.class); when(right.getValue()).thenReturn(1D); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); when(op.NEQ()).thenReturn(mock(TerminalNode.class)); Token<Boolean> evaluated = evaluator.evaluate(left, right, op, null); assertFalse(evaluated.getValue()); }
@Test public void unexpectedOperatorShouldThrowException() throws Exception { exception.expect(ParseException.class); exception.expectMessage("Unsupported operations. The following expression is invalid: "); Token<Double> left = mock(Token.class); when(left.getValue()).thenReturn(0D); Token<Double> right = mock(Token.class); when(right.getValue()).thenReturn(1D); StellarParser.ComparisonOpContext op = mock(StellarParser.ComparisonOpContext.class); evaluator.evaluate(left, right, op, null); }