/*
* 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.Matchers.any;
import static org.mockito.Matchers.anyList;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.ext.ResourceContext;
import com.google.gwt.resources.gss.ResourceUrlFunction.MethodByPathHelper;
import com.google.gwt.resources.gss.ast.CssJavaExpressionNode;
import com.google.gwt.thirdparty.common.css.SourceCodeLocation;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssFunctionArgumentsNode;
import com.google.gwt.thirdparty.common.css.compiler.ast.CssFunctionNode;
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.GssError;
import com.google.gwt.thirdparty.common.css.compiler.ast.GssFunctionException;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import junit.framework.TestCase;
import java.util.List;
/**
* Test for {@link ResourceUrlFunction}.
*/
public class ResourceUrlFunctionTest extends TestCase {
private static String JAVA_EXPRESSION_PATTERN = "ResourceUrlFunctionTest.this.%s.getSafeUri()" +
".asString()";
private ResourceContext resourceContext;
private ErrorManager errorManager;
private MethodByPathHelper methodByPathHelper;
private ResourceUrlFunction resourceUrlFunction;
private JClassType dataResourceType;
private JClassType imageResourceType;
@Override
protected void setUp() {
errorManager = mock(ErrorManager.class);
methodByPathHelper = mock(MethodByPathHelper.class);
dataResourceType = mock(JClassType.class);
imageResourceType = mock(JClassType.class);
resourceContext = mockResourceContext();
resourceUrlFunction = new ResourceUrlFunction(resourceContext, methodByPathHelper);
}
public void testValidImageResource() throws GssFunctionException {
// given
List<CssValueNode> input = createInput("image");
when(dataResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(false);
when(imageResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(true);
// when
List<CssValueNode> result = resourceUrlFunction.getCallResultNodes(input, errorManager);
// then
assertResultIsValid(result, JAVA_EXPRESSION_PATTERN.replace("%s", "image()"));
}
public void testValidDataResource() throws GssFunctionException {
// given
List<CssValueNode> input = createInput("data");
when(dataResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(true);
when(imageResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(false);
// when
List<CssValueNode> result = resourceUrlFunction.getCallResultNodes(input, errorManager);
// then
assertResultIsValid(result, JAVA_EXPRESSION_PATTERN.replace("%s", "data()"));
}
public void testMultiplePath() throws GssFunctionException {
// given
List<CssValueNode> input = createInput("method1.method2.resource");
when(dataResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(true);
// when
List<CssValueNode> result = resourceUrlFunction.getCallResultNodes(input, errorManager);
// then
assertResultIsValid(result, JAVA_EXPRESSION_PATTERN.replace("%s",
"method1().method2().resource()"));
}
public void testInvalidResource() {
// given
List<CssValueNode> input = createInput("invalidResource");
when(dataResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(false);
when(imageResourceType.isAssignableFrom(any(JClassType.class))).thenReturn(false);
// when
try {
resourceUrlFunction.getCallResultNodes(input, errorManager);
} catch (GssFunctionException expected) {
// then
verify(errorManager).report(any(GssError.class));
return;
}
fail("GssFunctionException expected");
}
public void testInvalidPath() throws NotFoundException {
// given
List<CssValueNode> input = createInput("invalid.path");
when(methodByPathHelper.getReturnType(any(ResourceContext.class),
anyList())).thenThrow(NotFoundException.class);
// when
try {
resourceUrlFunction.getCallResultNodes(input, errorManager);
} catch (GssFunctionException expected) {
// then
verify(errorManager).report(any(GssError.class));
return;
}
fail("GssFunctionException expected");
}
private void assertResultIsValid(List<CssValueNode> result, String expectedJavaExpression) {
assertEquals(1, result.size());
assertTrue(result.get(0) instanceof CssFunctionNode);
CssFunctionArgumentsNode arguments = ((CssFunctionNode) result.get(0)).getArguments();
assertEquals(1, arguments.numChildren());
assertTrue(arguments.getChildAt(0) instanceof CssJavaExpressionNode);
CssJavaExpressionNode javaExpressionNode = (CssJavaExpressionNode) arguments.getChildAt(0);
assertEquals(expectedJavaExpression, javaExpressionNode.getValue());
verify(errorManager, never()).report(any(GssError.class));
verify(errorManager, never()).reportWarning(any(GssError.class));
}
private List<CssValueNode> createInput(String value) {
CssValueNode input = mock(CssValueNode.class);
when(input.getValue()).thenReturn(value);
SourceCodeLocation sourceCodeLocation = mock(SourceCodeLocation.class);
when(input.getSourceCodeLocation()).thenReturn(sourceCodeLocation);
return ImmutableList.of(input);
}
private ResourceContext mockResourceContext() {
ResourceContext context = mock(ResourceContext.class);
when(context.getImplementationSimpleSourceName()).thenReturn("ResourceUrlFunctionTest");
GeneratorContext generatorContext = mock(GeneratorContext.class);
TypeOracle oracle = mock(TypeOracle.class);
when(oracle.findType(DataResource.class.getCanonicalName())).thenReturn(dataResourceType);
when(oracle.findType(ImageResource.class.getCanonicalName())).thenReturn(imageResourceType);
when(generatorContext.getTypeOracle()).thenReturn(oracle);
when(context.getGeneratorContext()).thenReturn(generatorContext);
return context;
}
}