blob: b79a637a5c0fb83b5a4951866953e0afd04453fa [file] [log] [blame]
/*
* Copyright 2009 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.uibinder.rebind.model;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.rebind.MortalLogger;
import com.google.gwt.uibinder.rebind.UiBinderContext;
import com.google.gwt.uibinder.test.UiJavaResources;
import junit.framework.TestCase;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Tests for the owner class descriptor.
*/
public class OwnerClassTest extends TestCase {
private static TreeLogger createCompileLogger() {
PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
System.err, true));
logger.setMaxDetail(TreeLogger.ERROR);
return logger;
}
private TypeOracle types;
private JClassType labelType;
private JClassType buttonType;
private JClassType clickEventType;
private JClassType mouseOverEventType;
private UiBinderContext uiBinderCtx;
@Override
protected void setUp() throws Exception {
super.setUp();
CompilationState state = CompilationStateBuilder.buildFrom(
createCompileLogger(), getJavaResources());
types = state.getTypeOracle();
uiBinderCtx = new UiBinderContext();
labelType = types.findType("com.google.gwt.user.client.ui.Label");
buttonType = types.findType("com.google.gwt.user.client.ui.Button");
clickEventType = types.findType("com.google.gwt.event.dom.client.ClickEvent");
mouseOverEventType = types.findType("com.google.gwt.event.dom.client.MouseOverEvent");
}
private Set<Resource> getJavaResources() {
MockJavaResource[] javaFiles = {
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.EmptyOwnerClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("public class EmptyOwnerClass {\n");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.BadUiFactoryClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("public class BadUiFactoryClass {\n");
code.append(" @UiFactory int thisShouldntWork() { return 0; }\n");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.UiFieldsClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.user.client.ui.Button;\n");
code.append("import com.google.gwt.user.client.ui.Label;\n");
code.append("import com.google.gwt.uibinder.client.UiField;\n");
code.append("public class UiFieldsClass {\n");
code.append(" @UiField Label label1;");
code.append(" @UiField(provided=true) Button button1;");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.UiHandlersClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.event.dom.client.ClickEvent;\n");
code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n");
code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
code.append("public class UiHandlersClass {\n");
code.append(" @UiHandler(\"myField\") void onMyFieldClicked(ClickEvent ev) {}");
code.append(" @UiHandler( {\"myField\", \"myOtherField\"}) void onMouseOver(MouseOverEvent ev){}");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.BadUiFieldsClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiField;\n");
code.append("public class BadUiFieldsClass {\n");
code.append(" @UiField int thisShouldntWork;");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.UiFactoryClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("import com.google.gwt.user.client.ui.Label;\n");
code.append("public class UiFactoryClass {");
code.append(" @UiFactory");
code.append(" Label createLabel() { return null; }");
code.append("}\n");
return code;
}
},
new MockJavaResource("com.google.gwt.uibinder.rebind.model.Abstract") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("public class Abstract<T> {");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("public class WildcardWidgetFactory {");
code.append(" @UiFactory");
code.append(" Abstract<?> createOne() { return null; }");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("public class ParamterizedWidgetFactory {");
code.append(" @UiFactory");
code.append(" Abstract<String> createOne() { return null; }");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.TooManyGenerics") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("public class TooManyGenerics {");
code.append(" @UiFactory");
code.append(" Abstract<?> createSomething() { return null; }");
code.append(" @UiFactory");
code.append(" Abstract<String> createStringThing() { return null; }");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("import com.google.gwt.user.client.ui.Label;\n");
code.append("public class DuplicateUiFactoryClass {");
code.append(" @UiFactory");
code.append(" Label labelFactory1() { return null; }");
code.append(" @UiFactory");
code.append(" Label labelFactory2() { return null; }");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.ParentUiBinderClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n");
code.append("import com.google.gwt.uibinder.client.UiField;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
code.append("import com.google.gwt.user.client.ui.Label;\n");
code.append("public class ParentUiBinderClass {");
code.append(" @UiField Label label1;");
code.append(" @UiFactory Label createLabel() { return null; }");
code.append(" @UiHandler(\"label1\")");
code.append(" void onLabelMouseOver(MouseOverEvent e) { }");
code.append("}\n");
return code;
}
},
new MockJavaResource(
"com.google.gwt.uibinder.rebind.model.ChildUiBinderClass") {
@Override
protected CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.uibinder.rebind.model;\n");
code.append("import com.google.gwt.event.dom.client.ClickEvent;\n");
code.append("import com.google.gwt.uibinder.client.UiField;\n");
code.append("import com.google.gwt.uibinder.client.UiFactory;\n");
code.append("import com.google.gwt.uibinder.client.UiHandler;\n");
code.append("import com.google.gwt.user.client.ui.Button;\n");
code.append("public class ChildUiBinderClass extends ParentUiBinderClass {");
code.append(" @UiField(provided = true) Button button1;");
code.append(" @UiFactory Button createButton() { return null; }");
code.append(" @UiHandler(\"button1\")");
code.append(" void onButtonClicked(ClickEvent e) { }");
code.append("}\n");
return code;
}
},};
Set<Resource> rtn = new HashSet<Resource>(UiJavaResources.getUiResources());
rtn.addAll(Arrays.asList(javaFiles));
return rtn;
}
@SuppressWarnings("deprecation")
public void testOwnerClass_empty() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.EmptyOwnerClass");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
assertNull(ownerClass.getUiFactoryMethod(labelType));
assertNull(ownerClass.getUiField("fieldName"));
assertNull(ownerClass.getUiFieldForType(labelType));
assertTrue(ownerClass.getUiFields().isEmpty());
assertTrue(ownerClass.getUiHandlers().isEmpty());
}
public void testOwnerClass_uiFactory() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFactoryClass");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
assertNotNull(uiFactoryMethod);
assertEquals("createLabel", uiFactoryMethod.getName());
assertEquals(labelType, uiFactoryMethod.getReturnType());
JParameter[] parameters = uiFactoryMethod.getParameters();
assertNotNull(parameters);
assertEquals(0, parameters.length);
}
public void testParameterizedWidgets() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory");
JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
JMethod expected = ownerType.findMethod("createOne", new JType[] {});
JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType);
assertEquals(expected, uiFactoryMethod);
}
public void testWildcardWidgets() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory");
JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
JMethod expected = ownerType.findMethod("createOne", new JType[] {});
JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType);
assertEquals(expected, uiFactoryMethod);
}
public void testHowSuckyWeReallyAreWithGenerics() {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.TooManyGenerics");
try {
new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
fail();
} catch (UnableToCompleteException e) {
/* pass */
}
}
public void testOwnerClass_uiFactoryBadType() {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFactoryClass");
try {
new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
fail("Expected exception not thrown.");
} catch (UnableToCompleteException utce) {
// Expected
}
}
public void testOwnerClass_uiFactoryDuplicateType() {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass");
try {
new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
fail("Expected exception not thrown.");
} catch (UnableToCompleteException utce) {
// Expected
}
}
@SuppressWarnings("deprecation")
public void testOwnerClass_uiFields() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFieldsClass");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
OwnerField labelField = ownerClass.getUiField("label1");
OwnerField labelField2 = ownerClass.getUiFieldForType(labelType);
assertNotNull(labelField);
assertNotNull(labelField2);
assertEquals(labelField, labelField2);
assertFalse(labelField.isProvided());
assertEquals(labelType, labelField.getType().getRawType());
assertEquals("label1", labelField.getName());
OwnerField buttonField = ownerClass.getUiField("button1");
OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType);
assertNotNull(buttonField);
assertNotNull(buttonField2);
assertEquals(buttonField, buttonField2);
assertTrue(buttonField.isProvided());
assertEquals(buttonType, buttonField.getType().getRawType());
assertEquals("button1", buttonField.getName());
Collection<OwnerField> uiFields = ownerClass.getUiFields();
Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields);
Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>();
expectedFieldSet.add(labelField);
expectedFieldSet.add(buttonField);
assertEquals(expectedFieldSet, uiFieldSet);
}
public void testOwnerClass_uiFieldsBadType() {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFieldsClass");
try {
new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx);
fail("Expected exception not thrown.");
} catch (UnableToCompleteException utce) {
// Expected
}
}
public void testOwnerClass_uiHandlers() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiHandlersClass");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
// Assert the two expected handlers are there
List<JMethod> uiHandlers = ownerClass.getUiHandlers();
assertEquals(2, uiHandlers.size());
JMethod clickMethod = null, mouseOverMethod = null;
// Don't care about ordering
for (JMethod method : uiHandlers) {
if (method.getName().equals("onMyFieldClicked")) {
clickMethod = method;
} else if (method.getName().equals("onMouseOver")) {
mouseOverMethod = method;
}
}
assertNotNull(clickMethod);
assertNotNull(mouseOverMethod);
// Check the click handler
JParameter[] clickParams = clickMethod.getParameters();
assertEquals(1, clickParams.length);
assertEquals(clickEventType, clickParams[0].getType());
assertTrue(clickMethod.isAnnotationPresent(UiHandler.class));
UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class);
String[] clickFields = clickAnnotation.value();
assertEquals(1, clickFields.length);
assertEquals("myField", clickFields[0]);
// Check the mouse over handler
JParameter[] mouseOverParams = mouseOverMethod.getParameters();
assertEquals(1, mouseOverParams.length);
assertEquals(mouseOverEventType, mouseOverParams[0].getType());
assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class));
UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class);
String[] mouseOverFields = mouseOverAnnotation.value();
assertEquals(2, mouseOverFields.length);
assertEquals("myField", mouseOverFields[0]);
assertEquals("myOtherField", mouseOverFields[1]);
}
@SuppressWarnings("deprecation")
public void testOwnerClass_withParent() throws UnableToCompleteException {
JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ChildUiBinderClass");
OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL,
uiBinderCtx);
// Test fields
OwnerField labelField = ownerClass.getUiField("label1");
OwnerField labelField2 = ownerClass.getUiFieldForType(labelType);
assertNotNull(labelField);
assertNotNull(labelField2);
assertEquals(labelField, labelField2);
assertFalse(labelField.isProvided());
assertEquals(labelType, labelField.getType().getRawType());
assertEquals("label1", labelField.getName());
OwnerField buttonField = ownerClass.getUiField("button1");
OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType);
assertNotNull(buttonField);
assertNotNull(buttonField2);
assertEquals(buttonField, buttonField2);
assertTrue(buttonField.isProvided());
assertEquals(buttonType, buttonField.getType().getRawType());
assertEquals("button1", buttonField.getName());
Collection<OwnerField> uiFields = ownerClass.getUiFields();
Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields);
Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>();
expectedFieldSet.add(labelField);
expectedFieldSet.add(buttonField);
assertEquals(expectedFieldSet, uiFieldSet);
// Test factories
JMethod labelFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
assertNotNull(labelFactoryMethod);
assertEquals("createLabel", labelFactoryMethod.getName());
assertEquals(labelType, labelFactoryMethod.getReturnType());
JParameter[] labelParams = labelFactoryMethod.getParameters();
assertNotNull(labelParams);
assertEquals(0, labelParams.length);
JMethod buttonFactoryMethod = ownerClass.getUiFactoryMethod(labelType);
assertNotNull(buttonFactoryMethod);
assertEquals("createLabel", buttonFactoryMethod.getName());
assertEquals(labelType, buttonFactoryMethod.getReturnType());
JParameter[] buttonParams = buttonFactoryMethod.getParameters();
assertNotNull(buttonParams);
assertEquals(0, buttonParams.length);
// Test handlers
List<JMethod> uiHandlers = ownerClass.getUiHandlers();
assertEquals(2, uiHandlers.size());
JMethod clickMethod = null, mouseOverMethod = null;
for (JMethod method : uiHandlers) {
if (method.getName().equals("onButtonClicked")) {
clickMethod = method;
} else if (method.getName().equals("onLabelMouseOver")) {
mouseOverMethod = method;
}
}
assertNotNull(clickMethod);
assertNotNull(mouseOverMethod);
JParameter[] clickParams = clickMethod.getParameters();
assertEquals(1, clickParams.length);
assertEquals(clickEventType, clickParams[0].getType());
assertTrue(clickMethod.isAnnotationPresent(UiHandler.class));
UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class);
String[] clickFields = clickAnnotation.value();
assertEquals(1, clickFields.length);
assertEquals("button1", clickFields[0]);
JParameter[] mouseOverParams = mouseOverMethod.getParameters();
assertEquals(1, mouseOverParams.length);
assertEquals(mouseOverEventType, mouseOverParams[0].getType());
assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class));
UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class);
String[] mouseOverFields = mouseOverAnnotation.value();
assertEquals(1, mouseOverFields.length);
assertEquals("label1", mouseOverFields[0]);
}
}