blob: 0ed6a1aed1b1f25bc273587503d9752a0835b664 [file] [log] [blame]
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.resources.gss;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssClassSelectorNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssCompositeValueNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssLiteralNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssStringNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssUnknownAtRuleNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssValueNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.ErrorManager;
import com.google.gwt.thirdparty.common.css.compiler.ast.MutatingVisitController;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import junit.framework.TestCase;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Test for {@link com.google.gwt.resources.gss.ExternalClassesCollector}.
*/
public class ExternalClassesCollectorTest extends TestCase {
private CssUnknownAtRuleNode cssUnknownAtRuleNode;
private CssLiteralNode atRuleNameNode;
private MutatingVisitController mutatingVisitController;
private CssCompositeValueNode atRuleParameters;
private ErrorManager errorManager;
@Override
protected void setUp() {
cssUnknownAtRuleNode = mock(CssUnknownAtRuleNode.class);
atRuleNameNode = mock(CssLiteralNode.class);
mutatingVisitController = mock(MutatingVisitController.class);
atRuleParameters = mock(CssCompositeValueNode.class);
errorManager = mock(ErrorManager.class);
when(cssUnknownAtRuleNode.getName()).thenReturn(atRuleNameNode);
when(cssUnknownAtRuleNode.getParameters()).thenReturn(
Lists.<CssValueNode>newArrayList(atRuleParameters));
}
public void testLeaveUnknownAtRule_notAnExternalAtRule_doNothing() {
// Given
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
when(atRuleNameNode.getValue()).thenReturn("dummy");
// When
externalClassesCollector.leaveUnknownAtRule(cssUnknownAtRuleNode);
// Then
verify(cssUnknownAtRuleNode, never()).getParameters();
verify(mutatingVisitController, never()).removeCurrentNode();
}
public void testLeaveUnknownAtRule_simpleExternalAtRule_classesReturnByGetExternalClass() {
// Given
HashSet<String> styleClassSet = Sets.newHashSet();
HashSet<String> orphanClassName = Sets.newHashSet();
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
when(atRuleNameNode.getValue()).thenReturn("external");
List<CssValueNode> parameters = Lists.newArrayList(literalNode("externalClass"),
literalNode("externalClass2"));
when(atRuleParameters.getValues()).thenReturn(parameters);
// When
externalClassesCollector.leaveUnknownAtRule(cssUnknownAtRuleNode);
// Then
verify(cssUnknownAtRuleNode).getParameters();
verify(atRuleParameters).getValues();
verify(mutatingVisitController).removeCurrentNode();
Set<String> externalClasses = externalClassesCollector.getExternalClassNames(styleClassSet,
orphanClassName);
assertEquals(2, externalClasses.size());
assertTrue(externalClasses.contains("externalClass"));
assertTrue(externalClasses.contains("externalClass2"));
}
public void testLeaveUnknownAtRule_externalAtRuleWithMatchAllPrefix_allClassesAreExternals() {
// Given
HashSet<String> styleClassSet = Sets.newHashSet("class1", "class2", "class3");
HashSet<String> orphanClassName = Sets.newHashSet();
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
when(atRuleNameNode.getValue()).thenReturn("external");
List<CssValueNode> parameters = Lists.newArrayList(stringNode("*"));
when(atRuleParameters.getValues()).thenReturn(parameters);
// When
externalClassesCollector.leaveUnknownAtRule(cssUnknownAtRuleNode);
// Then
verify(cssUnknownAtRuleNode).getParameters();
verify(atRuleParameters).getValues();
verify(mutatingVisitController).removeCurrentNode();
Set<String> externalClasses = externalClassesCollector.getExternalClassNames(styleClassSet,
orphanClassName);
assertEquals(3, externalClasses.size());
assertTrue(externalClasses.contains("class1"));
assertTrue(externalClasses.contains("class2"));
assertTrue(externalClasses.contains("class3"));
}
public void
testLeaveUnknownAtRule_styleClassWithoutMethodAndRemovedFromAST_consideredAsExternal() {
// Given
HashSet<String> styleClassSet = Sets.newHashSet("foo", "bar");
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
// AST contains only one style class named foo, bar is not in the AST anymore
CssClassSelectorNode classSelectorNode = mock(CssClassSelectorNode.class);
when(classSelectorNode.getRefinerName()).thenReturn("foo");
externalClassesCollector.enterClassSelector(classSelectorNode);
// The style class bar is not associated to a java method
HashSet<String> orphanClassName = Sets.newHashSet("bar");
// When
Set<String> externalClasses = externalClassesCollector.getExternalClassNames(styleClassSet,
orphanClassName);
// Then
assertEquals(1, externalClasses.size());
assertTrue(externalClasses.contains("bar"));
}
public void testLeaveUnknownAtRule_externalAtRuleWithMatchAllPrefixThenAnotherExternalAtRule_anotherAtRuleNotProcessed() {
// Given
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
when(atRuleNameNode.getValue()).thenReturn("external");
List<CssValueNode> parameters = Lists.newArrayList(stringNode("*"));
when(atRuleParameters.getValues()).thenReturn(parameters);
externalClassesCollector.leaveUnknownAtRule(cssUnknownAtRuleNode);
reset(mutatingVisitController);
CssUnknownAtRuleNode secondAtRuleNode = mock(CssUnknownAtRuleNode.class);
CssLiteralNode secondAtRuleNameNode = mock(CssLiteralNode.class);
when(secondAtRuleNameNode.getValue()).thenReturn("external");
when(secondAtRuleNode.getName()).thenReturn(secondAtRuleNameNode);
// When
externalClassesCollector.leaveUnknownAtRule(secondAtRuleNode);
// Then
verify(secondAtRuleNode, never()).getParameters();
verify(mutatingVisitController).removeCurrentNode();
}
public void testLeaveUnknownAtRule_externalAtRuleWithPrefix_classesMatchingThePrefixAreExternals() {
// Given
HashSet<String> styleClassSet = Sets.newHashSet("prefix", "prefix-class1",
"prefi-notexternal","external");
HashSet<String> orphanClassName = Sets.newHashSet();
ExternalClassesCollector externalClassesCollector = createAndInitExternalClassesCollector();
when(atRuleNameNode.getValue()).thenReturn("external");
List<CssValueNode> parameters = Lists.newArrayList(literalNode("external"),
stringNode("prefix*"));
when(atRuleParameters.getValues()).thenReturn(parameters);
// When
externalClassesCollector.leaveUnknownAtRule(cssUnknownAtRuleNode);
// Then
verify(cssUnknownAtRuleNode).getParameters();
verify(atRuleParameters).getValues();
verify(mutatingVisitController).removeCurrentNode();
Set<String> externalClasses = externalClassesCollector.getExternalClassNames(styleClassSet,
orphanClassName);
assertEquals(3, externalClasses.size());
assertTrue(externalClasses.contains("prefix"));
assertTrue(externalClasses.contains("prefix-class1"));
assertTrue(externalClasses.contains("external"));
}
private CssValueNode literalNode(String externalClass) {
CssValueNode node = mock(CssLiteralNode.class);
when(node.getValue()).thenReturn(externalClass);
return node;
}
private CssValueNode stringNode(String selector) {
CssStringNode node = mock(CssStringNode.class);
when(node.getConcreteValue()).thenReturn(selector);
return node;
}
private ExternalClassesCollector createAndInitExternalClassesCollector() {
ExternalClassesCollector externalClassesCollector =
new ExternalClassesCollector(mutatingVisitController, errorManager);
// initialise the object but do nothing
externalClassesCollector.runPass();
return externalClassesCollector;
}
}