@@ -0,0 +1,91 @@ | |||
/* | |||
* 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.Objects; | |||
/** | |||
* Implementation of {@link TypeAwareVisitor} that implements a depth first crawling of the | |||
* {@link ComponentImpl} tree. It supports a max depth for crawling (component strictly deeper than the specified | |||
* type will be ignored). | |||
*/ | |||
public abstract class ChildFirstTypeAwareVisitor implements TypeAwareVisitor { | |||
private final Component.Type maxDepth; | |||
protected ChildFirstTypeAwareVisitor(Component.Type maxDepth) { | |||
this.maxDepth = Objects.requireNonNull(maxDepth); | |||
} | |||
@Override | |||
public void visit(Component component) { | |||
if (component.getType().isDeeperThan(maxDepth)) { | |||
return; | |||
} | |||
if (component.getType() != maxDepth) { | |||
for (Component child : component.getChildren()) { | |||
visit(child); | |||
} | |||
} | |||
switch (component.getType()) { | |||
case PROJECT: | |||
visitProject(component); | |||
break; | |||
case MODULE: | |||
visitModule(component); | |||
break; | |||
case DIRECTORY: | |||
visitDirectory(component); | |||
break; | |||
case FILE: | |||
visitFile(component); | |||
break; | |||
default: | |||
visitUnknown(component); | |||
} | |||
} | |||
@Override | |||
public void visitProject(Component tree) { | |||
// empty implementation, meant to be override at will by subclasses | |||
} | |||
@Override | |||
public void visitModule(Component tree) { | |||
// empty implementation, meant to be override at will by subclasses | |||
} | |||
@Override | |||
public void visitDirectory(Component tree) { | |||
// empty implementation, meant to be override at will by subclasses | |||
} | |||
@Override | |||
public void visitFile(Component tree) { | |||
// empty implementation, meant to be override at will by subclasses | |||
} | |||
@Override | |||
public void visitUnknown(Component tree) { | |||
// empty implementation, meant to be override at will by subclasses | |||
} | |||
} |
@@ -0,0 +1,65 @@ | |||
/* | |||
* 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.List; | |||
import org.sonar.server.computation.context.ComputationContext; | |||
import org.sonar.server.computation.event.EventRepository; | |||
import org.sonar.server.computation.measure.MeasureRepository; | |||
public interface Component { | |||
enum Type { | |||
PROJECT(0), MODULE(1), DIRECTORY(2), FILE(3); | |||
private final int depth; | |||
Type(int depth) { | |||
this.depth = depth; | |||
} | |||
public int getDepth() { | |||
return depth; | |||
} | |||
public boolean isDeeperThan(Type otherType) { | |||
return this.getDepth() > otherType.getDepth(); | |||
} | |||
} | |||
ComputationContext getContext(); | |||
Type getType(); | |||
// FIXME we should not expose a batch specific information | |||
int getRef(); | |||
List<Component> getChildren(); | |||
/** | |||
* The event repository for the current component | |||
*/ | |||
EventRepository getEventRepository(); | |||
/** | |||
* the measure repository for the current component | |||
*/ | |||
MeasureRepository getMeasureRepository(); | |||
} |
@@ -0,0 +1,142 @@ | |||
/* | |||
* 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 com.google.common.base.Optional; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Iterables; | |||
import java.util.Collections; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
import javax.annotation.Nonnull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.batch.protocol.Constants; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import org.sonar.core.measure.db.MeasureDto; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.server.computation.ComputationContext; | |||
import org.sonar.server.computation.event.Event; | |||
import org.sonar.server.computation.event.EventRepository; | |||
import org.sonar.server.computation.measure.MeasureRepository; | |||
import org.sonar.server.db.DbClient; | |||
import static com.google.common.base.Predicates.notNull; | |||
import static com.google.common.collect.ImmutableList.copyOf; | |||
import static com.google.common.collect.Iterables.filter; | |||
import static java.util.Objects.requireNonNull; | |||
public class ComponentImpl implements Component { | |||
private final ComputationContext context; | |||
private final Type type; | |||
private final BatchReport.Component component; | |||
private final List<Component> children; | |||
private final EventRepository eventRepository = new SetEventRepository(); | |||
public ComponentImpl(ComputationContext context, BatchReport.Component component, @Nullable Iterable<Component> children) { | |||
this.context = context; | |||
this.component = component; | |||
this.type = convertType(component.getType()); | |||
this.children = children == null ? Collections.<Component>emptyList() : copyOf(filter(children, notNull())); | |||
} | |||
private static Type convertType(Constants.ComponentType type) { | |||
switch (type) { | |||
case PROJECT: | |||
return Type.PROJECT; | |||
case MODULE: | |||
return Type.MODULE; | |||
case DIRECTORY: | |||
return Type.DIRECTORY; | |||
case FILE: | |||
return Type.FILE; | |||
default: | |||
throw new IllegalArgumentException("Unsupported Constants.ComponentType value " + type); | |||
} | |||
} | |||
@Override | |||
public Type getType() { | |||
return type; | |||
} | |||
@Override | |||
public int getRef() { | |||
return component.getRef(); | |||
} | |||
@Override | |||
public List<Component> getChildren() { | |||
return children; | |||
} | |||
@Override | |||
public org.sonar.server.computation.context.ComputationContext getContext() { | |||
return context; | |||
} | |||
@Override | |||
public EventRepository getEventRepository() { | |||
return eventRepository; | |||
} | |||
@Override | |||
public MeasureRepository getMeasureRepository() { | |||
return new MeasureRepository() { | |||
@Override | |||
public Optional<MeasureDto> findPrevious(Metric<?> metric) { | |||
DbClient dbClient = context.getDbClient(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
return Optional.fromNullable( | |||
dbClient.measureDao().findByComponentKeyAndMetricKey(dbSession, component.getKey(), metric.getKey()) | |||
); | |||
} | |||
} | |||
@Override | |||
public Optional<BatchReport.Measure> findCurrent(final Metric<?> metric) { | |||
return Optional.fromNullable(Iterables.find( | |||
context.getReportReader().readComponentMeasures(component.getRef()), | |||
new Predicate<BatchReport.Measure>() { | |||
@Override | |||
public boolean apply(@Nonnull BatchReport.Measure input) { | |||
return input.getMetricKey().equals(metric.getKey()); | |||
} | |||
} | |||
)); | |||
} | |||
}; | |||
} | |||
private static class SetEventRepository implements EventRepository { | |||
private final Set<Event> events = new HashSet<>(); | |||
@Override | |||
public void add(Event event) { | |||
events.add(requireNonNull(event)); | |||
} | |||
@Override | |||
public Iterable<Event> getEvents() { | |||
return events; | |||
} | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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 ComponentVisitor { | |||
void visit(Component tree); | |||
} |
@@ -0,0 +1,35 @@ | |||
/* | |||
* 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; | |||
/** | |||
* A {@link ComponentVisitor} which can exposes methods which ensure the type of the visited Component. | |||
*/ | |||
public interface TypeAwareVisitor extends ComponentVisitor { | |||
void visitProject(Component tree); | |||
void visitModule(Component tree); | |||
void visitDirectory(Component tree); | |||
void visitFile(Component tree); | |||
void visitUnknown(Component tree); | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.computation.component; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,31 @@ | |||
/* | |||
* 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.context; | |||
import org.sonar.server.computation.component.Component; | |||
import org.sonar.server.computation.language.LanguageRepository; | |||
public interface ComputationContext { | |||
Component getRoot(); | |||
LanguageRepository getLanguageRepository(); | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.computation.context; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,92 @@ | |||
/* | |||
* 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.event; | |||
import java.util.Objects; | |||
import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import static java.util.Objects.requireNonNull; | |||
@Immutable | |||
public class Event { | |||
private final String name; | |||
private final Category category; | |||
@Nullable | |||
private final String data; | |||
@Nullable | |||
private final String description; | |||
private Event(String name, Category category, @Nullable String data, @Nullable String description) { | |||
this.name = requireNonNull(name); | |||
this.category = requireNonNull(category); | |||
this.data = data; | |||
this.description = description; | |||
} | |||
public static Event createAlert(String name, @Nullable String data, @Nullable String description) { | |||
return new Event(name, Category.ALERT, data, description); | |||
} | |||
public static Event createProfile(String name, @Nullable String data, @Nullable String description) { | |||
return new Event(name, Category.PROFILE, data, description); | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public Category getCategory() { | |||
return category; | |||
} | |||
public String getData() { | |||
return data; | |||
} | |||
@Nullable | |||
public String getDescription() { | |||
return description; | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
return true; | |||
} | |||
if (o == null || getClass() != o.getClass()) { | |||
return false; | |||
} | |||
Event event = (Event) o; | |||
return Objects.equals(name, event.name) && | |||
Objects.equals(category, event.category); | |||
} | |||
@Override | |||
public int hashCode() { | |||
return Objects.hash(name, category); | |||
} | |||
public enum Category { | |||
ALERT, PROFILE | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
/* | |||
* 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.event; | |||
public interface EventRepository { | |||
void add(Event event); | |||
Iterable<Event> getEvents(); | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.computation.event; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,34 @@ | |||
/* | |||
* 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.measure; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
import com.google.common.base.Optional; | |||
import org.sonar.core.measure.db.MeasureDto; | |||
public interface MeasureRepository { | |||
// FIXME should not expose MeasureDto from DAO layer | |||
Optional<MeasureDto> findPrevious(Metric<?> metric); | |||
// FIXME should not expose Measure from BatchReport | |||
Optional<BatchReport.Measure> findCurrent(Metric<?> metric); | |||
} |
@@ -0,0 +1,304 @@ | |||
/* | |||
* 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 com.google.common.collect.ImmutableList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.junit.Test; | |||
import org.mockito.InOrder; | |||
import org.sonar.server.computation.context.ComputationContext; | |||
import org.sonar.server.computation.event.EventRepository; | |||
import org.sonar.server.computation.measure.MeasureRepository; | |||
import static org.mockito.Mockito.inOrder; | |||
import static org.mockito.Mockito.spy; | |||
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; | |||
public class ChildFirstTypeAwareVisitorTest { | |||
private static final String UNSUPPORTED_OPERATION_ERROR = "This node has no repository nor context"; | |||
private static final Component FILE_4 = component(FILE, 4); | |||
private static final Component FILE_5 = component(FILE, 5); | |||
private static final Component DIRECTORY_3 = component(DIRECTORY, 3, FILE_4, FILE_5); | |||
private static final Component MODULE_2 = component(MODULE, 2, DIRECTORY_3); | |||
private static final Component COMPONENT_TREE = component(PROJECT, 1, MODULE_2); | |||
private final ChildFirstTypeAwareVisitor spyProjectVisitor = spy(new ChildFirstTypeAwareVisitor(PROJECT) {}); | |||
private final ChildFirstTypeAwareVisitor spyModuleVisitor = spy(new ChildFirstTypeAwareVisitor(MODULE) {}); | |||
private final ChildFirstTypeAwareVisitor spyDirectoryVisitor = spy(new ChildFirstTypeAwareVisitor(DIRECTORY) {}); | |||
private final ChildFirstTypeAwareVisitor spyFileVisitor = spy(new ChildFirstTypeAwareVisitor(FILE) {}); | |||
private final InOrder inOrder = inOrder(spyProjectVisitor, spyModuleVisitor, spyDirectoryVisitor, spyFileVisitor); | |||
@Test(expected = NullPointerException.class) | |||
public void non_null_max_depth_fast_fail() { | |||
new ChildFirstTypeAwareVisitor(null) { | |||
}; | |||
} | |||
@Test(expected = NullPointerException.class) | |||
public void visit_null_Component_throws_NPE() { | |||
spyFileVisitor.visit(null); | |||
} | |||
@Test | |||
public void visit_file_with_depth_FILE_calls_visit_file() { | |||
Component component = component(FILE, 1); | |||
spyFileVisitor.visit(component); | |||
inOrder.verify(spyFileVisitor).visit(component); | |||
inOrder.verify(spyFileVisitor).visitFile(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_module_with_depth_FILE_calls_visit_module() { | |||
Component component = component(MODULE, 1); | |||
spyFileVisitor.visit(component); | |||
inOrder.verify(spyFileVisitor).visit(component); | |||
inOrder.verify(spyFileVisitor).visitModule(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_directory_with_depth_FILE_calls_visit_directory() { | |||
Component component = component(DIRECTORY, 1); | |||
spyFileVisitor.visit(component); | |||
inOrder.verify(spyFileVisitor).visit(component); | |||
inOrder.verify(spyFileVisitor).visitDirectory(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_project_with_depth_FILE_calls_visit_project() { | |||
Component component = component(PROJECT, 1); | |||
spyFileVisitor.visit(component); | |||
inOrder.verify(spyFileVisitor).visit(component); | |||
inOrder.verify(spyFileVisitor).visitProject(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_file_with_depth_DIRECTORY_does_not_call_visit_file() { | |||
Component component = component(FILE, 1); | |||
spyDirectoryVisitor.visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_directory_with_depth_DIRECTORY_calls_visit_directory() { | |||
Component component = component(DIRECTORY, 1); | |||
spyDirectoryVisitor.visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visitDirectory(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_module_with_depth_DIRECTORY_calls_visit_module() { | |||
Component component = component(MODULE, 1); | |||
spyDirectoryVisitor.visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visitModule(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_project_with_depth_DIRECTORY_calls_visit_project() { | |||
Component component = component(PROJECT, 1); | |||
spyDirectoryVisitor.visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visit(component); | |||
inOrder.verify(spyDirectoryVisitor).visitProject(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_file_with_depth_MODULE_does_not_call_visit_file() { | |||
Component component = component(FILE, 1); | |||
spyModuleVisitor.visit(component); | |||
inOrder.verify(spyModuleVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_directory_with_depth_MODULE_does_not_call_visit_directory() { | |||
Component component = component(DIRECTORY, 1); | |||
spyModuleVisitor.visit(component); | |||
inOrder.verify(spyModuleVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_module_with_depth_MODULE_calls_visit_module() { | |||
Component component = component(MODULE, 1); | |||
spyModuleVisitor.visit(component); | |||
inOrder.verify(spyModuleVisitor).visit(component); | |||
inOrder.verify(spyModuleVisitor).visitModule(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_project_with_depth_MODULE_calls_visit_project() { | |||
Component component = component(MODULE, 1); | |||
spyModuleVisitor.visit(component); | |||
inOrder.verify(spyModuleVisitor).visit(component); | |||
inOrder.verify(spyModuleVisitor).visitModule(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_file_with_depth_PROJECT_does_not_call_visit_file() { | |||
Component component = component(FILE, 1); | |||
spyProjectVisitor.visit(component); | |||
inOrder.verify(spyProjectVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_directory_with_depth_PROJECT_does_not_call_visit_directory() { | |||
Component component = component(DIRECTORY, 1); | |||
spyProjectVisitor.visit(component); | |||
inOrder.verify(spyProjectVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_module_with_depth_PROJECT_does_not_call_visit_module() { | |||
Component component = component(MODULE, 1); | |||
spyProjectVisitor.visit(component); | |||
inOrder.verify(spyProjectVisitor).visit(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void visit_project_with_depth_PROJECT_calls_visit_project() { | |||
Component component = component(PROJECT, 1); | |||
spyProjectVisitor.visit(component); | |||
inOrder.verify(spyProjectVisitor).visit(component); | |||
inOrder.verify(spyProjectVisitor).visitProject(component); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void verify_visit_call_when_visit_tree_with_depth_FILE() { | |||
spyFileVisitor.visit(COMPONENT_TREE); | |||
inOrder.verify(spyFileVisitor).visit(COMPONENT_TREE); | |||
inOrder.verify(spyFileVisitor).visit(MODULE_2); | |||
inOrder.verify(spyFileVisitor).visit(DIRECTORY_3); | |||
inOrder.verify(spyFileVisitor).visit(FILE_4); | |||
inOrder.verify(spyFileVisitor).visitFile(FILE_4); | |||
inOrder.verify(spyFileVisitor).visit(FILE_5); | |||
inOrder.verify(spyFileVisitor).visitFile(FILE_5); | |||
inOrder.verify(spyFileVisitor).visitDirectory(DIRECTORY_3); | |||
inOrder.verify(spyFileVisitor).visitModule(MODULE_2); | |||
inOrder.verify(spyFileVisitor).visitProject(COMPONENT_TREE); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void verify_visit_call_when_visit_tree_with_depth_DIRECTORY() { | |||
spyDirectoryVisitor.visit(COMPONENT_TREE); | |||
inOrder.verify(spyDirectoryVisitor).visit(COMPONENT_TREE); | |||
inOrder.verify(spyDirectoryVisitor).visit(MODULE_2); | |||
inOrder.verify(spyDirectoryVisitor).visit(DIRECTORY_3); | |||
inOrder.verify(spyDirectoryVisitor).visitDirectory(DIRECTORY_3); | |||
inOrder.verify(spyDirectoryVisitor).visitModule(MODULE_2); | |||
inOrder.verify(spyDirectoryVisitor).visitProject(COMPONENT_TREE); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void verify_visit_call_when_visit_tree_with_depth_MODULE() { | |||
spyModuleVisitor.visit(COMPONENT_TREE); | |||
inOrder.verify(spyModuleVisitor).visit(COMPONENT_TREE); | |||
inOrder.verify(spyModuleVisitor).visit(MODULE_2); | |||
inOrder.verify(spyModuleVisitor).visitModule(MODULE_2); | |||
inOrder.verify(spyModuleVisitor).visitProject(COMPONENT_TREE); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
@Test | |||
public void verify_visit_call_when_visit_tree_with_depth_PROJECT() { | |||
spyProjectVisitor.visit(COMPONENT_TREE); | |||
inOrder.verify(spyProjectVisitor).visit(COMPONENT_TREE); | |||
inOrder.verify(spyProjectVisitor).visitProject(COMPONENT_TREE); | |||
inOrder.verifyNoMoreInteractions(); | |||
} | |||
private static Component component(final Component.Type type, final int ref, final Component... children) { | |||
return new Component() { | |||
@Override | |||
public Type getType() { | |||
return type; | |||
} | |||
@Override | |||
public int getRef() { | |||
return ref; | |||
} | |||
@Override | |||
public List<Component> getChildren() { | |||
return children == null ? Collections.<Component>emptyList() : ImmutableList.copyOf(Arrays.asList(children)); | |||
} | |||
@Override | |||
public ComputationContext getContext() { | |||
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_ERROR); | |||
} | |||
@Override | |||
public EventRepository getEventRepository() { | |||
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_ERROR); | |||
} | |||
@Override | |||
public MeasureRepository getMeasureRepository() { | |||
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_ERROR); | |||
} | |||
}; | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
* 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.Test; | |||
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.MODULE; | |||
import static org.sonar.server.computation.component.Component.Type.PROJECT; | |||
public class ComponentTest { | |||
@Test | |||
public void verify_type_is_deeper_than_when_comparing_to_itself() throws Exception { | |||
for (Component.Type type : Component.Type.values()) { | |||
assertThat(type.isDeeperThan(type)).isFalse(); | |||
} | |||
} | |||
@Test | |||
public void FILE_type_is_deeper_than_all_other_types() throws Exception { | |||
assertThat(Component.Type.FILE.isDeeperThan(DIRECTORY)).isTrue(); | |||
assertThat(Component.Type.FILE.isDeeperThan(MODULE)).isTrue(); | |||
assertThat(Component.Type.FILE.isDeeperThan(PROJECT)).isTrue(); | |||
} | |||
@Test | |||
public void DIRECTORY_type_is_deeper_than_MODULE_and_PROJECT() throws Exception { | |||
assertThat(Component.Type.DIRECTORY.isDeeperThan(MODULE)).isTrue(); | |||
assertThat(Component.Type.DIRECTORY.isDeeperThan(PROJECT)).isTrue(); | |||
} | |||
@Test | |||
public void MODULE_type_is_deeper_than_PROJECT() throws Exception { | |||
assertThat(Component.Type.MODULE.isDeeperThan(PROJECT)).isTrue(); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* 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.event; | |||
import org.junit.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class EventTest { | |||
private static final String SOME_NAME = "someName"; | |||
private static final String SOME_DATA = "some data"; | |||
private static final String SOME_DESCRIPTION = "some description"; | |||
@Test(expected = NullPointerException.class) | |||
public void createAlert_fail_fast_null_check_on_null_name() { | |||
Event.createAlert(null, SOME_DATA, SOME_DESCRIPTION); | |||
} | |||
@Test(expected = NullPointerException.class) | |||
public void createProfile_fail_fast_null_check_on_null_name() { | |||
Event.createProfile(null, SOME_DATA, SOME_DESCRIPTION); | |||
} | |||
@Test | |||
public void createAlert_verify_fields() { | |||
Event event = Event.createAlert(SOME_NAME, SOME_DATA, SOME_DESCRIPTION); | |||
assertThat(event.getName()).isEqualTo(SOME_NAME); | |||
assertThat(event.getCategory()).isEqualTo(Event.Category.ALERT); | |||
assertThat(event.getData()).isEqualTo(SOME_DATA); | |||
assertThat(event.getDescription()).isEqualTo(SOME_DESCRIPTION); | |||
} | |||
@Test | |||
public void createProfile_verify_fields() { | |||
Event event = Event.createProfile(SOME_NAME, SOME_DATA, SOME_DESCRIPTION); | |||
assertThat(event.getName()).isEqualTo(SOME_NAME); | |||
assertThat(event.getCategory()).isEqualTo(Event.Category.PROFILE); | |||
assertThat(event.getData()).isEqualTo(SOME_DATA); | |||
assertThat(event.getDescription()).isEqualTo(SOME_DESCRIPTION); | |||
} | |||
} |