* @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 component for the reference
+ */
+ Component getComponentByRef(int ref);
}
*/
package org.sonar.server.computation.component;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.POST_ORDER;
+
/**
* Holds the reference to the root of the {@link Component} tree for the current CE run.
*/
public class TreeRootHolderImpl implements MutableTreeRootHolder {
+
private Component root;
+ private Map<Integer, Component> componentsByRef = new HashMap<>();
@Override
public void setRoot(Component newRoot) {
this.root = Objects.requireNonNull(newRoot);
+ feedComponentsByRef();
}
@Override
public Component getRoot() {
+ checkRoot();
+ return this.root;
+ }
+
+ @Override
+ public Component getComponentByRef(int ref) {
+ checkRoot();
+ Component component = componentsByRef.get(ref);
+ if (component == null) {
+ throw new IllegalArgumentException(String.format("Component '%s' hasn't been found", ref));
+ }
+ return component;
+ }
+
+ private void checkRoot() {
if (this.root == null) {
throw new IllegalStateException("Root has not been created yet");
}
- return this.root;
+ }
+
+ private void feedComponentsByRef() {
+ new DepthTraversalTypeAwareVisitor(Component.Type.FILE, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ componentsByRef.put(component.getRef(), component);
+ }
+ }.visit(root);
}
}
*/
package org.sonar.server.computation.batch;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.POST_ORDER;
+
public class TreeRootHolderRule implements TestRule, TreeRootHolder {
private Component root;
+ private Map<Integer, Component> componentsByRef = new HashMap<>();
@Override
public Statement apply(final Statement statement, Description description) {
return root;
}
+ @Override
+ public Component getComponentByRef(int ref) {
+ if (root == null) {
+ throw new IllegalStateException("Root has not been set in " + TreeRootHolder.class.getSimpleName());
+ }
+
+ Component component = componentsByRef.get(ref);
+ if (component == null) {
+ throw new IllegalArgumentException(String.format("Component '%s' hasn't been found", ref));
+ }
+ return component;
+ }
+
public void setRoot(Component newRoot) {
this.root = Objects.requireNonNull(newRoot);
+ new DepthTraversalTypeAwareVisitor(Component.Type.FILE, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ componentsByRef.put(component.getRef(), component);
+ }
+ }.visit(root);
}
}
*/
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;
-import static org.mockito.Mockito.mock;
public class TreeRootHolderImplTest {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
TreeRootHolderImpl treeRootHolder = new TreeRootHolderImpl();
- Component component = mock(Component.class);
+ Component project = DumbComponent.DUMB_PROJECT;
- @Test(expected = NullPointerException.class)
+ @Test
public void setRoot_throws_NPE_if_arg_is_null() {
+ thrown.expect(NullPointerException.class);
treeRootHolder.setRoot(null);
}
- @Test(expected = IllegalStateException.class)
+ @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(component);
- assertThat(treeRootHolder.getRoot()).isSameAs(component);
+ treeRootHolder.setRoot(project);
+ assertThat(treeRootHolder.getRoot()).isSameAs(project);
+ }
+
+ @Test
+ public void get_by_ref() throws Exception {
+ Component file = new DumbComponent(Component.Type.FILE, 4, null, null);
+ Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, null, null, file);
+ Component module = new DumbComponent(Component.Type.MODULE, 2, null, null, directory);
+ Component project = new DumbComponent(Component.Type.PROJECT, 1, null, null, module);
+ 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() throws Exception {
+ thrown.expect(IllegalStateException.class);
+ treeRootHolder.getComponentByRef(project.getRef());
+ }
+
+ @Test
+ public void fail_to_get_by_ref_if_ref_not_found() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ treeRootHolder.setRoot(project);
+ treeRootHolder.getComponentByRef(123);
}
}