DATACMNS-1258 - Polishing.
Moved newly introduced types into the ….data.repository.query package as the parser one contains types that parses queries from method names. Simplified the API surface by hiding SpelExtractor completely and making the API on SpelQueryContext more convenient to directly create a SpelEvaluator.
This commit is contained in:
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.repository.query.parser;
|
||||
package org.springframework.data.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.repository.query.SpelQueryContext.QuotationMap;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link QuotationMap}.
|
||||
@@ -41,7 +42,9 @@ public class QuotationMapUnitTests {
|
||||
|
||||
@Test // DATAJPA-1235
|
||||
public void simpleStringDoesNotContainQuotes() {
|
||||
|
||||
String query = "something";
|
||||
|
||||
isNotQuoted(query, "simple String", -1, 0, query.length() - 1, query.length(), query.length() + 1);
|
||||
}
|
||||
|
||||
@@ -49,6 +52,7 @@ public class QuotationMapUnitTests {
|
||||
public void fullySingleQuotedStringDoesContainQuotes() {
|
||||
|
||||
String query = "'something'";
|
||||
|
||||
isNotQuoted(query, "quoted String", -1, query.length());
|
||||
isQuoted(query, "quoted String", 0, 1, 5, query.length() - 1);
|
||||
}
|
||||
@@ -57,6 +61,7 @@ public class QuotationMapUnitTests {
|
||||
public void fullyDoubleQuotedStringDoesContainQuotes() {
|
||||
|
||||
String query = "\"something\"";
|
||||
|
||||
isNotQuoted(query, "double quoted String", -1, query.length());
|
||||
isQuoted(query, "double quoted String", 0, 1, 5, query.length() - 1);
|
||||
}
|
||||
@@ -65,6 +70,7 @@ public class QuotationMapUnitTests {
|
||||
public void stringWithEmptyQuotes() {
|
||||
|
||||
String query = "abc''def";
|
||||
|
||||
isNotQuoted(query, "zero length quote", -1, 0, 1, 2, 5, 6, 7);
|
||||
isQuoted(query, "zero length quote", 3, 4);
|
||||
}
|
||||
@@ -73,6 +79,7 @@ public class QuotationMapUnitTests {
|
||||
public void doubleInSingleQuotes() {
|
||||
|
||||
String query = "abc'\"'def";
|
||||
|
||||
isNotQuoted(query, "double inside single quote", -1, 0, 1, 2, 6, 7, 8);
|
||||
isQuoted(query, "double inside single quote", 3, 4, 5);
|
||||
}
|
||||
@@ -81,6 +88,7 @@ public class QuotationMapUnitTests {
|
||||
public void singleQuotesInDoubleQuotes() {
|
||||
|
||||
String query = "abc\"'\"def";
|
||||
|
||||
isNotQuoted(query, "single inside double quote", -1, 0, 1, 2, 6, 7, 8);
|
||||
isQuoted(query, "single inside double quote", 3, 4, 5);
|
||||
}
|
||||
@@ -95,11 +103,10 @@ public class QuotationMapUnitTests {
|
||||
|
||||
@Test // DATAJPA-1235
|
||||
public void openEndedQuoteThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> new QuotationMap("a'b"));
|
||||
}
|
||||
|
||||
private void isNotQuoted(String query, Object label, int... indexes) {
|
||||
private static void isNotQuoted(String query, Object label, int... indexes) {
|
||||
|
||||
QuotationMap quotationMap = new QuotationMap(query);
|
||||
|
||||
@@ -111,14 +118,15 @@ public class QuotationMapUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
private void isQuoted(String query, Object label, int... indexes) {
|
||||
private static void isQuoted(String query, Object label, int... indexes) {
|
||||
|
||||
QuotationMap quotationMap = new QuotationMap(query);
|
||||
|
||||
for (int index : indexes) {
|
||||
|
||||
assertThat(quotationMap.isQuoted(index))
|
||||
.describedAs(String.format("(%s) %s does contain a quote at %s", label, query, index)).isTrue();
|
||||
.describedAs(String.format("(%s) %s does contain a quote at %s", label, query, index)) //
|
||||
.isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.assertj.core.groups.Tuple;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.repository.query.SpelQueryContext.SpelExtractor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SpelExtractor}.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SpelExtractorUnitTests {
|
||||
|
||||
static final BiFunction<Integer, String, String> PARAMETER_NAME_SOURCE = (index, spel) -> "EPP" + index;
|
||||
static final BiFunction<String, String, String> REPLACEMENT_SOURCE = (prefix, name) -> prefix + name;
|
||||
|
||||
final SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullQueryThrowsException() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> context.parse(null));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void emptyStringGetsParsedCorrectly() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
SpelExtractor extractor = context.parse("");
|
||||
|
||||
softly.assertThat(extractor.getQueryString()).isEqualTo("");
|
||||
softly.assertThat(extractor.getParameterMap()).isEmpty();
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void findsAndReplacesExpressions() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
SpelExtractor extractor = context.parse(":#{one} ?#{two}");
|
||||
|
||||
softly.assertThat(extractor.getQueryString()).isEqualTo(":EPP0 ?EPP1");
|
||||
softly.assertThat(extractor.getParameterMap().entrySet()) //
|
||||
.extracting(Map.Entry::getKey, Map.Entry::getValue) //
|
||||
.containsExactlyInAnyOrder( //
|
||||
Tuple.tuple("EPP0", "one"), //
|
||||
Tuple.tuple("EPP1", "two") //
|
||||
);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void keepsStringWhenNoMatchIsFound() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
SpelExtractor extractor = context.parse("abcdef");
|
||||
|
||||
softly.assertThat(extractor.getQueryString()).isEqualTo("abcdef");
|
||||
softly.assertThat(extractor.getParameterMap()).isEmpty();
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void spelsInQuotesGetIgnored() {
|
||||
|
||||
List<String> queries = Arrays.asList(//
|
||||
"a'b:#{one}cd'ef", //
|
||||
"a'b:#{o'ne}cdef", //
|
||||
"ab':#{one}'cdef", //
|
||||
"ab:'#{one}cd'ef", //
|
||||
"ab:#'{one}cd'ef", //
|
||||
"a'b:#{o'ne}cdef");
|
||||
|
||||
queries.forEach(this::checkNoSpelIsFound);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
private void checkNoSpelIsFound(String query) {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
SpelExtractor extractor = context.parse(query);
|
||||
|
||||
softly.assertThat(extractor.getQueryString()).describedAs(query).isEqualTo(query);
|
||||
softly.assertThat(extractor.getParameterMap()).describedAs(query).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.repository.query;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SpelQueryContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public class SpelQueryContextUnitTests {
|
||||
|
||||
static final QueryMethodEvaluationContextProvider EVALUATION_CONTEXT_PROVIDER = QueryMethodEvaluationContextProvider.DEFAULT;
|
||||
static final BiFunction<Integer, String, String> PARAMETER_NAME_SOURCE = (index, spel) -> "EPP" + index;
|
||||
static final BiFunction<String, String, String> REPLACEMENT_SOURCE = (prefix, name) -> prefix + name;
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullParameterNameSourceThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> SpelQueryContext.of(null, REPLACEMENT_SOURCE));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullReplacementSourceThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> SpelQueryContext.of(PARAMETER_NAME_SOURCE, null));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void rejectsNullEvaluationContextProvider() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> context.withEvaluationContextProvider(null));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void createsEvaluatingContextUsingProvider() {
|
||||
|
||||
SpelQueryContext context = SpelQueryContext.of(PARAMETER_NAME_SOURCE, REPLACEMENT_SOURCE);
|
||||
|
||||
assertThat(context.withEvaluationContextProvider(EVALUATION_CONTEXT_PROVIDER)).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.repository.query.parser;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.assertj.core.groups.Tuple;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SpelQueryContext} and
|
||||
* {@link org.springframework.data.repository.query.parser.SpelQueryContext.SpelExtractor}
|
||||
*
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
public class SpelExtractorUnitTests {
|
||||
|
||||
static final String EXPRESSION_PARAMETER_PREFIX = "EPP";
|
||||
static final BiFunction<Integer, String, String> PARAMETER_NAME_SOURCE = (index, spel) -> EXPRESSION_PARAMETER_PREFIX + index;
|
||||
static final BiFunction<String, String, String> REPLACEMENT_SOURCE = (prefix, name) -> prefix + name;
|
||||
final SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullQueryThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
REPLACEMENT_SOURCE) //
|
||||
.parse(null) //
|
||||
);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullParameterNameSourceThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy(() -> new SpelQueryContext( //
|
||||
null, //
|
||||
REPLACEMENT_SOURCE) //
|
||||
);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void nullReplacementSourceThrowsException() {
|
||||
|
||||
assertThatExceptionOfType(IllegalArgumentException.class) //
|
||||
.isThrownBy( //
|
||||
() -> new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
null) //
|
||||
);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void emptyStringGetsParsedCorrectly() {
|
||||
|
||||
SpelQueryContext.SpelExtractor extractor = new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
REPLACEMENT_SOURCE //
|
||||
).parse("");
|
||||
|
||||
softly.assertThat(extractor.query()).isEqualTo("");
|
||||
softly.assertThat(extractor.parameterNameToSpelMap()).isEmpty();
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void findsAndReplacesExpressions() {
|
||||
|
||||
SpelQueryContext.SpelExtractor extractor = new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
REPLACEMENT_SOURCE //
|
||||
).parse(":#{one} ?#{two}");
|
||||
|
||||
softly.assertThat(extractor.query()).isEqualTo(":EPP0 ?EPP1");
|
||||
softly.assertThat(extractor.parameterNameToSpelMap().entrySet()) //
|
||||
.extracting(Map.Entry::getKey, Map.Entry::getValue) //
|
||||
.containsExactlyInAnyOrder( //
|
||||
Tuple.tuple("EPP0", "one"), //
|
||||
Tuple.tuple("EPP1", "two") //
|
||||
);
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void keepsStringWhenNoMatchIsFound() {
|
||||
|
||||
SpelQueryContext.SpelExtractor extractor = new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
REPLACEMENT_SOURCE //
|
||||
).parse("abcdef");
|
||||
|
||||
softly.assertThat(extractor.query()).isEqualTo("abcdef");
|
||||
softly.assertThat(extractor.parameterNameToSpelMap()).isEmpty();
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1258
|
||||
public void spelsInQuotesGetIgnored() {
|
||||
|
||||
List<String> queries = Arrays.asList("a'b:#{one}cd'ef", "a'b:#{o'ne}cdef", "ab':#{one}'cdef", "ab:'#{one}cd'ef",
|
||||
"ab:#'{one}cd'ef", "a'b:#{o'ne}cdef");
|
||||
|
||||
for (String query : queries) {
|
||||
checkNoSpelIsFound(query);
|
||||
}
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
private void checkNoSpelIsFound(String query) {
|
||||
|
||||
SpelQueryContext.SpelExtractor extractor = new SpelQueryContext( //
|
||||
PARAMETER_NAME_SOURCE, //
|
||||
REPLACEMENT_SOURCE //
|
||||
).parse(query);
|
||||
|
||||
softly.assertThat(extractor.query()).describedAs(query).isEqualTo(query);
|
||||
softly.assertThat(extractor.parameterNameToSpelMap()).describedAs(query).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user