// =====================================================================
//
// Copyright (C) 2012 - 2016, Philip Graf
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// =====================================================================
package ch.acanda.eclipse.pmd.cache;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import net.sourceforge.pmd.RuleSets;
import org.junit.Test;
import ch.acanda.eclipse.pmd.domain.Location;
import ch.acanda.eclipse.pmd.domain.LocationContext;
import ch.acanda.eclipse.pmd.domain.ProjectModel;
import ch.acanda.eclipse.pmd.domain.RuleSetModel;
import ch.acanda.eclipse.pmd.domain.WorkspaceModel;
import com.google.common.cache.CacheLoader;
/**
* Unit tests for {@link RuleSetsCache}.
*
* @author Philip Graf
*/
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
public final class RuleSetsCacheTest {
private static final String PROJECT_NAME_1 = "Foo";
private static final String PROJECT_NAME_2 = "Bar";
private static final RuleSets RULE_SETS_FOO_1 = new TestRuleSets("RULE_SETS_FOO_1");
private static final RuleSets RULE_SETS_FOO_2 = new TestRuleSets("RULE_SETS_FOO_2");
private static final RuleSets RULE_SETS_BAR_1 = new TestRuleSets("RULE_SETS_BAR_1");
private static final RuleSets RULE_SETS_BAR_2 = new TestRuleSets("RULE_SETS_BAR_2");
/**
* Verifies that the first cache access loads the rule sets from the cache loader.
*/
@Test
public void firstGetLoadsFromCache() throws Exception {
final RuleSetsCache cache = new RuleSetsCache(getCacheLoaderMock(), getWorkspaceModel());
final RuleSets actualRuleSets = cache.getRuleSets(PROJECT_NAME_1);
assertSame("First cache access should return rule sets from loader", RULE_SETS_FOO_1, actualRuleSets);
}
/**
* Verifies that the second cache access returns the cached rule sets.
*/
@Test
public void secondGetDoesNotLoad() throws Exception {
final RuleSetsCache cache = new RuleSetsCache(getCacheLoaderMock(), getWorkspaceModel());
cache.getRuleSets(PROJECT_NAME_1);
final RuleSets actualRuleSets = cache.getRuleSets(PROJECT_NAME_1);
assertSame("Second cache access should return cached rule sets", RULE_SETS_FOO_1, actualRuleSets);
}
/**
* Verifies that the second cache access loads the rule sets if the project model's rule sets have been changed
* after the first access.
*/
@Test
public void secondGetLoadsWhenProjectRuleSetsWereChanged() throws Exception {
final WorkspaceModel workspaceModel = getWorkspaceModel();
final RuleSetsCache cache = new RuleSetsCache(getCacheLoaderMock(), workspaceModel);
cache.getRuleSets(PROJECT_NAME_1);
final RuleSetModel ruleSetModel = new RuleSetModel("abc", new Location("path", LocationContext.WORKSPACE));
workspaceModel.getOrCreateProject(PROJECT_NAME_1).setRuleSets(Arrays.asList(ruleSetModel));
final RuleSets actualRuleSets = cache.getRuleSets(PROJECT_NAME_1);
assertSame("Second cache access should reload rule sets", RULE_SETS_FOO_2, actualRuleSets);
}
/**
* Verifies that the second cache access loads the rule sets if the project model's rule sets have been changed
* after the first access. In this case, the project model was added after the rule sets cache was created.
*/
@Test
public void secondGetLoadsWhenLaterAddedProjectRuleSetsWereChanged() throws Exception {
final WorkspaceModel workspaceModel = getWorkspaceModel();
final RuleSetsCache cache = new RuleSetsCache(getCacheLoaderMock(), workspaceModel);
workspaceModel.add(new ProjectModel(PROJECT_NAME_2));
cache.getRuleSets(PROJECT_NAME_2);
final RuleSetModel ruleSetModel = new RuleSetModel("abc", new Location("path", LocationContext.WORKSPACE));
workspaceModel.getOrCreateProject(PROJECT_NAME_2).setRuleSets(Arrays.asList(ruleSetModel));
final RuleSets actualRuleSets = cache.getRuleSets(PROJECT_NAME_2);
assertSame("Second cache access should reload rule sets", RULE_SETS_BAR_2, actualRuleSets);
}
/**
* Verifies that the second cache access loads the rule sets if the project model has been removed and added after
* the first access.
*/
@Test
public void secondGetLoadsWhenProjectWasREmovedAndAddedAfterFirstGet() throws Exception {
final WorkspaceModel workspaceModel = getWorkspaceModel();
final RuleSetsCache cache = new RuleSetsCache(getCacheLoaderMock(), workspaceModel);
cache.getRuleSets(PROJECT_NAME_1);
workspaceModel.remove(PROJECT_NAME_1);
workspaceModel.add(new ProjectModel(PROJECT_NAME_1));
final RuleSets actualRuleSets = cache.getRuleSets(PROJECT_NAME_1);
assertSame("Second cache access should reload rule sets", RULE_SETS_FOO_2, actualRuleSets);
}
private CacheLoader<String, RuleSets> getCacheLoaderMock() throws Exception {
@SuppressWarnings("unchecked")
final CacheLoader<String, RuleSets> loader = mock(CacheLoader.class);
when(loader.load(PROJECT_NAME_1)).thenReturn(RULE_SETS_FOO_1, RULE_SETS_FOO_2);
when(loader.load(PROJECT_NAME_2)).thenReturn(RULE_SETS_BAR_1, RULE_SETS_BAR_2);
return loader;
}
private WorkspaceModel getWorkspaceModel() {
final WorkspaceModel workspaceModel = new WorkspaceModel();
workspaceModel.add(new ProjectModel(PROJECT_NAME_1));
return workspaceModel;
}
private static final class TestRuleSets extends RuleSets {
private final String name;
public TestRuleSets(final String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
}