### Question:
JsonPathExpression implements Expression { @Override public ExpressionResult apply(ExpressionContext expressionContext, ExpressionResult input) { ExpressionResult doc = document.apply(expressionContext, input); String json = jsonPath.apply(expressionContext, input).getValue().toString(); Object result = JsonPath.compile(json).read(doc.asJson()); List<ExpressionResult> values = new ArrayList<>(); boolean isList = false; if( result instanceof JSONArray) { isList = true; JSONArray resultArray = (JSONArray)result; resultArray.forEach(value -> values.add(toExpressionResult(value))); } else { values.add(toExpressionResult(result)); } if( ! isList) { if( values.size() == 1 ) return values.get(0); return NullExpressionResult.INSTANCE; } return new ListExpressionResult(values); } JsonPathExpression(String alias, Expression[] expressions); @Override ExpressionResult apply(ExpressionContext expressionContext, ExpressionResult input); @Override String alias();  }### Answer:
@Test public void apply() { testSubject = new JsonPathExpression("title", new Expression[]{ new Identifier("test"), new StringLiteral("$.book[*].title") }); ExpressionResult result = testSubject.apply(expressionContext, new MapExpressionResult(map)); assertThat(result).isInstanceOf(ListExpressionResult.class); ListExpressionResult resultList = (ListExpressionResult) result; assertThat(resultList.getValue()).contains(new StringExpressionResult("JSON: Questions and Answers")); }
@Test public void applySingleValue() { testSubject = new JsonPathExpression("title", new Expression[]{ new Identifier("test"), new StringLiteral("$.book[0].title") }); ExpressionResult result = testSubject.apply(expressionContext, new MapExpressionResult(map)); assertThat(result).isInstanceOf(StringExpressionResult.class); StringExpressionResult resultString = (StringExpressionResult) result; assertThat(resultString.getValue()).isEqualTo("Beginning JSON"); }
@Test public void applyNumberValue() { testSubject = new JsonPathExpression("title", new Expression[]{ new Identifier("test"), new StringLiteral("$.book[0].price") }); ExpressionResult result = testSubject.apply(expressionContext, new MapExpressionResult(map)); assertThat(result).isInstanceOf(NumericExpressionResult.class); assertThat(result.getValue()).isEqualTo(BigDecimal.valueOf(49.0)); }
@Test public void applyNodes() { testSubject = new JsonPathExpression("title", new Expression[]{ new Identifier("test"), new StringLiteral("$.book") }); ExpressionResult result = testSubject.apply(expressionContext, new MapExpressionResult(map)); assertThat(result).isInstanceOf(ListExpressionResult.class); ListExpressionResult resultList = (ListExpressionResult) result; }