From ef46d8123ea8a8cb7f1a75692a26874effce9f58 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 19 Oct 2016 16:25:11 +0200 Subject: [PATCH] SONAR-8307 Project measures query now supports equal operator --- .../component/es/ProjectMeasuresQuery.java | 9 ++++--- .../ws/ProjectMeasuresQueryFactory.java | 26 +++++++++++-------- .../ws/ProjectMeasuresQueryFactoryTest.java | 26 +++++++++++++++++-- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresQuery.java b/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresQuery.java index 0c152ed23e9..b64d67070ca 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresQuery.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresQuery.java @@ -25,6 +25,7 @@ import java.util.List; import static java.lang.String.format; import static java.util.Arrays.stream; +import static java.util.Objects.requireNonNull; public class ProjectMeasuresQuery { private List metricCriteria = new ArrayList<>(); @@ -39,7 +40,7 @@ public class ProjectMeasuresQuery { } public enum Operator { - LTE("<="), GT(">"); + LTE("<="), GT(">"), EQ("="); String value; @@ -65,9 +66,9 @@ public class ProjectMeasuresQuery { private final double value; public MetricCriteria(String metricKey, Operator operator, double value) { - this.metricKey = metricKey; - this.operator = operator; - this.value = value; + this.metricKey = requireNonNull(metricKey); + this.operator = requireNonNull(operator); + this.value = requireNonNull(value); } public String getMetricKey() { diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java index 76d93035a17..8fb948d41dd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java @@ -33,8 +33,8 @@ import static org.sonar.server.component.es.ProjectMeasuresQuery.Operator; class ProjectMeasuresQueryFactory { - private static final Splitter CRITERIA_SPLITTER = Splitter.on("and"); - private static final Pattern CRITERIA_PATTERN = Pattern.compile("(\\w+)\\s*([<>][=]?)\\s*(\\w+)"); + private static final Splitter CRITERIA_SPLITTER = Splitter.on(Pattern.compile("and", Pattern.CASE_INSENSITIVE)); + private static final Pattern CRITERIA_PATTERN = Pattern.compile("(\\w+)\\s*([<>]?[=]?)\\s*(\\w+)"); private ProjectMeasuresQueryFactory() { // Only static methods @@ -47,18 +47,22 @@ class ProjectMeasuresQueryFactory { ProjectMeasuresQuery query = new ProjectMeasuresQuery(); - CRITERIA_SPLITTER.split(filter.toLowerCase(ENGLISH)) - .forEach(criteria -> processCriteria(criteria, query)); + CRITERIA_SPLITTER.split(filter) + .forEach(criteria -> processCriterion(criteria, query)); return query; } - private static void processCriteria(String criteria, ProjectMeasuresQuery query) { - Matcher matcher = CRITERIA_PATTERN.matcher(criteria); - checkArgument(matcher.find() && matcher.groupCount() == 3, "Invalid criterion '%s'", criteria); - String metric = matcher.group(1); - Operator operator = Operator.getByValue(matcher.group(2)); - Double value = Double.parseDouble(matcher.group(3)); - query.addMetricCriterion(new MetricCriteria(metric, operator, value)); + private static void processCriterion(String criterion, ProjectMeasuresQuery query) { + try { + Matcher matcher = CRITERIA_PATTERN.matcher(criterion); + checkArgument(matcher.find() && matcher.groupCount() == 3, "Criterion should have a metric, an operator and a value"); + String metric = matcher.group(1).toLowerCase(ENGLISH); + Operator operator = Operator.getByValue(matcher.group(2)); + double value = Double.parseDouble(matcher.group(3)); + query.addMetricCriterion(new MetricCriteria(metric, operator, value)); + } catch (Exception e) { + throw new IllegalArgumentException(String.format("Invalid criterion '%s'", criterion), e); + } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java index 5a4014d07c9..dbe87ed2398 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java @@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.tuple; import static org.sonar.server.component.es.ProjectMeasuresQuery.MetricCriteria; import static org.sonar.server.component.es.ProjectMeasuresQuery.Operator; import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.newProjectMeasuresQuery; +import static org.sonar.test.ExceptionCauseMatcher.hasType; public class ProjectMeasuresQueryFactoryTest { @@ -49,7 +50,21 @@ public class ProjectMeasuresQueryFactoryTest { } @Test - public void convert_upper_case_to_lower_case() throws Exception { + public void create_query_having_equal_operation() throws Exception { + ProjectMeasuresQuery query = newProjectMeasuresQuery("ncloc = 10"); + + assertThat(query.getMetricCriteria()) + .extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue) + .containsOnly(tuple("ncloc", Operator.EQ, 10d)); + } + + @Test + public void search_is_case_insensitive() throws Exception { + assertThat(newProjectMeasuresQuery("ncloc > 10 AnD coverage <= 80 AND debt = 10 AND issues = 20").getMetricCriteria()).hasSize(4); + } + + @Test + public void convert_metric_to_lower_case() throws Exception { assertThat(newProjectMeasuresQuery("NCLOC > 10 AND coVERage <= 80").getMetricCriteria()) .extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue) .containsOnly( @@ -74,7 +89,7 @@ public class ProjectMeasuresQueryFactoryTest { @Test public void fail_on_unknown_operator() throws Exception { expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Unknown operator '>='"); + expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("Unknown operator '>='")); newProjectMeasuresQuery("ncloc >= 10"); } @@ -85,6 +100,13 @@ public class ProjectMeasuresQueryFactoryTest { newProjectMeasuresQuery("ncloc ? 10"); } + @Test + public void fail_when_not_double() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Invalid criterion 'ncloc > ten'"); + newProjectMeasuresQuery("ncloc > ten"); + } + @Test public void fail_when_no_operator() throws Exception { expectedException.expect(IllegalArgumentException.class); -- 2.39.5