3 * Copyright (C) 2009-2023 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.ce.task.projectanalysis.measure;
22 import java.util.Arrays;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.sonar.api.ce.measure.MeasureComputer;
26 import org.sonar.api.ce.measure.test.TestMeasureComputerDefinitionContext;
27 import org.sonar.ce.task.projectanalysis.api.measurecomputer.MeasureComputerDefinitionImpl;
28 import org.sonar.ce.task.projectanalysis.component.Component;
29 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
30 import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler;
31 import org.sonar.ce.task.projectanalysis.issue.ComponentIssuesRepository;
32 import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
34 import static org.assertj.core.api.Assertions.assertThat;
35 import static org.mockito.Mockito.mock;
36 import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES;
37 import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_KEY;
38 import static org.sonar.api.measures.CoreMetrics.NCLOC;
39 import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
40 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT_VIEW;
41 import static org.sonar.ce.task.projectanalysis.component.Component.Type.SUBVIEW;
42 import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
43 import static org.sonar.ce.task.projectanalysis.component.ViewsComponent.builder;
44 import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
45 import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
46 import static org.sonar.ce.task.projectanalysis.measure.MeasureRepoEntry.toEntries;
48 public class ViewsMeasureComputersVisitorTest {
50 private static final String NEW_METRIC_KEY = "new_metric_key";
51 private static final String NEW_METRIC_NAME = "new metric name";
53 private static final org.sonar.api.measures.Metric<Integer> NEW_METRIC = new org.sonar.api.measures.Metric.Builder(NEW_METRIC_KEY, NEW_METRIC_NAME,
54 org.sonar.api.measures.Metric.ValueType.INT)
57 private static final int ROOT_REF = 1;
58 private static final int VIEW_REF = 12;
59 private static final int SUB_SUBVIEW_REF = 123;
60 private static final int PROJECT_VIEW_1_REF = 1231;
61 private static final int PROJECT_VIEW_2_REF = 1232;
63 private static final Component TREE_WITH_SUB_VIEWS = builder(VIEW, ROOT_REF)
65 builder(SUBVIEW, VIEW_REF)
67 builder(SUBVIEW, SUB_SUBVIEW_REF)
69 builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build(),
70 builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build())
75 private static final Component TREE_WITH_DIRECT_PROJECT_VIEW = builder(VIEW, ROOT_REF)
77 builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build(),
78 builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build())
81 private static final MeasureComputer MEASURE_COMPUTER = new MeasureComputer() {
83 public MeasureComputer.MeasureComputerDefinition define(MeasureComputer.MeasureComputerDefinitionContext defContext) {
84 return new MeasureComputerDefinitionImpl.BuilderImpl()
85 .setInputMetrics(NCLOC_KEY, COMMENT_LINES_KEY)
86 .setOutputMetrics(NEW_METRIC_KEY)
91 public void compute(MeasureComputer.MeasureComputerContext context) {
92 org.sonar.api.ce.measure.Measure ncloc = context.getMeasure(NCLOC_KEY);
93 org.sonar.api.ce.measure.Measure comment = context.getMeasure(COMMENT_LINES_KEY);
94 if (ncloc != null && comment != null) {
95 context.addMeasure(NEW_METRIC_KEY, ncloc.getIntValue() + comment.getIntValue());
101 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
104 public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
110 public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(TREE_WITH_SUB_VIEWS, metricRepository);
113 public MeasureComputersHolderRule measureComputersHolder = new MeasureComputersHolderRule(new TestMeasureComputerDefinitionContext());
115 ComponentIssuesRepository componentIssuesRepository = mock(ComponentIssuesRepository.class);
118 public void compute_plugin_measure() {
119 treeRootHolder.setRoot(TREE_WITH_SUB_VIEWS);
121 addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);
122 addRawMeasure(PROJECT_VIEW_1_REF, COMMENT_LINES_KEY, 2);
123 addRawMeasure(PROJECT_VIEW_2_REF, NCLOC_KEY, 40);
124 addRawMeasure(PROJECT_VIEW_2_REF, COMMENT_LINES_KEY, 5);
125 addRawMeasure(SUB_SUBVIEW_REF, NCLOC_KEY, 50);
126 addRawMeasure(SUB_SUBVIEW_REF, COMMENT_LINES_KEY, 7);
127 addRawMeasure(VIEW_REF, NCLOC_KEY, 50);
128 addRawMeasure(VIEW_REF, COMMENT_LINES_KEY, 7);
129 addRawMeasure(ROOT_REF, NCLOC_KEY, 50);
130 addRawMeasure(ROOT_REF, COMMENT_LINES_KEY, 7);
132 measureComputersHolder.addMeasureComputer(MEASURE_COMPUTER);
134 VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.asList(new MeasureComputersVisitor(metricRepository, measureRepository, null,
135 measureComputersHolder, componentIssuesRepository)));
136 visitorsCrawler.visit(treeRootHolder.getRoot());
138 assertNoAddedRawMeasureOnProjectViews();
139 assertAddedRawMeasure(57, SUB_SUBVIEW_REF, NEW_METRIC_KEY);
140 assertAddedRawMeasure(57, VIEW_REF, NEW_METRIC_KEY);
141 assertAddedRawMeasure(57, ROOT_REF, NEW_METRIC_KEY);
145 public void compute_plugin_measure_on_views_tree_having_only_one_view_with_a_project_view() {
146 treeRootHolder.setRoot(TREE_WITH_DIRECT_PROJECT_VIEW);
148 addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);
149 addRawMeasure(PROJECT_VIEW_1_REF, COMMENT_LINES_KEY, 2);
150 addRawMeasure(PROJECT_VIEW_2_REF, NCLOC_KEY, 40);
151 addRawMeasure(PROJECT_VIEW_2_REF, COMMENT_LINES_KEY, 5);
152 addRawMeasure(ROOT_REF, NCLOC_KEY, 50);
153 addRawMeasure(ROOT_REF, COMMENT_LINES_KEY, 7);
155 measureComputersHolder.addMeasureComputer(MEASURE_COMPUTER);
157 VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.asList(new MeasureComputersVisitor(metricRepository, measureRepository, null,
158 measureComputersHolder, componentIssuesRepository)));
159 visitorsCrawler.visit(treeRootHolder.getRoot());
161 assertNoAddedRawMeasureOnProjectViews();
162 assertAddedRawMeasure(57, ROOT_REF, NEW_METRIC_KEY);
166 public void nothing_to_compute_when_no_project_view() {
167 treeRootHolder.setRoot(builder(VIEW, ROOT_REF)
169 builder(SUBVIEW, VIEW_REF)
171 builder(SUBVIEW, SUB_SUBVIEW_REF)
176 measureComputersHolder.addMeasureComputer(MEASURE_COMPUTER);
178 VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.asList(new MeasureComputersVisitor(metricRepository, measureRepository, null,
179 measureComputersHolder, componentIssuesRepository)));
180 visitorsCrawler.visit(treeRootHolder.getRoot());
182 assertNoAddedRawMeasureOnProjectViews();
183 assertNoAddedRawMeasure(SUB_SUBVIEW_REF);
184 assertNoAddedRawMeasure(VIEW_REF);
185 assertNoAddedRawMeasure(ROOT_REF);
189 public void nothing_to_compute_when_no_measure_computers() {
190 treeRootHolder.setRoot(TREE_WITH_SUB_VIEWS);
192 addRawMeasure(PROJECT_VIEW_1_REF, NCLOC_KEY, 10);
193 addRawMeasure(PROJECT_VIEW_1_REF, COMMENT_LINES_KEY, 2);
194 addRawMeasure(PROJECT_VIEW_2_REF, NCLOC_KEY, 40);
195 addRawMeasure(PROJECT_VIEW_2_REF, COMMENT_LINES_KEY, 5);
196 addRawMeasure(SUB_SUBVIEW_REF, NCLOC_KEY, 50);
197 addRawMeasure(SUB_SUBVIEW_REF, COMMENT_LINES_KEY, 7);
198 addRawMeasure(VIEW_REF, NCLOC_KEY, 50);
199 addRawMeasure(VIEW_REF, COMMENT_LINES_KEY, 7);
200 addRawMeasure(ROOT_REF, NCLOC_KEY, 50);
201 addRawMeasure(ROOT_REF, COMMENT_LINES_KEY, 7);
203 VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.asList(new MeasureComputersVisitor(metricRepository, measureRepository, null,
204 measureComputersHolder, componentIssuesRepository)));
205 visitorsCrawler.visit(treeRootHolder.getRoot());
207 assertNoAddedRawMeasureOnProjectViews();
208 assertNoAddedRawMeasure(SUB_SUBVIEW_REF);
209 assertNoAddedRawMeasure(VIEW_REF);
210 assertNoAddedRawMeasure(ROOT_REF);
213 private void assertNoAddedRawMeasureOnProjectViews() {
214 assertNoAddedRawMeasure(PROJECT_VIEW_1_REF);
215 assertNoAddedRawMeasure(PROJECT_VIEW_2_REF);
218 private void addRawMeasure(int componentRef, String metricKey, int value) {
219 measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value));
222 private void assertNoAddedRawMeasure(int componentRef) {
223 assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).isEmpty();
226 private void assertAddedRawMeasure(int value, int componentRef, String metricKey) {
227 assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly(entryOf(metricKey, newMeasureBuilder().create(value)));