* @param newRoot a {@link Component}, can not be {@code null}
*
* @throws NullPointerException if {@code newRoot} is {@code null}
+ * @throws IllegalStateException if root {@link Component} has already been set
*/
MutableTreeRootHolder setRoot(Component newRoot);
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.component;
-
-public interface ReportTreeRootHolder extends TreeRootHolder {
-
- /**
- * Return a component by its batch reference
- *
- * @throws IllegalStateException if the holder is empty (ie. there is no root yet)
- * @throws IllegalArgumentException if there's no component for the reference
- */
- Component getComponentByRef(int ref);
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.component;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
-
-public class ReportTreeRootHolderImpl extends TreeRootHolderImpl implements ReportTreeRootHolder {
- private Map<Integer, Component> componentsByRef = new HashMap<>();
-
- @Override
- public MutableTreeRootHolder setRoot(Component newRoot) {
- super.setRoot(newRoot);
- feedComponentsByRef(newRoot);
- return this;
- }
-
- private void feedComponentsByRef(Component newRoot) {
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
- @Override
- public void visitAny(Component component) {
- componentsByRef.put(component.getReportAttributes().getRef(), component);
- }
- }).visit(newRoot);
- }
-
- @Override
- public Component getComponentByRef(int ref) {
- // makes sure the root is set, hence componentsByRef is populated
- getRoot();
- Component component = componentsByRef.get(ref);
- checkArgument(component != null, String.format("Component '%s' hasn't been found", ref));
- return component;
- }
-}
* @throws IllegalStateException if the holder is empty (ie. there is no root yet)
*/
Component getRoot();
+
+ /**
+ * Return a component by its batch reference
+ *
+ * @throws IllegalStateException if the holder is empty (ie. there is no root yet)
+ * @throws IllegalArgumentException if there's no {@link Component} with the specified reference
+ */
+ Component getComponentByRef(int ref);
+
+ /**
+ * Retrieves the component with the specified key in the {@link Component} tree in the holder.
+ *
+ * @throws NullPointerException if {@code key} is {@code null}
+ * @throws IllegalStateException if the holder is empty (ie. there is not root yet)
+ * @throws IllegalArgumentException if there is no {@link Component} with the specified key in the tree
+ */
+ Component getComponentByKey(String key);
+
+ /**
+ * Checks whether the {@link Component} with the specified key exists in the tree.
+ *
+ * @throws NullPointerException if {@code key} is {@code null}
+ * @throws IllegalStateException if the holder is empty (ie. there is not root yet)
+ */
+ boolean hasComponentWithKey(String key);
}
*/
package org.sonar.server.computation.component;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
+import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
/**
* Holds the reference to the root of the {@link Component} tree for the current CE run.
*/
public class TreeRootHolderImpl implements MutableTreeRootHolder {
+ @CheckForNull
+ private Map<Integer, Component> componentsByRef;
+ @CheckForNull
+ private Map<String, Component> componentsByKey;
private Component root;
@Override
- public MutableTreeRootHolder setRoot(Component newRoot) {
- this.root = requireNonNull(newRoot);
+ public MutableTreeRootHolder setRoot(Component root) {
+ checkState(this.root == null, "root can not be set twice in holder");
+ this.root = requireNonNull(root, "root can not be null");
return this;
}
@Override
public Component getRoot() {
- checkState(this.root != null, "Root has not been created yet");
+ checkInitialized();
return this.root;
}
+ @Override
+ public Component getComponentByRef(int ref) {
+ checkInitialized();
+ ensureComponentByRefIsPopulated();
+ Component component = componentsByRef.get(ref);
+ checkArgument(component != null, "Component with ref '%s' can't be found", ref);
+ return component;
+ }
+
+ private void ensureComponentByRefIsPopulated() {
+ if (componentsByRef != null) {
+ return;
+ }
+
+ final ImmutableMap.Builder<Integer, Component> builder = ImmutableMap.builder();
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ builder.put(component.getReportAttributes().getRef(), component);
+ }
+ }).visit(this.root);
+ this.componentsByRef = builder.build();
+ }
+
+ @Override
+ public Component getComponentByKey(String key) {
+ checkKeyArgument(key);
+ checkInitialized();
+ ensureComponentByKeyIsPopulated();
+ Component component = componentsByKey.get(key);
+ checkArgument(component != null, "Component with key '%s' can't be found", key);
+ return component;
+ }
+
+ @Override
+ public boolean hasComponentWithKey(String key) {
+ checkKeyArgument(key);
+ checkInitialized();
+ ensureComponentByKeyIsPopulated();
+
+ return componentsByKey.containsKey(key);
+ }
+
+ private void checkInitialized() {
+ checkState(this.root != null, "Holder has not been initialized yet");
+ }
+
+ private static void checkKeyArgument(String key) {
+ requireNonNull(key, "key can not be null");
+ }
+
+ private void ensureComponentByKeyIsPopulated() {
+ if (componentsByKey != null) {
+ return;
+ }
+
+ final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(CrawlerDepthLimit.LEAVES, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ builder.put(component.getKey(), component);
+ }
+ }).visit(this.root);
+ this.componentsByKey = builder.build();
+ }
}
import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl;
import org.sonar.server.computation.batch.BatchReportReaderImpl;
import org.sonar.server.computation.component.DbIdsRepositoryImpl;
-import org.sonar.server.computation.component.ReportTreeRootHolderImpl;
import org.sonar.server.computation.component.SettingsRepositoryImpl;
+import org.sonar.server.computation.component.TreeRootHolderImpl;
import org.sonar.server.computation.debt.DebtModelHolderImpl;
import org.sonar.server.computation.duplication.DuplicationRepositoryImpl;
import org.sonar.server.computation.event.EventRepositoryImpl;
// holders
AnalysisMetadataHolderImpl.class,
BatchReportDirectoryHolderImpl.class,
- ReportTreeRootHolderImpl.class,
+ TreeRootHolderImpl.class,
PeriodsHolderImpl.class,
QualityGateHolderImpl.class,
DebtModelHolderImpl.class,
*/
package org.sonar.server.computation.issue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.protobuf.DbIssues;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.issue.commonrule.CommonRuleEngine;
import org.sonar.server.computation.source.SourceLinesRepository;
import org.sonar.server.rule.CommonRuleKeys;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
import static com.google.common.collect.Lists.newArrayList;
public class TrackerRawInputFactory {
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;
private final SourceLinesRepository sourceLinesRepository;
private final CommonRuleEngine commonRuleEngine;
- public TrackerRawInputFactory(ReportTreeRootHolder treeRootHolder, BatchReportReader reportReader,
+ public TrackerRawInputFactory(TreeRootHolder treeRootHolder, BatchReportReader reportReader,
SourceLinesRepository sourceLinesRepository, CommonRuleEngine commonRuleEngine) {
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.duplication.DuplicationRepository;
import org.sonar.server.computation.duplication.TextBlock;
* Loads duplication information from the report and loads them into the {@link DuplicationRepository}.
*/
public class LoadDuplicationsFromReportStep implements ComputationStep {
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final BatchReportReader batchReportReader;
private final DuplicationRepository duplicationRepository;
- public LoadDuplicationsFromReportStep(ReportTreeRootHolder treeRootHolder, BatchReportReader batchReportReader, DuplicationRepository duplicationRepository) {
+ public LoadDuplicationsFromReportStep(TreeRootHolder treeRootHolder, BatchReportReader batchReportReader, DuplicationRepository duplicationRepository) {
this.treeRootHolder = treeRootHolder;
this.batchReportReader = batchReportReader;
this.duplicationRepository = duplicationRepository;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.duplication.CrossProjectDuplicate;
import org.sonar.server.computation.duplication.Duplicate;
private final DbClient dbClient;
private final DbIdsRepository dbIdsRepository;
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final DuplicationRepository duplicationRepository;
- public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, ReportTreeRootHolder treeRootHolder,
- DuplicationRepository duplicationRepository) {
+ public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
+ DuplicationRepository duplicationRepository) {
this.dbClient = dbClient;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
try {
MetricDto duplicationMetric = dbClient.metricDao().selectOrFailByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
new DepthTraversalTypeAwareCrawler(new DuplicationVisitor(session, duplicationMetric))
- .visit(treeRootHolder.getRoot());
+ .visit(treeRootHolder.getRoot());
session.commit();
} finally {
MyBatis.closeQuietly(session);
private void saveDuplications(Component component, Iterable<Duplication> duplications) {
String duplicationXml = createXmlDuplications(component.getKey(), duplications);
MeasureDto measureDto = new MeasureDto()
- .setMetricId(duplicationMetric.getId())
- .setData(duplicationXml)
- .setComponentId(dbIdsRepository.getComponentId(component))
- .setSnapshotId(dbIdsRepository.getSnapshotId(component));
+ .setMetricId(duplicationMetric.getId())
+ .setData(duplicationXml)
+ .setComponentId(dbIdsRepository.getComponentId(component))
+ .setSnapshotId(dbIdsRepository.getSnapshotId(component));
dbClient.measureDao().insert(session, measureDto);
}
private void appendDuplication(StringBuilder xml, String componentKey, TextBlock textBlock) {
int length = textBlock.getEnd() - textBlock.getStart() + 1;
xml.append("<b s=\"").append(textBlock.getStart())
- .append("\" l=\"").append(length)
- .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
- .append("\"/>");
+ .append("\" l=\"").append(length)
+ .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
+ .append("\"/>");
}
}
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.utils.System2;
-import org.sonar.core.util.Uuids;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
import org.sonar.server.computation.component.ComponentVisitor;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
public class PersistTestsStep implements ComputationStep {
private final DbClient dbClient;
private final System2 system;
private final BatchReportReader reportReader;
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
- public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, ReportTreeRootHolder treeRootHolder) {
+ public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.system = system;
this.reportReader = reportReader;
*/
package org.sonar.server.computation.batch;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
+import org.junit.rules.ExternalResource;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.CrawlerDepthLimit;
-import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.MutableTreeRootHolder;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
+import org.sonar.server.computation.component.TreeRootHolderImpl;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
-
-public class TreeRootHolderRule implements TestRule, MutableTreeRootHolder, ReportTreeRootHolder {
- private Component root;
- private Map<Integer, Component> componentsByRef = new HashMap<>();
+public class TreeRootHolderRule extends ExternalResource implements TreeRootHolder {
+ protected TreeRootHolderImpl delegate = new TreeRootHolderImpl();
@Override
- public Statement apply(final Statement statement, Description description) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- try {
- statement.evaluate();
- } finally {
- clear();
- }
- }
- };
+ protected void after() {
+ this.delegate = null;
}
- private void clear() {
- this.root = null;
- this.componentsByRef.clear();
+ public TreeRootHolderRule setRoot(Component newRoot) {
+ delegate = new TreeRootHolderImpl();
+ delegate.setRoot(newRoot);
+ return this;
}
@Override
public Component getRoot() {
- checkInitialized();
-
- return root;
+ return delegate.getRoot();
}
@Override
public Component getComponentByRef(int ref) {
- checkInitialized();
-
- Component component = componentsByRef.get(ref);
- checkArgument(component != null, "Component with ref '%s' hasn't been found", ref);
- return component;
+ return delegate.getComponentByRef(ref);
}
- private void checkInitialized() {
- checkState(root != null, "Root has not been set in %s", TreeRootHolder.class.getSimpleName());
+ @Override
+ public Component getComponentByKey(String key) {
+ return delegate.getComponentByKey(key);
}
- public TreeRootHolderRule setRoot(Component newRoot) {
- this.root = requireNonNull(newRoot);
- if (newRoot.getType().isReportType()) {
- new DepthTraversalTypeAwareCrawler(new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
- @Override
- public void visitAny(Component component) {
- componentsByRef.put(component.getReportAttributes().getRef(), component);
- }
- }).visit(root);
- }
- return this;
+ @Override
+ public boolean hasComponentWithKey(String key) {
+ return delegate.hasComponentWithKey(key);
}
}
public class MutableTreeRootHolderRule extends TreeRootHolderRule implements MutableTreeRootHolder {
@Override
public MutableTreeRootHolderRule setRoot(Component newRoot) {
- return (MutableTreeRootHolderRule)super.setRoot(newRoot);
+ delegate.setRoot(newRoot);
+ return this;
}
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.component;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ReportTreeRootHolderImplTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- ReportTreeRootHolderImpl treeRootHolder = new ReportTreeRootHolderImpl();
- Component project = ReportComponent.DUMB_PROJECT;
-
- @Test
- public void setRoot_throws_NPE_if_arg_is_null() {
- thrown.expect(NullPointerException.class);
- treeRootHolder.setRoot(null);
- }
-
- @Test
- public void getRoot_throws_ISE_if_root_has_not_been_set_yet() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getRoot();
- }
-
- @Test
- public void verify_setRoot_getRoot() {
- treeRootHolder.setRoot(project);
- assertThat(treeRootHolder.getRoot()).isSameAs(project);
- }
-
- @Test
- public void get_by_ref() {
- Component file = ReportComponent.builder(Component.Type.FILE, 4).build();
- Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 3).addChildren(file).build();
- Component module = ReportComponent.builder(Component.Type.MODULE, 2).addChildren(directory).build();
- Component project = ReportComponent.builder(Component.Type.PROJECT, 1).addChildren(module).build();
- treeRootHolder.setRoot(project);
-
- assertThat(treeRootHolder.getComponentByRef(1)).isEqualTo(project);
- assertThat(treeRootHolder.getComponentByRef(2)).isEqualTo(module);
- assertThat(treeRootHolder.getComponentByRef(3)).isEqualTo(directory);
- assertThat(treeRootHolder.getComponentByRef(4)).isEqualTo(file);
- }
-
- @Test
- public void fail_to_get_by_ref_if_root_not_set() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getComponentByRef(project.getReportAttributes().getRef());
- }
-
- @Test
- public void fail_to_get_by_ref_if_ref_not_found() {
- thrown.expect(IllegalArgumentException.class);
- treeRootHolder.setRoot(project);
- treeRootHolder.getComponentByRef(123);
- }
-}
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
+import static org.sonar.server.computation.component.Component.Type.FILE;
+import static org.sonar.server.computation.component.Component.Type.MODULE;
+import static org.sonar.server.computation.component.Component.Type.PROJECT;
+import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW;
+import static org.sonar.server.computation.component.Component.Type.VIEW;
+import static org.sonar.server.computation.component.ReportComponent.DUMB_PROJECT;
public class TreeRootHolderImplTest {
+ private static final ReportComponent SOME_REPORT_COMPONENT_TREE = ReportComponent.builder(PROJECT, 1)
+ .addChildren(
+ ReportComponent.builder(MODULE, 2)
+ .addChildren(ReportComponent.builder(DIRECTORY, 3)
+ .addChildren(
+ ReportComponent.builder(FILE, 4).build()
+ )
+ .build())
+ .build()
+ )
+ .build();
+ private static final ViewsComponent SOME_VIEWS_COMPONENT_TREE = ViewsComponent.builder(VIEW, 1)
+ .addChildren(
+ ViewsComponent.builder(VIEW, 2)
+ .addChildren(ViewsComponent.builder(PROJECT_VIEW, 3).build())
+ .build()
+ )
+ .build();
+
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
- TreeRootHolderImpl treeRootHolder = new TreeRootHolderImpl();
- Component project = ReportComponent.DUMB_PROJECT;
+ private TreeRootHolderImpl underTest = new TreeRootHolderImpl();
@Test
public void setRoot_throws_NPE_if_arg_is_null() {
- thrown.expect(NullPointerException.class);
- treeRootHolder.setRoot(null);
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("root can not be null");
+
+ underTest.setRoot(null);
+ }
+
+ @Test
+ public void setRoot_throws_ISE_when_called_twice() {
+ underTest.setRoot(DUMB_PROJECT);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("root can not be set twice in holder");
+
+ underTest.setRoot(DUMB_PROJECT);
}
@Test
public void getRoot_throws_ISE_if_root_has_not_been_set_yet() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getRoot();
+ expectNotInitialized_ISE();
+
+ underTest.getRoot();
+ }
+
+ @Test
+ public void getComponentByRef_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.getComponentByRef(12);
+ }
+
+ @Test
+ public void getComponentByRef_returns_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ assertThat(underTest.getComponentByRef(i).getReportAttributes().getRef()).isEqualTo(i);
+ }
+ }
+
+ @Test
+ public void getComponentByRef_throws_IAE_if_holder_does_not_contain_specified_component() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Component with ref '6' can't be found");
+
+ underTest.getComponentByRef(6);
+ }
+
+ @Test
+ public void getComponentByRef_throws_IAE_if_holder_contains_View_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Component with ref '1' can't be found");
+
+ underTest.getComponentByRef(1);
+ }
+
+ @Test
+ public void getComponentByKey_throws_NPE_if_key_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key can not be null");
+
+ underTest.getComponentByKey(null);
+ }
+
+ @Test
+ public void getComponentByKey_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.getComponentByKey("key");
+ }
+
+ @Test
+ public void getComponentByKey_returns_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ String key = "key_" + i;
+ assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
+ }
+ }
+
+ @Test
+ public void getComponentByKey_returns_any_views_component_in_the_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ for (int i = 1; i <= 3; i++) {
+ String key = String.valueOf(i);
+ assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
+ }
}
@Test
public void verify_setRoot_getRoot() {
- treeRootHolder.setRoot(project);
- assertThat(treeRootHolder.getRoot()).isSameAs(project);
+ underTest.setRoot(DUMB_PROJECT);
+ assertThat(underTest.getRoot()).isSameAs(DUMB_PROJECT);
+ }
+
+ @Test
+ public void hasComponentWithKey_throws_NPE_if_key_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key can not be null");
+
+ underTest.hasComponentWithKey(null);
+ }
+
+ @Test
+ public void hasComponentWithKey_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.hasComponentWithKey("key");
+ }
+
+ @Test
+ public void hasComponentWithKey_returns_true_for_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ String key = "key_" + i;
+ assertThat(underTest.hasComponentWithKey(key)).isTrue();
+ }
+ assertThat(underTest.hasComponentWithKey("toto")).isFalse();
+ }
+
+ @Test
+ public void hasComponentWithKey_returns_true_for_any_views_component_in_the_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ for (int i = 1; i <= 3; i++) {
+ String key = String.valueOf(i);
+ assertThat(underTest.hasComponentWithKey(key)).isTrue();
+ }
+ assertThat(underTest.hasComponentWithKey("toto")).isFalse();
+ }
+
+ private void expectNotInitialized_ISE() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Holder has not been initialized yet");
}
}
import org.junit.rules.ExternalResource;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public class ComponentIssuesRepositoryRule extends ExternalResource implements MutableComponentIssuesRepository, ComponentIssuesRepository {
- private final ReportTreeRootHolder reportTreeRootHolder;
+ private final TreeRootHolder treeRootHolder;
@CheckForNull
private List<DefaultIssue> issues;
@CheckForNull
private Component component;
- public ComponentIssuesRepositoryRule(ReportTreeRootHolder reportTreeRootHolder) {
- this.reportTreeRootHolder = reportTreeRootHolder;
+ public ComponentIssuesRepositoryRule(TreeRootHolder treeRootHolder) {
+ this.treeRootHolder = treeRootHolder;
}
@Override
public void setIssues(int componentRef, List<DefaultIssue> issues) {
this.issues = requireNonNull(issues, "issues cannot be null");
- Component component = reportTreeRootHolder.getComponentByRef(componentRef);
+ Component component = treeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
this.component = component;
}
public List<DefaultIssue> getIssues(int componentRef) {
checkState(this.component != null && this.issues != null, "Issues have not been initialized");
- Component component = reportTreeRootHolder.getComponentByRef(componentRef);
+ Component component = treeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
checkArgument(component == this.component,
String.format("Only issues from component '%s' are available, but wanted component is '%s'.",
reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(666, line + 1)));
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Component with ref '666' hasn't been found");
+ expectedException.expectMessage("Component with ref '666' can't be found");
underTest.execute();
}