From bc8291e48a31911171b341e0b1060bf663b1a0f1 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 5 Jun 2014 17:29:48 +0200 Subject: [PATCH] SONAR-5300 Return differential measures when a period is set in /api/components/app --- .../org/sonar/core/issue/db/IssueDao.java | 9 +- .../org/sonar/core/issue/db/IssueMapper.java | 5 +- .../org/sonar/core/measure/db/MeasureDto.java | 44 ++++ .../org/sonar/core/issue/db/IssueMapper.xml | 6 + .../sonar/core/measure/db/MeasureMapper.xml | 5 + .../org/sonar/core/issue/db/IssueDaoTest.java | 9 +- .../IssueDaoTest/find_rules_by_component.xml | 20 +- .../find_severities_by_component.xml | 26 +-- .../component/ws/ComponentAppAction.java | 200 ++++++++++++------ .../org/sonar/server/issue/IssueService.java | 8 +- .../component/ws/ComponentAppActionTest.java | 151 +++++++++++-- .../server/component/ws/ComponentsWsTest.java | 2 +- .../sonar/server/issue/IssueServiceTest.java | 11 +- .../measure/persistence/MeasureDaoTest.java | 5 + .../app_with_issues_measures.json | 29 +++ ...th_issues_measures_when_period_is_set.json | 31 +++ .../app_with_measures.json | 8 +- .../app_with_measures_when_period_is_set.json | 23 ++ .../app_with_rules_when_period_is_set.json | 20 ++ ...pp_with_severities_when_period_is_set.json | 20 ++ .../persistence/MeasureDaoTest/shared.xml | 9 +- 21 files changed, 506 insertions(+), 135 deletions(-) create mode 100644 sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures_when_period_is_set.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures_when_period_is_set.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_rules_when_period_is_set.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_severities_when_period_is_set.json diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java index 3aad9a41f25..9c876b02874 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java @@ -36,6 +36,7 @@ import javax.annotation.Nullable; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.List; import static com.google.common.collect.Lists.newArrayList; @@ -142,12 +143,12 @@ public class IssueDao implements BatchComponent, ServerComponent { } // TODO replace by aggregation in IssueIndex - public List findRulesByComponent(String componentKey, DbSession session) { - return session.getMapper(IssueMapper.class).findRulesByComponent(componentKey); + public List findRulesByComponent(String componentKey, @Nullable Date createdAtOrAfter, DbSession session) { + return session.getMapper(IssueMapper.class).findRulesByComponent(componentKey, createdAtOrAfter); } // TODO replace by aggregation in IssueIndex - public List findSeveritiesByComponent(String componentKey, DbSession session) { - return session.getMapper(IssueMapper.class).findSeveritiesByComponent(componentKey); + public List findSeveritiesByComponent(String componentKey, @Nullable Date createdAtOrAfter, DbSession session) { + return session.getMapper(IssueMapper.class).findSeveritiesByComponent(componentKey, createdAtOrAfter); } } diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java index 7204be2b572..64565efbffd 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java @@ -26,6 +26,7 @@ import org.sonar.core.rule.RuleDto; import javax.annotation.Nullable; import java.util.Collection; +import java.util.Date; import java.util.List; public interface IssueMapper { @@ -48,9 +49,9 @@ public interface IssueMapper { @Nullable @Param("userId") Integer userId, @Nullable @Param("role") String role); - List findRulesByComponent(String componentKey); + List findRulesByComponent(@Param("componentKey") String componentKey, @Nullable @Param("createdAt") Date createdAtOrAfter); - List findSeveritiesByComponent(String componentKey); + List findSeveritiesByComponent(@Param("componentKey") String componentKey, @Nullable @Param("createdAt") Date createdAtOrAfter); void insert(IssueDto issue); diff --git a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java index 886a06d31ee..7d45ab6784e 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java +++ b/sonar-core/src/main/java/org/sonar/core/measure/db/MeasureDto.java @@ -28,6 +28,8 @@ import javax.annotation.Nullable; public class MeasureDto extends Dto{ + private static final String INDEX_SHOULD_BE_IN_RANGE_FROM_1_TO_5 = "Index should be in range from 1 to 5"; + private Integer id; private String metricKey; @@ -40,6 +42,8 @@ public class MeasureDto extends Dto{ private byte[] data; + protected Double variation1, variation2, variation3, variation4, variation5; + private MeasureDto(){ // Nothing here } @@ -92,6 +96,46 @@ public class MeasureDto extends Dto{ return textValue; } + public Double getVariation(int index) { + switch (index) { + case 1: + return variation1; + case 2: + return variation2; + case 3: + return variation3; + case 4: + return variation4; + case 5: + return variation5; + default: + throw new IndexOutOfBoundsException(INDEX_SHOULD_BE_IN_RANGE_FROM_1_TO_5); + } + } + + public MeasureDto setVariation(int index, Double d) { + switch (index) { + case 1: + variation1 = d; + break; + case 2: + variation2 = d; + break; + case 3: + variation3 = d; + break; + case 4: + variation4 = d; + break; + case 5: + variation5 = d; + break; + default: + throw new IndexOutOfBoundsException(INDEX_SHOULD_BE_IN_RANGE_FROM_1_TO_5); + } + return this; + } + @Override public MeasureKey getKey() { return MeasureKey.of(componentKey, metricKey); diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml index 3180427721c..6d7a4f2401f 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml @@ -322,6 +322,9 @@ AND p.kee=#{componentKey} AND i.resolution IS NULL + + AND i.issue_creation_date >= #{createdAt} + @@ -333,6 +336,9 @@ AND projects.kee=#{componentKey} AND i.resolution IS NULL + + AND i.issue_creation_date >= #{createdAt} + diff --git a/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml b/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml index 48d066cade0..cde157e101f 100644 --- a/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/measure/db/MeasureMapper.xml @@ -9,6 +9,11 @@ pm.value as value, pm.text_value as textValue, pm.measure_data as data, + pm.variation_value_1 as variation1, + pm.variation_value_2 as variation2, + pm.variation_value_3 as variation3, + pm.variation_value_4 as variation4, + pm.variation_value_5 as variation5, p.kee as componentKey, metric.name as metricKey diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java index 4f2f0e2c528..5157ab9319a 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java @@ -32,7 +32,6 @@ import org.sonar.api.rule.Severity; import org.sonar.api.utils.DateUtils; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.persistence.DbSession; -import org.sonar.core.rule.RuleDto; import java.util.List; @@ -444,16 +443,16 @@ public class IssueDaoTest extends AbstractDaoTestCase { public void find_rules_by_component() { setupData("shared", "find_rules_by_component"); - List results = dao.findRulesByComponent("Action.java", session); - assertThat(results).hasSize(3); + assertThat(dao.findRulesByComponent("Action.java", null, session)).hasSize(3); + assertThat(dao.findRulesByComponent("Action.java", DateUtils.parseDate("2013-04-17"), session)).hasSize(2); } @Test public void find_severities_by_component() { setupData("shared", "find_severities_by_component"); - List results = dao.findSeveritiesByComponent("Action.java", session); - assertThat(results).containsExactly(Severity.BLOCKER, Severity.MAJOR, Severity.BLOCKER); + assertThat(dao.findSeveritiesByComponent("Action.java", null, session)).containsExactly(Severity.BLOCKER, Severity.MAJOR, Severity.BLOCKER); + assertThat(dao.findSeveritiesByComponent("Action.java", DateUtils.parseDate("2013-04-17"), session)).containsExactly(Severity.MAJOR); } private List getIssueIds(List issues) { diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_rules_by_component.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_rules_by_component.xml index d396550e94d..50ef94fe567 100644 --- a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_rules_by_component.xml +++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_rules_by_component.xml @@ -44,11 +44,11 @@ assignee="perceval" author_login="[null]" issue_attributes="JIRA=FOO-1234" - issue_creation_date="2013-04-16" - issue_update_date="2013-04-16" - issue_close_date="2013-04-16" - created_at="2013-04-16" - updated_at="2013-04-16" + issue_creation_date="2013-04-17" + issue_update_date="2013-04-17" + issue_close_date="2013-04-17" + created_at="2013-04-17" + updated_at="2013-04-17" /> @@ -71,10 +71,10 @@ assignee="perceval" author_login="[null]" issue_attributes="JIRA=FOO-1234" - issue_creation_date="2013-04-16" - issue_update_date="2013-04-16" - issue_close_date="2013-04-16" - created_at="2013-04-16" - updated_at="2013-04-16" + issue_creation_date="2013-04-18" + issue_update_date="2013-04-18" + issue_close_date="2013-04-18" + created_at="2013-04-18" + updated_at="2013-04-18" /> diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_severities_by_component.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_severities_by_component.xml index fbadd1cb359..2d7e237e3ed 100644 --- a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_severities_by_component.xml +++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_severities_by_component.xml @@ -1,23 +1,3 @@ - - @@ -64,9 +44,9 @@ assignee="perceval" author_login="[null]" issue_attributes="JIRA=FOO-1234" - issue_creation_date="2013-04-16" - issue_update_date="2013-04-16" - issue_close_date="2013-04-16" + issue_creation_date="2013-04-17" + issue_update_date="2013-04-17" + issue_close_date="2013-04-17" created_at="2013-04-16" updated_at="2013-04-16" /> diff --git a/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java b/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java index 6b9ae2ff38e..a617f22bb68 100644 --- a/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java +++ b/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java @@ -24,6 +24,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Multiset; import com.google.common.io.Resources; +import org.elasticsearch.common.inject.internal.Strings; import org.sonar.api.component.Component; import org.sonar.api.i18n.I18n; import org.sonar.api.measures.CoreMetrics; @@ -67,7 +68,8 @@ import static com.google.common.collect.Maps.newHashMap; public class ComponentAppAction implements RequestHandler { - private static final String KEY = "key"; + private static final String PARAM_KEY = "key"; + private static final String PARAM_PERIOD = "period"; private final DbClient dbClient; @@ -97,15 +99,20 @@ public class ComponentAppAction implements RequestHandler { .setResponseExample(Resources.getResource(this.getClass(), "components-app-example-show.json")); action - .createParam(KEY) + .createParam(PARAM_KEY) .setRequired(true) .setDescription("File key") .setExampleValue("org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java"); + + action + .createParam(PARAM_PERIOD) + .setDescription("Period index in order to get differential measures") + .setPossibleValues(1, 2, 3, 4, 5); } @Override public void handle(Request request, Response response) { - String fileKey = request.mandatoryParam(KEY); + String fileKey = request.mandatoryParam(PARAM_KEY); UserSession userSession = UserSession.get(); JsonWriter json = response.newJsonWriter(); @@ -119,11 +126,18 @@ public class ComponentAppAction implements RequestHandler { } userSession.checkComponentPermission(UserRole.USER, fileKey); + List periodList = periods(component.projectId(), session); + Integer periodIndex = request.paramAsInt(PARAM_PERIOD); + Date periodDate = periodDate(periodIndex, periodList); + + RulesAggregation rulesAggregation = issueService.findRulesByComponent(component.key(), periodDate, session); + Multiset severitiesAggregation = issueService.findSeveritiesByComponent(component.key(), periodDate, session); + appendComponent(json, component, userSession, session); appendPermissions(json, component, userSession); - appendPeriods(json, component.projectId(), session); - appendIssuesAggregation(json, component.key(), session); - appendMeasures(json, component, session); + appendPeriods(json, periodList); + appendIssuesAggregation(json, rulesAggregation, severitiesAggregation, session); + appendMeasures(json, component, severitiesAggregation, periodIndex, session); appendExtensions(json, component, userSession); } finally { MyBatis.closeQuietly(session); @@ -166,67 +180,53 @@ public class ComponentAppAction implements RequestHandler { json.prop("canBulkChange", userSession.isLoggedIn()); } - private void appendMeasures(JsonWriter json, ComponentDto component, DbSession session) { + private void appendMeasures(JsonWriter json, ComponentDto component, Multiset severitiesAggregation, Integer periodIndex, DbSession session) { json.name("measures").beginObject(); String fileKey = component.getKey(); List measures = dbClient.measureDao().findByComponentKeyAndMetricKeys(fileKey, - newArrayList(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.VIOLATIONS_KEY, - CoreMetrics.BLOCKER_VIOLATIONS_KEY, CoreMetrics.CRITICAL_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, - CoreMetrics.INFO_VIOLATIONS_KEY, CoreMetrics.TESTS_KEY), + newArrayList(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.TESTS_KEY), session ); - json.prop("fNcloc", formatMeasure(CoreMetrics.NCLOC_KEY, measures)); - json.prop("fCoverage", formatMeasure(CoreMetrics.COVERAGE_KEY, measures)); - json.prop("fDuplicationDensity", formatMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, measures)); - json.prop("fDebt", formatMeasure(CoreMetrics.TECHNICAL_DEBT_KEY, measures)); - json.prop("fIssues", formatMeasure(CoreMetrics.VIOLATIONS_KEY, measures)); - json.prop("fBlockerIssues", formatMeasure(CoreMetrics.BLOCKER_VIOLATIONS_KEY, measures)); - json.prop("fCriticalIssues", formatMeasure(CoreMetrics.CRITICAL_VIOLATIONS_KEY, measures)); - json.prop("fMajorIssues", formatMeasure(CoreMetrics.MAJOR_VIOLATIONS_KEY, measures)); - json.prop("fMinorIssues", formatMeasure(CoreMetrics.MINOR_VIOLATIONS_KEY, measures)); - json.prop("fInfoIssues", formatMeasure(CoreMetrics.INFO_VIOLATIONS_KEY, measures)); - json.prop("fTests", formatMeasure(CoreMetrics.TESTS_KEY, measures)); + json.prop("fNcloc", formatMeasure(CoreMetrics.NCLOC_KEY, measures, periodIndex)); + json.prop("fCoverage", formatMeasure(CoreMetrics.COVERAGE_KEY, measures, periodIndex)); + json.prop("fDuplicationDensity", formatMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, measures, periodIndex)); + json.prop("fDebt", formatMeasure(CoreMetrics.TECHNICAL_DEBT_KEY, measures, periodIndex)); + json.prop("fTests", formatMeasure(CoreMetrics.TESTS_KEY, measures, periodIndex)); + + json.prop("fIssues", i18n.formatInteger(UserSession.get().locale(), severitiesAggregation.size())); + for (String severity : severitiesAggregation.elementSet()) { + json.prop("f" + Strings.capitalize(severity.toLowerCase()) + "Issues", i18n.formatInteger(UserSession.get().locale(), severitiesAggregation.count(severity))); + } json.endObject(); } - private void appendPeriods(JsonWriter json, Long projectId, DbSession session) { + private void appendPeriods(JsonWriter json, List periodList) { json.name("periods").beginArray(); - SnapshotDto snapshotDto = dbClient.resourceDao().getLastSnapshotByResourceId(projectId, session); - if (snapshotDto != null) { - for (int i = 1; i <= 5; i++) { - String mode = snapshotDto.getPeriodMode(i); - if (mode != null) { - Date periodDate = snapshotDto.getPeriodDate(i); - String label = periods.label(mode, snapshotDto.getPeriodModeParameter(i), periodDate); - if (label != null) { - json.beginArray() - .value(i) - .value(label) - .value(periodDate != null ? DateUtils.formatDateTime(periodDate) : null) - .endArray(); - } - } - } + for (Period period : periodList) { + Date periodDate = period.date(); + json.beginArray() + .value(period.index()) + .value(period.label()) + .value(periodDate != null ? DateUtils.formatDateTime(periodDate) : null) + .endArray(); } json.endArray(); } - private void appendIssuesAggregation(JsonWriter json, String componentKey, DbSession session) { + private void appendIssuesAggregation(JsonWriter json, RulesAggregation rulesAggregation, Multiset severitiesAggregation, DbSession session) { json.name("severities").beginArray(); - Multiset severities = issueService.findSeveritiesByComponent(componentKey, session); - for (String severity : severities.elementSet()) { + for (String severity : severitiesAggregation.elementSet()) { json.beginArray() .value(severity) .value(i18n.message(UserSession.get().locale(), "severity." + severity, null)) - .value(severities.count(severity)) + .value(severitiesAggregation.count(severity)) .endArray(); } json.endArray(); json.name("rules").beginArray(); - RulesAggregation rulesAggregation = issueService.findRulesByComponent(componentKey, session); for (RulesAggregation.Rule rule : rulesAggregation.rules()) { json.beginArray() .value(rule.ruleKey().toString()) @@ -254,18 +254,54 @@ public class ComponentAppAction implements RequestHandler { List providedExtensions = newArrayList("tests_viewer", "coverage", "duplications", "issues", "source"); for (ViewProxy page : extensions) { if (!providedExtensions.contains(page.getId())) { - if (page.getUserRoles().length == 0) { + addExtension(page, result, component, userSession); + } + } + return result; + } + + private void addExtension(ViewProxy page, Map result, ComponentDto component, UserSession userSession){ + if (page.getUserRoles().length == 0) { + result.put(page.getId(), page.getTitle()); + } else { + for (String userRole : page.getUserRoles()) { + if (userSession.hasComponentPermission(userRole, component.key())) { result.put(page.getId(), page.getTitle()); - } else { - for (String userRole : page.getUserRoles()) { - if (userSession.hasComponentPermission(userRole, component.key())) { - result.put(page.getId(), page.getTitle()); - } + } + } + } + } + + private List periods(Long projectId, DbSession session) { + List periodList = newArrayList(); + SnapshotDto snapshotDto = dbClient.resourceDao().getLastSnapshotByResourceId(projectId, session); + if (snapshotDto != null) { + for (int i = 1; i <= 5; i++) { + String mode = snapshotDto.getPeriodMode(i); + if (mode != null) { + Date periodDate = snapshotDto.getPeriodDate(i); + String label = periods.label(mode, snapshotDto.getPeriodModeParameter(i), periodDate); + if (label != null) { + periodList.add(new Period(i, label, periodDate)); } } } } - return result; + return periodList; + } + + @CheckForNull + private Date periodDate(@Nullable final Integer periodIndex, List periodList){ + if (periodIndex != null) { + Period period = Iterables.find(periodList, new Predicate() { + @Override + public boolean apply(@Nullable Period input) { + return input != null && periodIndex.equals(input.index()); + } + }, null); + return period != null ? period.date() : null; + } + return null; } @CheckForNull @@ -281,30 +317,51 @@ public class ComponentAppAction implements RequestHandler { } @CheckForNull - private String formatMeasure(final String metricKey, List measures) { + private String formatMeasure(final String metricKey, List measures, @Nullable Integer periodIndex) { MeasureDto measure = measureByMetricKey(metricKey, measures); if (measure != null) { Metric metric = CoreMetrics.getMetric(measure.getKey().metricKey()); - Double value = measure.getValue(); - if (value != null) { - return formatValue(value, metric.getType()); + if (periodIndex == null) { + Double value = measure.getValue(); + if (value != null) { + return formatValue(value, metric.getType()); + } + } else { + Double variation = measure.getVariation(periodIndex); + if (variation != null) { + return formatVariation(variation, metric.getType()); + } } } return null; } @CheckForNull - private String formatValue(Double value, Metric.ValueType metryType) { - if (metryType.equals(Metric.ValueType.FLOAT)) { + private String formatValue(Double value, Metric.ValueType metricType) { + if (metricType.equals(Metric.ValueType.FLOAT)) { return i18n.formatDouble(UserSession.get().locale(), value); } - if (metryType.equals(Metric.ValueType.INT)) { + if (metricType.equals(Metric.ValueType.INT)) { return i18n.formatInteger(UserSession.get().locale(), value.intValue()); } - if (metryType.equals(Metric.ValueType.PERCENT)) { + if (metricType.equals(Metric.ValueType.PERCENT)) { return i18n.formatDouble(UserSession.get().locale(), value) + "%"; } - if (metryType.equals(Metric.ValueType.WORK_DUR)) { + if (metricType.equals(Metric.ValueType.WORK_DUR)) { + return durations.format(UserSession.get().locale(), durations.create(value.longValue()), Durations.DurationFormat.SHORT); + } + return null; + } + + @CheckForNull + private String formatVariation(Double value, Metric.ValueType metricType) { + if (metricType.equals(Metric.ValueType.FLOAT) || metricType.equals(Metric.ValueType.PERCENT)) { + return i18n.formatDouble(UserSession.get().locale(), value); + } + if (metricType.equals(Metric.ValueType.INT)) { + return i18n.formatInteger(UserSession.get().locale(), value.intValue()); + } + if (metricType.equals(Metric.ValueType.WORK_DUR)) { return durations.format(UserSession.get().locale(), durations.create(value.longValue()), Durations.DurationFormat.SHORT); } return null; @@ -320,4 +377,29 @@ public class ComponentAppAction implements RequestHandler { }, null); } + protected static class Period { + Integer index; + String label; + Date date; + + protected Period(Integer index, String label, @Nullable Date date) { + this.index = index; + this.label = label; + this.date = date; + } + + public Integer index() { + return index; + } + + public String label() { + return label; + } + + @CheckForNull + public Date date() { + return date; + } + } + } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java index 29f7dece639..5c97fc8f070 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java @@ -281,18 +281,18 @@ public class IssueService implements ServerComponent { } // TODO result should be replaced by an aggregation object in IssueIndex - public RulesAggregation findRulesByComponent(String componentKey, DbSession session) { + public RulesAggregation findRulesByComponent(String componentKey, @Nullable Date periodDate, DbSession session) { RulesAggregation rulesAggregation = new RulesAggregation(); - for (RuleDto ruleDto : issueDao.findRulesByComponent(componentKey, session)) { + for (RuleDto ruleDto : issueDao.findRulesByComponent(componentKey, periodDate, session)) { rulesAggregation.add(ruleDto); } return rulesAggregation; } // TODO result should be replaced by an aggregation object in IssueIndex - public Multiset findSeveritiesByComponent(String componentKey, DbSession session) { + public Multiset findSeveritiesByComponent(String componentKey, @Nullable Date periodDate, DbSession session) { Multiset aggregation = HashMultiset.create(); - for (String severity : issueDao.findSeveritiesByComponent(componentKey, session)) { + for (String severity : issueDao.findSeveritiesByComponent(componentKey, periodDate, session)) { aggregation.add(severity); } return aggregation; diff --git a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java index 5cc36e08b2b..fe5908c64e0 100644 --- a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java +++ b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java @@ -21,6 +21,7 @@ package org.sonar.server.component.ws; import com.google.common.collect.HashMultiset; +import com.google.common.collect.LinkedHashMultiset; import com.google.common.collect.Multiset; import org.junit.Before; import org.junit.Test; @@ -127,8 +128,8 @@ public class ComponentAppActionTest { when(dbClient.propertiesDao()).thenReturn(propertiesDao); when(dbClient.measureDao()).thenReturn(measureDao); - when(issueService.findSeveritiesByComponent(anyString(), eq(session))).thenReturn(mock(Multiset.class)); - when(issueService.findRulesByComponent(anyString(), eq(session))).thenReturn(mock(RulesAggregation.class)); + when(issueService.findSeveritiesByComponent(anyString(), any(Date.class), eq(session))).thenReturn(mock(Multiset.class)); + when(issueService.findRulesByComponent(anyString(), any(Date.class), eq(session))).thenReturn(mock(RulesAggregation.class)); when(measureDao.findByComponentKeyAndMetricKeys(anyString(), anyListOf(String.class), eq(session))).thenReturn(measures); tester = new WsTester(new ComponentsWs(new ComponentAppAction(dbClient, issueService, sourceService, views, periods, durations, i18n))); @@ -182,18 +183,11 @@ public class ComponentAppActionTest { @Test public void app_with_measures() throws Exception { MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); - addComponent(); addMeasure(CoreMetrics.NCLOC_KEY, 200); addMeasure(CoreMetrics.COVERAGE_KEY, 95.4); addMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, 7.4); - addMeasure(CoreMetrics.VIOLATIONS_KEY, 14); - addMeasure(CoreMetrics.BLOCKER_VIOLATIONS_KEY, 1); - addMeasure(CoreMetrics.CRITICAL_VIOLATIONS_KEY, 2); - addMeasure(CoreMetrics.MAJOR_VIOLATIONS_KEY, 5); - addMeasure(CoreMetrics.MINOR_VIOLATIONS_KEY, 4); - addMeasure(CoreMetrics.INFO_VIOLATIONS_KEY, 2); measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, CoreMetrics.TECHNICAL_DEBT_KEY)).setValue(182.0)); when(durations.format(any(Locale.class), any(Duration.class), eq(Durations.DurationFormat.SHORT))).thenReturn("3h 2min"); @@ -203,8 +197,86 @@ public class ComponentAppActionTest { verify(measureDao).findByComponentKeyAndMetricKeys(eq(COMPONENT_KEY), measureKeysCaptor.capture(), eq(session)); assertThat(measureKeysCaptor.getValue()).contains(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, - CoreMetrics.TECHNICAL_DEBT_KEY, CoreMetrics.VIOLATIONS_KEY, - CoreMetrics.BLOCKER_VIOLATIONS_KEY, CoreMetrics.CRITICAL_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY); + CoreMetrics.TECHNICAL_DEBT_KEY); + } + + @Test + public void app_with_measures_when_period_is_set() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); + addComponent(); + addPeriod(); + + addVariationMeasure(CoreMetrics.NCLOC_KEY, 2, 1); + addVariationMeasure(CoreMetrics.COVERAGE_KEY, 5d, 1); + addVariationMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, 1.2, 1); + + measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, CoreMetrics.TECHNICAL_DEBT_KEY)).setVariation(1, 10.0)); + when(durations.format(any(Locale.class), any(Duration.class), eq(Durations.DurationFormat.SHORT))).thenReturn("10min"); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY).setParam("period", "1"); + request.execute().assertJson(getClass(), "app_with_measures_when_period_is_set.json"); + + verify(measureDao).findByComponentKeyAndMetricKeys(eq(COMPONENT_KEY), measureKeysCaptor.capture(), eq(session)); + assertThat(measureKeysCaptor.getValue()).contains(CoreMetrics.NCLOC_KEY, CoreMetrics.COVERAGE_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY, + CoreMetrics.TECHNICAL_DEBT_KEY); + } + + @Test + public void app_with_issues_measures() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); + addComponent(); + + Multiset severities = LinkedHashMultiset.create(); + severities.add("BLOCKER", 1); + severities.add("CRITICAL", 2); + severities.add("MAJOR", 5); + severities.add("MINOR", 4); + severities.add("INFO", 2); + when(issueService.findSeveritiesByComponent(COMPONENT_KEY, null, session)).thenReturn(severities); + when(i18n.message(any(Locale.class), eq("severity.BLOCKER"), isNull(String.class))).thenReturn("Blocker"); + when(i18n.message(any(Locale.class), eq("severity.CRITICAL"), isNull(String.class))).thenReturn("Critical"); + when(i18n.message(any(Locale.class), eq("severity.MAJOR"), isNull(String.class))).thenReturn("Major"); + when(i18n.message(any(Locale.class), eq("severity.MINOR"), isNull(String.class))).thenReturn("Minor"); + when(i18n.message(any(Locale.class), eq("severity.INFO"), isNull(String.class))).thenReturn("Info"); + + when(i18n.formatInteger(any(Locale.class), eq(14))).thenReturn("14"); + when(i18n.formatInteger(any(Locale.class), eq(1))).thenReturn("1"); + when(i18n.formatInteger(any(Locale.class), eq(2))).thenReturn("2"); + when(i18n.formatInteger(any(Locale.class), eq(5))).thenReturn("5"); + when(i18n.formatInteger(any(Locale.class), eq(4))).thenReturn("4"); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY); + request.execute().assertJson(getClass(), "app_with_issues_measures.json"); + } + + @Test + public void app_with_issues_measures_when_period_is_set() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); + addComponent(); + addPeriod(); + + Multiset severities = LinkedHashMultiset.create(); + severities.add("BLOCKER", 1); + severities.add("CRITICAL", 2); + severities.add("MAJOR", 5); + severities.add("MINOR", 4); + severities.add("INFO", 2); + when(issueService.findSeveritiesByComponent(eq(COMPONENT_KEY), any(Date.class), eq(session))).thenReturn(severities); + + when(i18n.message(any(Locale.class), eq("severity.BLOCKER"), isNull(String.class))).thenReturn("Blocker"); + when(i18n.message(any(Locale.class), eq("severity.CRITICAL"), isNull(String.class))).thenReturn("Critical"); + when(i18n.message(any(Locale.class), eq("severity.MAJOR"), isNull(String.class))).thenReturn("Major"); + when(i18n.message(any(Locale.class), eq("severity.MINOR"), isNull(String.class))).thenReturn("Minor"); + when(i18n.message(any(Locale.class), eq("severity.INFO"), isNull(String.class))).thenReturn("Info"); + + when(i18n.formatInteger(any(Locale.class), eq(14))).thenReturn("14"); + when(i18n.formatInteger(any(Locale.class), eq(1))).thenReturn("1"); + when(i18n.formatInteger(any(Locale.class), eq(2))).thenReturn("2"); + when(i18n.formatInteger(any(Locale.class), eq(5))).thenReturn("5"); + when(i18n.formatInteger(any(Locale.class), eq(4))).thenReturn("4"); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY).setParam("period", "1"); + request.execute().assertJson(getClass(), "app_with_issues_measures_when_period_is_set.json"); } @Test @@ -250,19 +322,34 @@ public class ComponentAppActionTest { Multiset severities = HashMultiset.create(); severities.add("MAJOR", 5); - when(issueService.findSeveritiesByComponent(COMPONENT_KEY, session)).thenReturn(severities); + when(issueService.findSeveritiesByComponent(COMPONENT_KEY, null, session)).thenReturn(severities); when(i18n.message(any(Locale.class), eq("severity.MAJOR"), isNull(String.class))).thenReturn("Major"); WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY); request.execute().assertJson(getClass(), "app_with_severities.json"); } + @Test + public void app_with_severities_when_period_is_set() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); + addComponent(); + addPeriod(); + + Multiset severities = HashMultiset.create(); + severities.add("MAJOR", 5); + when(issueService.findSeveritiesByComponent(eq(COMPONENT_KEY), any(Date.class), eq(session))).thenReturn(severities); + when(i18n.message(any(Locale.class), eq("severity.MAJOR"), isNull(String.class))).thenReturn("Major"); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY).setParam("period", "1"); + request.execute().assertJson(getClass(), "app_with_severities_when_period_is_set.json"); + } + @Test public void app_with_rules() throws Exception { MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); addComponent(); - when(issueService.findRulesByComponent(COMPONENT_KEY, session)).thenReturn( + when(issueService.findRulesByComponent(COMPONENT_KEY, null, session)).thenReturn( new RulesAggregation().add(new RuleDto().setRuleKey("AvoidCycle").setRepositoryKey("squid").setName("Avoid Cycle")) ); @@ -270,6 +357,26 @@ public class ComponentAppActionTest { request.execute().assertJson(getClass(), "app_with_rules.json"); } + @Test + public void app_with_rules_when_period_is_set() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); + + addComponent(); + + Date periodDate = DateUtils.parseDate("2014-05-08"); + when(resourceDao.getLastSnapshotByResourceId(eq(1L), eq(session))).thenReturn( + new SnapshotDto().setPeriod1Mode("previous_analysis").setPeriod1Date(periodDate) + ); + when(periods.label(anyString(), anyString(), any(Date.class))).thenReturn("since previous analysis (May 08 2014)"); + + when(issueService.findRulesByComponent(COMPONENT_KEY, periodDate, session)).thenReturn( + new RulesAggregation().add(new RuleDto().setRuleKey("AvoidCycle").setRepositoryKey("squid").setName("Avoid Cycle")) + ); + + WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY).setParam("period", "1"); + request.execute().assertJson(getClass(), "app_with_rules_when_period_is_set.json"); + } + @Test public void app_with_extension() throws Exception { MockUserSession.set().addComponentPermission(UserRole.USER, PROJECT_KEY, COMPONENT_KEY); @@ -303,6 +410,14 @@ public class ComponentAppActionTest { when(componentDao.getById(1L, session)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube")); } + private void addPeriod(){ + Date periodDate = DateUtils.parseDate("2014-05-08"); + when(resourceDao.getLastSnapshotByResourceId(eq(1L), eq(session))).thenReturn( + new SnapshotDto().setPeriod1Mode("previous_analysis").setPeriod1Date(periodDate) + ); + when(periods.label(anyString(), anyString(), any(Date.class))).thenReturn("since previous analysis (May 08 2014)"); + } + private void addMeasure(String metricKey, Integer value) { measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, metricKey)).setValue(value.doubleValue())); when(i18n.formatInteger(any(Locale.class), eq(value.intValue()))).thenReturn(Integer.toString(value)); @@ -313,6 +428,16 @@ public class ComponentAppActionTest { when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value)); } + private void addVariationMeasure(String metricKey, Integer value, Integer periodIndex) { + measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, metricKey)).setVariation(periodIndex, value.doubleValue())); + when(i18n.formatInteger(any(Locale.class), eq(value))).thenReturn(Integer.toString(value)); + } + + private void addVariationMeasure(String metricKey, Double value, Integer periodIndex) { + measures.add(MeasureDto.createFor(MeasureKey.of(COMPONENT_KEY, metricKey)).setVariation(periodIndex, value)); + when(i18n.formatDouble(any(Locale.class), eq(value))).thenReturn(Double.toString(value)); + } + @NavigationSection(NavigationSection.RESOURCE_TAB) private static class MyExtension implements Page { public String getId() { diff --git a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java index b61e0a2de9f..df93361f402 100644 --- a/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java @@ -74,7 +74,7 @@ public class ComponentsWsTest { assertThat(action.isPost()).isFalse(); assertThat(action.handler()).isNotNull(); assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(1); + assertThat(action.params()).hasSize(2); } } diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java index 27aebc4452c..4f555e56a9b 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceTest.java @@ -58,6 +58,7 @@ import org.sonar.server.issue.actionplan.ActionPlanService; import org.sonar.server.user.UserSession; import java.util.Collections; +import java.util.Date; import java.util.List; import static com.google.common.collect.Lists.newArrayList; @@ -507,12 +508,13 @@ public class IssueServiceTest { DbSession session = mock(DbSession.class); String componentKey = "org.sonar.Sample"; - when(issueDao.findRulesByComponent(componentKey, session)).thenReturn(newArrayList( + Date date = new Date(); + when(issueDao.findRulesByComponent(componentKey, date, session)).thenReturn(newArrayList( RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name"), RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name") )); - RulesAggregation result = issueService.findRulesByComponent(componentKey, session); + RulesAggregation result = issueService.findRulesByComponent(componentKey, date, session); assertThat(result.rules()).hasSize(1); } @@ -521,9 +523,10 @@ public class IssueServiceTest { DbSession session = mock(DbSession.class); String componentKey = "org.sonar.Sample"; - when(issueDao.findSeveritiesByComponent(componentKey, session)).thenReturn(newArrayList("MAJOR", "MAJOR", "INFO")); + Date date = new Date(); + when(issueDao.findSeveritiesByComponent(componentKey, date, session)).thenReturn(newArrayList("MAJOR", "MAJOR", "INFO")); - Multiset result = issueService.findSeveritiesByComponent(componentKey, session); + Multiset result = issueService.findSeveritiesByComponent(componentKey, date, session); assertThat(result.count("MAJOR")).isEqualTo(2); assertThat(result.count("INFO")).isEqualTo(1); assertThat(result.count("UNKNOWN")).isEqualTo(0); diff --git a/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java b/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java index 63e5f745ef6..be4b2e00ed8 100644 --- a/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java +++ b/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java @@ -92,6 +92,11 @@ public class MeasureDaoTest extends AbstractDaoTestCase { assertThat(result.getId()).isEqualTo(22); assertThat(result.getValue()).isEqualTo(10d); assertThat(result.getKey()).isNotNull(); + assertThat(result.getVariation(1)).isEqualTo(1d); + assertThat(result.getVariation(2)).isEqualTo(2d); + assertThat(result.getVariation(3)).isEqualTo(3d); + assertThat(result.getVariation(4)).isEqualTo(4d); + assertThat(result.getVariation(5)).isEqualTo(-5d); } @Test diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures.json new file mode 100644 index 00000000000..da382ae72e3 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures.json @@ -0,0 +1,29 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "q": "FIL", + "subProjectName": "SonarQube :: Plugin API", + "projectName": "SonarQube", + "fav": false, + "scmAvailable": false, + "canMarkAsFavourite": false, + "canBulkChange": false, + "periods": [], + "severities": [ + ["BLOCKER", "Blocker", 1], + ["CRITICAL", "Critical", 2], + ["MAJOR", "Major", 5], + ["MINOR", "Minor", 4], + ["INFO", "Info", 2] + ], + "rules": [], + "measures": { + "fIssues": "14", + "fBlockerIssues": "1", + "fCriticalIssues": "2", + "fMajorIssues": "5", + "fMinorIssues": "4", + "fInfoIssues": "2" + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures_when_period_is_set.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures_when_period_is_set.json new file mode 100644 index 00000000000..c76c0297698 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_issues_measures_when_period_is_set.json @@ -0,0 +1,31 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "q": "FIL", + "subProjectName": "SonarQube :: Plugin API", + "projectName": "SonarQube", + "fav": false, + "scmAvailable": false, + "canMarkAsFavourite": false, + "canBulkChange": false, + "periods": [ + [1, "since previous analysis (May 08 2014)", "2014-05-08T00:00:00+0200"] + ], + "severities": [ + ["BLOCKER", "Blocker", 1], + ["CRITICAL", "Critical", 2], + ["MAJOR", "Major", 5], + ["MINOR", "Minor", 4], + ["INFO", "Info", 2] + ], + "rules": [], + "measures": { + "fIssues": "14", + "fBlockerIssues": "1", + "fCriticalIssues": "2", + "fMajorIssues": "5", + "fMinorIssues": "4", + "fInfoIssues": "2" + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json index 0a888c70c9d..af6333f7ca6 100644 --- a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures.json @@ -16,12 +16,6 @@ "fNcloc": "200", "fCoverage": "95.4%", "fDuplicationDensity": "7.4%", - "fDebt": "3h 2min", - "fIssues": "14", - "fBlockerIssues": "1", - "fCriticalIssues": "2", - "fMajorIssues": "5", - "fMinorIssues": "4", - "fInfoIssues": "2" + "fDebt": "3h 2min" } } diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures_when_period_is_set.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures_when_period_is_set.json new file mode 100644 index 00000000000..ad91e5e003a --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_measures_when_period_is_set.json @@ -0,0 +1,23 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "q": "FIL", + "subProjectName": "SonarQube :: Plugin API", + "projectName": "SonarQube", + "fav": false, + "scmAvailable": false, + "canMarkAsFavourite": false, + "canBulkChange": false, + "periods": [ + [1, "since previous analysis (May 08 2014)", "2014-05-08T00:00:00+0200"] + ], + "severities": [], + "rules": [], + "measures": { + "fNcloc": "2", + "fCoverage": "5.0", + "fDuplicationDensity": "1.2", + "fDebt": "10min" + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_rules_when_period_is_set.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_rules_when_period_is_set.json new file mode 100644 index 00000000000..6bd62351925 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_rules_when_period_is_set.json @@ -0,0 +1,20 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "q": "FIL", + "subProjectName": "SonarQube :: Plugin API", + "projectName": "SonarQube", + "fav": false, + "scmAvailable": false, + "canMarkAsFavourite": false, + "canBulkChange": false, + "periods": [ + [1, "since previous analysis (May 08 2014)", "2014-05-08T00:00:00+0200"] + ], + "severities": [], + "rules": [ + ["squid:AvoidCycle", "Avoid Cycle", 1] + ], + "measures": {} +} diff --git a/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_severities_when_period_is_set.json b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_severities_when_period_is_set.json new file mode 100644 index 00000000000..76c5339abfd --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/component/ws/ComponentAppActionTest/app_with_severities_when_period_is_set.json @@ -0,0 +1,20 @@ +{ + "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java", + "path": "src/main/java/org/sonar/api/Plugin.java", + "name": "Plugin.java", + "q": "FIL", + "subProjectName": "SonarQube :: Plugin API", + "projectName": "SonarQube", + "fav": false, + "scmAvailable": false, + "canMarkAsFavourite": false, + "canBulkChange": false, + "periods": [ + [1, "since previous analysis (May 08 2014)", "2014-05-08T00:00:00+0200"] + ], + "severities": [ + ["MAJOR", "Major", 5] + ], + "rules": [], + "measures": {} +} diff --git a/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml b/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml index 70097c0470f..041ca607f35 100644 --- a/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml +++ b/sonar-server/src/test/resources/org/sonar/server/measure/persistence/MeasureDaoTest/shared.xml @@ -8,8 +8,11 @@ - - - + + + -- 2.39.5