blob: 68ef590f7ffd25c464c07cad8763c2679bd01dd1 [file] [log] [blame]
/*
* Copyright 2011 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;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import org.xml.sax.SAXParseException;
/**
* Tests UiBinderWriter validation of UiRender getters and render method.
*/
public class UiRendererValidationTest extends AbstractUiBinderWriterTest {
private static String UI_XML = "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>"
+ "<ui:style field='styleField'>.foo {color:black;}</ui:style>"
+ "<ui:with field='withField' />"
+ " <div ui:field='root'>"
+ " <span ui:field='someField'><ui:text from='{withField.toString}'/></span>"
+ " </div>"
+ "</ui:UiBinder>";
private static String UI_XML_TYPED_WITH = "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>"
+ "<ui:with field='withField' type='foo.Foo' />"
+ " <div ui:field='root'>"
+ " <span ui:field='someField'><ui:text from='{withField.toString}'/></span>"
+ " </div>"
+ "</ui:UiBinder>";
private StringBuffer declaredMethods = new StringBuffer();
public void testAGoodUiRendererInterface() throws UnableToCompleteException, SAXParseException {
declaredMethods.append(" public void render(SafeHtmlBuilder sb, foo.Foo withField);");
declaredMethods.append(" public DivElement getRoot(Element foo);");
declaredMethods.append(" public SpanElement getSomeField(Element bar);");
declaredMethods.append(" public UiStyle getStyleField();");
init(UI_XML, generateRendererResource(declaredMethods));
writer.parseDocument(doc, printWriter);
}
public void testGetterBadParameterType() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public DivElement getRoot(String bar);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to getter parameter not of type Element.",
"Getter getRoot must have exactly one parameter of type assignable to "
+ "com.google.gwt.dom.client.Element in renderer.OwnerClass.Renderer");
}
public void testGetterParameterAssignableToElement()
throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public DivElement getRoot(DivElement bar);");
init(UI_XML, generateRendererResource(declaredMethods));
writer.parseDocument(doc, printWriter);
}
public void testGetterNoParameters() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public DivElement getRoot();");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to getter with no parameters.",
"Field getter getRoot must have exactly one parameter in renderer.OwnerClass.Renderer");
}
public void testStyleGetterWithParameter() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public UiStyle getStyleField(DivElement bar);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to style getter with a parameter.",
"Style getter getStyleField must have no parameters in renderer.OwnerClass.Renderer");
}
public void testGetterTooManyParameters() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public DivElement getRoot(Element parent, Integer i);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to bad getter signature.",
"Field getter getRoot must have exactly one parameter in renderer.OwnerClass.Renderer");
}
public void testGetterUnknownField() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public DivElement getQuux(Element parent);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to getter for an unexpected field name.",
"getQuux does not match a \"ui:field='quux'\" declaration in renderer.OwnerClass.Renderer,"
+ " or 'quux' refers to something other than a ui:style or an HTML element in"
+ " the template");
}
public void testRenderBadReturnType() throws SAXParseException, UnableToCompleteException {
declaredMethods.append(" public String render(SafeHtmlBuilder sb, foo.Foo withField);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to bad render() return type.",
"renderer.OwnerClass.Renderer#render(SafeHtmlBuilder ...) does not return void");
}
public void testRenderExtraParametersOk() throws SAXParseException, UnableToCompleteException {
declaredMethods.append(" public void render("
+ "SafeHtmlBuilder sb, foo.Foo withField, foo.Foo withUnknownField);");
init(UI_XML, generateRendererResource(declaredMethods));
writer.parseDocument(doc, printWriter);
}
public void testRenderMethodRepeated() throws SAXParseException, UnableToCompleteException {
declaredMethods.append(" public void render(SafeHtmlBuilder sb, foo.Foo withField);");
declaredMethods.append(" public void render(SafeHtmlBuilder sb);");
init(UI_XML, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to more than one render method.",
"renderer.OwnerClass.Renderer declares more than one method named render");
}
public void testRenderMissing() throws SAXParseException, UnableToCompleteException {
// No render method here
init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to missing render method.",
"renderer.OwnerClass.Renderer does not declare a render(SafeHtmlBuilder ...) method");
}
public void testRenderNoParameters() throws SAXParseException, UnableToCompleteException {
declaredMethods.append(" public void render();");
init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to render with no parameters.",
"renderer.OwnerClass.Renderer does not declare a render(SafeHtmlBuilder ...) method");
}
public void testRenderNoParametersRepeated() throws SAXParseException, UnableToCompleteException {
declaredMethods.append(" public void render(SafeHtmlBuilder sb, foo.Foo withField);");
declaredMethods.append(" public void render();");
init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to render method repeated.",
"renderer.OwnerClass.Renderer declares more than one method named render");
}
public void testUnknownMethodDeclaration() throws SAXParseException, UnableToCompleteException {
initGetterTest();
declaredMethods.append(" public void quux();");
init(UI_XML_TYPED_WITH, generateRendererResource(declaredMethods));
assertParseFailure("Expected failure due to unexpected method.",
"Unexpected method \"quux\" found in renderer.OwnerClass.Renderer");
}
private void assertParseFailure(String message, String expectedMessage) {
try {
writer.parseDocument(doc, printWriter);
fail(message);
} catch (UnableToCompleteException e) {
if (expectedMessage != null) {
assertEquals(expectedMessage, logger.died);
} else {
fail("No message was received. " + message);
}
}
}
private MockJavaResource generateRendererResource(final StringBuffer declarations) {
return new MockJavaResource("renderer.OwnerClass") {
@Override
public CharSequence getContent() {
StringBuffer code = new StringBuffer();
code.append("package renderer;\n");
code.append("import com.google.gwt.safehtml.shared.SafeHtmlBuilder;\n");
code.append("import com.google.gwt.uibinder.client.UiRenderer;\n");
code.append("import com.google.gwt.dom.client.DivElement;\n");
code.append("import com.google.gwt.dom.client.Element;\n");
code.append("import com.google.gwt.dom.client.SpanElement;\n");
code.append("import foo.Foo;\n");
code.append("import foo.UiStyle;\n");
code.append("public class OwnerClass {");
code.append(" public interface Renderer");
code.append(" extends UiRenderer {");
code.append(declarations);
code.append(" }");
code.append("}");
return code;
}
};
}
private void initGetterTest() {
// Required, not part of test
declaredMethods.append(" public void render(SafeHtmlBuilder sb, foo.Foo withField);");
}
}