PipelineFunctionSubstringBefore implements PipelineFunction { @Override public PipelineElement apply(final PipelineElement value, final String paramsIncludingParentheses, final ExpressionResolver expressionResolver) { final String splitValue = parseAndResolve(paramsIncludingParentheses, expressionResolver); return value.onResolved(previousStage -> { if (previousStage.contains(splitValue)) { return PipelineElement.resolved(previousStage.substring(0, previousStage.indexOf(splitValue))); } else { return PipelineElement.unresolved(); } }); }  @Override String getName(); @Override Signature getSignature(); @Override PipelineElement apply(final PipelineElement value, final String paramsIncludingParentheses,
            final ExpressionResolver expressionResolver);  }
@Test public void apply() { assertThat(function.apply(KNOWN_INPUT, "('" + SUBSTRING_AT + "')", expressionResolver)).contains(EXPECTED_RESULT); }
@Test public void returnsEmptyForEmptyInput() { assertThat(function.apply(EMPTY_INPUT, "('" + SUBSTRING_AT + "')", expressionResolver)).isEmpty(); }
@Test public void returnsEmptyIfSubstringNotPossible() { assertThat(function.apply(UNMATCHING_INPUT, "('" + SUBSTRING_AT + "')", expressionResolver)).isEmpty(); }
@Test public void throwsOnInvalidParameters() { assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> function.apply(KNOWN_INPUT, "()", expressionResolver) ); assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> function.apply(KNOWN_INPUT, "(thing:id)", expressionResolver) ); assertThatExceptionOfType(PlaceholderFunctionSignatureInvalidException.class).isThrownBy(() -> function.apply(KNOWN_INPUT, "", expressionResolver) ); }