public Object evaluate(
      final GenericRow row,
      final Object defaultValue,
      final ProcessingLogger logger,
      final Supplier<String> errorMsg
  ) {
    try {
      return expressionEvaluator.evaluate(new Object[]{
          spec.resolveArguments(row),
          defaultValue,
          logger,
          row
      });
    } catch (final Exception e) {
      final Throwable cause = e instanceof InvocationTargetException
          ? e.getCause()
          : e;

      logger.error(RecordProcessingError.recordProcessingError(errorMsg.get(), cause, row));
      return defaultValue;
    }
  }
@Test
  public void shouldEvaluateExpressionWithValueColumnSpecs() throws Exception {
    // Given:
    spec.addParameter(
        ColumnName.of("foo1"),
        Integer.class,
        0
    );
    spec.addParameter(
        ColumnName.of("foo2"),
        Integer.class,
        1
    );
    compiledExpression = new CompiledExpression(
        expressionEvaluator,
        spec.build(),
        EXPRESSION_TYPE,
        expression
    );

    // When:
    final Object result = compiledExpression
        .evaluate(genericRow(123, 456), DEFAULT_VAL, processingLogger, errorMsgSupplier);

    // Then:
    assertThat(result, equalTo(RETURN_VALUE));

    final Map<String, Object> arguments = new HashMap<>();
    arguments.put("var0", 123);
    arguments.put("var1", 456);

    verify(expressionEvaluator).evaluate(new Object[]{arguments, DEFAULT_VAL, processingLogger, genericRow(123, 456)});
  }