Revision: 7185
Author: [email protected]
Date: Wed Nov 25 09:15:38 2009
Log: UiBinder AttributeParsers can now distinguish "" from null

When I revamped AttributeParsing last week, I made it impossible to set
styleName to an empty string. That's a regression.

Attribute parsing has inconsistently made the assumption that setting an
attribute to "" is the same as not setting it. That is, <foo bar=""> ==  
<foo />.
Following that rule during the revamp is part of what lead to this  
bug--turns
out that people already rely on <foo bar=''> causing foo.bar("") to be
generated.

So, this patch makes the parsers consistently return null for a missing
attribute, and "" only when the user actually provides it.

Reviewed by bobv
http://gwt-code-reviews.appspot.com/112812
http://code.google.com/p/google-web-toolkit/source/detail?r=7185

Modified:
   
/trunk/user/src/com/google/gwt/uibinder/attributeparsers/StrictAttributeParser.java
  /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
   
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DisclosurePanelParser.java
   
/trunk/user/src/com/google/gwt/uibinder/elementparsers/LayoutPanelParser.java
  /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
  /trunk/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java
   
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/IntAttributeParserTest.java
   
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/LengthAttributeParserTest.java
   
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/StringAttributeParserTest.java
  /trunk/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java
  /trunk/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
  /trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
  /trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml

=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/attributeparsers/StrictAttributeParser.java
      
Wed Nov 11 22:08:47 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/attributeparsers/StrictAttributeParser.java
      
Wed Nov 25 09:15:38 2009
@@ -82,11 +82,13 @@
     * UnableToCompleteException is thrown.
     */
    public String parse(String value) throws UnableToCompleteException {
-
+    if ("".equals(value.trim())) {
+      logger.die("Cannot use empty value as type %s",  
type.getSimpleSourceName());
+    }
      try {
        return converter.convert(value, new FieldReferenceDelegate(type));
      } catch (IllegalFieldReferenceException e) {
-      logger.die("Cannot parse value: \"%s\"", value);
+      logger.die("Cannot parse value: \"%s\" as type %s", value,  
type.getSimpleSourceName());
        return null; // Unreachable
      }
    }
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java      
 
Mon Nov 16 10:04:26 2009
+++ /trunk/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java      
 
Wed Nov 25 09:15:38 2009
@@ -135,8 +135,8 @@
            writer.die("In %s, class %s has no appropriate set%s() method",  
elem,
                elem.getLocalName(), initialCap(propertyName));
          }
-
-        String value =  
elem.consumeAttributeWithDefault(attribute.getName(),
+        String n = attribute.getName();
+        String value = elem.consumeAttributeWithDefault(n,
              null, getParamTypes(setter));

          if (value == null) {
=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DisclosurePanelParser.java
        
Wed Nov 11 22:08:47 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DisclosurePanelParser.java
        
Wed Nov 25 09:15:38 2009
@@ -68,14 +68,13 @@
        String headerText =  
children.header.consumeInnerTextEscapedAsHtmlStringLiteral(new  
TextInterpreter(
            writer));

-      if (("".equals(openImage) || "".equals(closedImage))
-          && !(openImage.equals(closedImage))) {
+      if ((openImage == null) ^ (closedImage == null)) {
          writer.die("In %s of %s, both %s and %s must be specified, or  
neither",
              children.header, panelElem, OPEN_IMAGE, CLOSED_IMAGE);
        }

        String panelTypeName = type.getQualifiedSourceName();
-      if (!"".equals(openImage)) {
+      if (openImage != null) {
          writer.setFieldInitializer(panelField, String.format(
              "new %s(%s, %s, \"%s\")", panelTypeName, openImage,  
closedImage,
              headerText));
=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/elementparsers/LayoutPanelParser.java   
 
Thu Nov 19 12:57:33 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/elementparsers/LayoutPanelParser.java   
 
Wed Nov 25 09:15:38 2009
@@ -21,7 +21,7 @@
  import com.google.gwt.uibinder.rebind.XMLElement;

  /**
- * Parses {...@link LayoutPanel} widgets.
+ * Parses {...@link com.google.gwt.user.client.ui.LayoutPanel LayoutPanel}  
widgets.
   */
  public class LayoutPanelParser implements ElementParser {

@@ -46,9 +46,9 @@
        writer.addStatement("%1$s.add(%2$s);", fieldName, childFieldName);

        // Parse the horizontal layout constraints.
-      String left = maybeConsumeLengthAttribute(layerElem, "left");
-      String right = maybeConsumeLengthAttribute(layerElem, "right");
-      String width = maybeConsumeLengthAttribute(layerElem, "width");
+      String left = layerElem.consumeLengthAttribute("left");
+      String right = layerElem.consumeLengthAttribute("right");
+      String width = layerElem.consumeLengthAttribute("width");

        if (left != null) {
          if (right != null) {
@@ -73,9 +73,9 @@
        }

        // Parse the vertical layout constraints.
-      String top = maybeConsumeLengthAttribute(layerElem, "top");
-      String bottom = maybeConsumeLengthAttribute(layerElem, "bottom");
-      String height = maybeConsumeLengthAttribute(layerElem, "height");
+      String top = layerElem.consumeLengthAttribute("top");
+      String bottom = layerElem.consumeLengthAttribute("bottom");
+      String height = layerElem.consumeLengthAttribute("height");

        if (top != null) {
          if (bottom != null) {
@@ -111,9 +111,4 @@
      return parent.getNamespaceUri().equals(child.getNamespaceUri())
          && type.equals(child.getLocalName());
    }
-
-  private String maybeConsumeLengthAttribute(XMLElement elem, String name)
-      throws UnableToCompleteException {
-    return elem.hasAttribute(name) ? elem.consumeLengthAttribute(name) :  
null;
-  }
-}
+}
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java      Thu Nov 
 
19 12:57:33 2009
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/XMLElement.java      Wed Nov 
 
25 09:15:38 2009
@@ -204,12 +204,12 @@
     *
     * @param name the attribute's full name (including prefix)
     * @param types the type(s) this attribute is expected to provide
-   * @return the attribute's value as a Java expression, or "" if it is  
not set
+   * @return the attribute's value as a Java expression, or null if it is  
not set
     * @throws UnableToCompleteException on parse failure
     */
    public String consumeAttribute(String name, JType type)
        throws UnableToCompleteException {
-    return consumeAttributeWithDefault(name, "", type);
+    return consumeAttributeWithDefault(name, null, type);
    }

    /**
@@ -234,7 +234,17 @@
     */
    public String consumeAttributeWithDefault(String name, String  
defaultValue,
        JType[] types) throws UnableToCompleteException {
-    return consumeAttributeWithDefault(false, name, defaultValue, types);
+    /*
+     * TODO(rjrjr) The only reason we need the attribute here is for  
getParser,
+     * and getParser only needs it for horrible old  
BundleAttributeParsers. When
+     * that dies, this gets much simpler.
+     */
+    XMLAttribute attribute = getAttribute(name);
+    if (attribute == null) {
+      return defaultValue;
+    }
+    String value = attribute.consumeRawValue();
+    return getParser(attribute, types).parse(value);
    }

    /**
@@ -242,7 +252,7 @@
     * reference.
     *
     * @return an expression that will evaluate to a boolean value in the
-   *         generated code, or "" if there is no such attribute
+   *         generated code, or null if there is no such attribute
     *
     * @throws UnableToCompleteException on unparseable value
     */
@@ -280,7 +290,7 @@
    public Boolean consumeBooleanConstantAttribute(String name)
        throws UnableToCompleteException {
      String value = consumeRawAttribute(name);
-    if ("".equals(value)) {
+    if (value == null) {
        return null;
      }
      if (value.equals("true") || value.equals("false")) {
@@ -333,27 +343,13 @@
      }
      return elements;
    }
-
-  /**
-   * Convenience method for parsing the named attribute as a double value  
or
-   * reference.
-   *
-   * @return a double literal, an expression that will evaluate to a double
-   *         value in the generated code, or "" if there is no such  
attribute
-   *
-   * @throws UnableToCompleteException on unparseable value
-   */
-  public String consumeDoubleAttribute(String name)
-      throws UnableToCompleteException {
-    return consumeAttribute(name, getDoubleType());
-  }

    /**
     * Convenience method for parsing the named attribute as an ImageResource
     * value or reference.
     *
     * @return an expression that will evaluate toan ImageResource value in  
the
-   *         generated code, or "" if there is no such attribute
+   *         generated code, or null if there is no such attribute
     * @throws UnableToCompleteException on unparseable value
     */
    public String consumeImageResourceAttribute(String name)
@@ -449,14 +445,14 @@
     * Convenience method for parsing the named attribute as a CSS length  
value.
     *
     * @return a (double, Unit) pair literal, an expression that will  
evaluate to
-   *         such a pair in the generated code, or "" if there is no such
+   *         such a pair in the generated code, or null if there is no such
     *         attribute
     *
     * @throws UnableToCompleteException on unparseable value
     */
    public String consumeLengthAttribute(String name)
        throws UnableToCompleteException {
-    return consumeAttributeWithDefault(name, "", new JType[] {  
getDoubleType(),
+    return consumeAttributeWithDefault(name, null, new JType[] {  
getDoubleType(),
          getUnitType() });
    }

@@ -498,6 +494,9 @@
     * @return the attribute's value, or ""
     */
    public String consumeRawAttribute(String name) {
+    if (!elem.hasAttribute(name)) {
+      return null;
+    }
      String value = elem.getAttribute(name);
      elem.removeAttribute(name);
      return value.trim();
@@ -513,7 +512,7 @@
     */
    public String consumeRawAttribute(String name, String defaultValue) {
      String value = consumeRawAttribute(name);
-    if ("".equals(value)) {
+    if (value == null) {
        return defaultValue;
      }
      return value;
@@ -526,7 +525,7 @@
     *
     * @param name the attribute's full name (including prefix)
     * @param types the type(s) this attribute is expected to provide
-   * @return the attribute's value as a Java expression, or "" if it is  
not set
+   * @return the attribute's value as a Java expression
     * @throws UnableToCompleteException on parse failure, or if the  
attribute is
     *           empty or unspecified
     */
@@ -551,7 +550,7 @@
     * value or reference.
     *
     * @return a double literal, an expression that will evaluate to a double
-   *         value in the generated code, or "" if there is no such  
attribute
+   *         value in the generated code
     *
     * @throws UnableToCompleteException on unparseable value, or if the  
attribute
     *           is empty or unspecified
@@ -562,12 +561,12 @@
    }

    /**
-   * Consumes the named attribute, or dies if it is missing or empty.
+   * Consumes the named attribute, or dies if it is missing.
     */
    public String consumeRequiredRawAttribute(String name)
        throws UnableToCompleteException {
      String value = consumeRawAttribute(name);
-    if ("".equals(value)) {
+    if (value == null) {
        failRequired(name);
      }
      return value;
@@ -622,7 +621,7 @@
     * reference.
     *
     * @return an expression that will evaluate to a String value in the  
generated
-   *         code, or "" if there is no such attribute
+   *         code, or null if there is no such attribute
     * @throws UnableToCompleteException on unparseable value
     */
    public String consumeStringAttribute(String name)
@@ -760,30 +759,6 @@
    public String toString() {
      return debugString;
    }
-
-  private String consumeAttributeWithDefault(boolean required, String name,
-      String defaultValue, JType[] types) throws UnableToCompleteException  
{
-    /*
-     * TODO(rjrjr) The only reason we need the attribute here is for  
getParser,
-     * and getParser only needs it for horrible old  
BundleAttributeParsers. When
-     * that dies, this gets much simpler.
-     */
-    XMLAttribute attribute = getAttribute(name);
-    if (attribute == null) {
-      if (required) {
-        failRequired(name);
-      }
-      return defaultValue;
-    }
-    String value = attribute.consumeRawValue();
-    if ("".equals(value)) {
-      if (required) {
-        failRequired(name);
-      }
-      return defaultValue;
-    }
-    return getParser(attribute, types).parse(value);
-  }

    private Iterable<XMLElement> consumeChildElementsNoEmptyCheck() {
      try {
=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java     
 
Wed Nov  4 11:14:50 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java     
 
Wed Nov 25 09:15:38 2009
@@ -135,7 +135,7 @@
     */
    public String consumeMessageAttribute(String attName, XMLElement elem) {
      String fullAttName = getMessagesPrefix() + ":" + attName;
-    return elem.consumeRawAttribute(fullAttName);
+    return elem.consumeRawAttribute(fullAttName, "");
    }

    /**
=======================================
---  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/IntAttributeParserTest.java
    
Wed Nov 11 22:08:47 2009
+++  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/IntAttributeParserTest.java
    
Wed Nov 25 09:15:38 2009
@@ -15,8 +15,13 @@
   */
  package com.google.gwt.uibinder.attributeparsers;

+import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.core.ext.UnableToCompleteException;
+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.uibinder.rebind.MortalLogger;
+import com.google.gwt.uibinder.test.UiJavaResources;

  import junit.framework.TestCase;

@@ -29,8 +34,11 @@
    @Override
    public void setUp() throws Exception {
      super.setUp();
-    parser = new IntAttributeParser(new FieldReferenceConverter(null),  
null,
-        MortalLogger.NULL);
+    CompilationState state =  
CompilationStateBuilder.buildFrom(TreeLogger.NULL,
+        UiJavaResources.getUiResources());
+    TypeOracle types = state.getTypeOracle();
+    parser = new IntAttributeParser(new FieldReferenceConverter(null),
+        types.parse("int"), MortalLogger.NULL);
    }

    public void testGood() throws UnableToCompleteException {
=======================================
---  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/LengthAttributeParserTest.java
         
Thu Nov 19 12:57:33 2009
+++  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/LengthAttributeParserTest.java
         
Wed Nov 25 09:15:38 2009
@@ -49,7 +49,7 @@
      DoubleAttributeParser doubleParser = new  
DoubleAttributeParser(converter,
          types.parse("double"), logger);

-    JEnumType enumType = (JEnumType) types.findType(
+    JEnumType enumType = types.findType(
          Unit.class.getCanonicalName()).isEnum();
      EnumAttributeParser enumParser = new EnumAttributeParser(converter,
          enumType, logger);
=======================================
---  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/StringAttributeParserTest.java
         
Wed Nov 11 22:08:47 2009
+++  
/trunk/user/test/com/google/gwt/uibinder/attributeparsers/StringAttributeParserTest.java
         
Wed Nov 25 09:15:38 2009
@@ -25,13 +25,25 @@
  public class StringAttributeParserTest extends TestCase {
    FieldReferenceConverter converter = new FieldReferenceConverter(null);

-  public void testSimple() {
+  public void testSimpleParse() {
+    String before = "snot";
+    String expected = "\"snot\"";
+    assertEquals(expected, converter.convert(before, new  
FieldReferenceDelegate(null)));
+  }
+
+  public void testParseEmpty() {
+    String before = "";
+    String expected = "\"\"";
+    assertEquals(expected, converter.convert(before, new  
FieldReferenceDelegate(null)));
+  }
+
+  public void testSimpleFieldRef() {
      String before = "{able.baker.charlie.prawns}";
      String expected = "\"\" + able.baker().charlie().prawns() + \"\"";
      assertEquals(expected, converter.convert(before, new  
FieldReferenceDelegate(null)));
    }

-  public void testEscaping() {
+  public void testBraceEscaping() {
      String before = "{able.baker.charlie} \"Howdy\nfriend\"  
{prawns.are.yummy}";
      String expected = "\"\" + able.baker().charlie() + \"  
\\\"Howdy\\nfriend\\\" \" + prawns.are().yummy() + \"\"";
      String after = converter.convert(before, new  
FieldReferenceDelegate(null));
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java Mon  
Nov 16 10:04:26 2009
+++ /trunk/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java Wed  
Nov 25 09:15:38 2009
@@ -22,7 +22,6 @@
  import com.google.gwt.dev.javac.CompilationStateBuilder;
  import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
  import com.google.gwt.uibinder.attributeparsers.AttributeParsers;
-import com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers;
  import com.google.gwt.uibinder.elementparsers.NullInterpreter;
  import com.google.gwt.uibinder.test.UiJavaResources;

@@ -66,19 +65,21 @@
    @Override
    public void setUp() throws Exception {
      super.setUp();
-    CompilationState state =  
CompilationStateBuilder.buildFrom(createCompileLogger(),
-        UiJavaResources.getUiResources());
+    CompilationState state = CompilationStateBuilder.buildFrom(
+        createCompileLogger(), UiJavaResources.getUiResources());
      types = state.getTypeOracle();
      logger = new MockMortalLogger();
      elemProvider = new XMLElementProviderImpl(new AttributeParsers(types,  
null,
-        logger), new BundleAttributeParsers(types, logger,  
null, "templatePath",
-            null), types, logger);
+        logger),
+        new  
com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers(
+            types, logger, null, "templatePath", null), types, logger);

      init("<doc><elm attr1=\"attr1Value\" attr2=\"attr2Value\"/></doc>");
    }

    public void testAssertNoAttributes() throws SAXException, IOException {
      init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    assertNull(logger.died);
      try {
        elm.assertNoAttributes();
        fail();
@@ -91,6 +92,7 @@

    public void testAssertNoBody() throws SAXException, IOException {
      init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    assertNull(logger.died);
      try {
        elm.assertNoBody();
        fail();
@@ -101,6 +103,7 @@

    public void testAssertNoText() throws SAXException, IOException {
      init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    assertNull(logger.died);
      try {
        elm.assertNoText();
        fail();
@@ -115,16 +118,17 @@
      init("<doc><elm yes='true' no='false' "
          + "fnord='fnord' ref='{foo.bar.baz}'/></doc>");

-    assertEquals("", elm.consumeBooleanAttribute("foo"));
+    assertNull(elm.consumeBooleanAttribute("foo"));

      assertEquals("true", elm.consumeBooleanAttribute("yes"));
-    assertEquals("", elm.consumeBooleanAttribute("yes"));
+    assertNull(elm.consumeBooleanAttribute("yes"));

      assertEquals("false", elm.consumeBooleanAttribute("no"));
-    assertEquals("", elm.consumeBooleanAttribute("no"));
+    assertNull(elm.consumeBooleanAttribute("no"));

      assertEquals("foo.bar().baz()", elm.consumeBooleanAttribute("ref"));

+    assertNull(logger.died);
      try {
        elm.consumeBooleanAttribute("fnord");
        fail("Should throw UnableToCompleteException on misparse");
@@ -146,8 +150,14 @@
      assertFalse(elm.consumeBooleanConstantAttribute("no"));
      assertNull(elm.consumeBooleanConstantAttribute("no"));

-    assertNull(elm.consumeBooleanConstantAttribute("empty"));
-
+    assertNull(logger.died);
+    try {
+      elm.consumeBooleanConstantAttribute("empty");
+    } catch (UnableToCompleteException c) {
+      assertNotNull(logger.died);
+    }
+
+    logger.died = null;
      try {
        elm.consumeBooleanConstantAttribute("ref");
        fail("Should throw UnableToCompleteException on field ref");
@@ -155,6 +165,7 @@
        assertNotNull(logger.died);
      }

+    logger.died = null;
      try {
        elm.consumeBooleanConstantAttribute("fnord");
        fail("Should throw UnableToCompleteException on misparse");
@@ -180,6 +191,7 @@
      assertEquals("foo.bar().baz()", elm.consumeBooleanAttribute("ref",  
true));
      assertEquals("true", elm.consumeBooleanAttribute("ref", true));

+    assertNull(logger.died);
      try {
        elm.consumeBooleanAttribute("fnord");
        fail("Should throw UnableToCompleteException on misparse");
@@ -191,6 +203,7 @@
    public void testConsumeChildrenNoTextAllowed() throws SAXException,
        IOException {
      init("<doc><elm><child>Hi.</child> Stray text is bad</elm></doc>");
+    assertNull(logger.died);
      try {
        elm.consumeChildElements();
        fail();
@@ -198,30 +211,6 @@
        assertNotNull(logger.died);
      }
    }
-
-  public void testConsumeDouble() throws UnableToCompleteException,
-      SAXException, IOException {
-    init("<doc><elm minus='-123.45' plus='123.45' minus-one='-1' "
-        + "plus-one='1' fnord='fnord' ref='{foo.bar.baz}'  
empty=''/></doc>");
-    assertEquals("1", elm.consumeDoubleAttribute("plus-one"));
-    assertEquals("", elm.consumeDoubleAttribute("plus-one"));
-    assertEquals("-1", elm.consumeDoubleAttribute("minus-one"));
-    assertEquals("", elm.consumeDoubleAttribute("minus-one"));
-    assertEquals("123.45", elm.consumeDoubleAttribute("plus"));
-    assertEquals("", elm.consumeDoubleAttribute("plus"));
-    assertEquals("-123.45", elm.consumeDoubleAttribute("minus"));
-    assertEquals("", elm.consumeDoubleAttribute("minus"));
-    assertEquals("(double)foo.bar().baz()",  
elm.consumeDoubleAttribute("ref"));
-    assertEquals("", elm.consumeDoubleAttribute("ref"));
-    assertEquals("", elm.consumeDoubleAttribute("empty"));
-
-    try {
-      elm.consumeDoubleAttribute("fnord");
-      fail("Should throw UnableToCompleteException on misparse");
-    } catch (UnableToCompleteException c) {
-      assertNotNull(logger.died);
-    }
-  }

    public void testConsumeInnerTextEscapedAsHtmlStringLiteral()
        throws UnableToCompleteException {
@@ -240,7 +229,7 @@

    public void testConsumeRawAttribute() {
      assertEquals("attr1Value", elm.consumeRawAttribute("attr1"));
-    assertEquals("", elm.consumeRawAttribute("attr1"));
+    assertNull(elm.consumeRawAttribute("attr1"));
    }

    public void testConsumeRawAttributeWithDefault() {
@@ -252,6 +241,7 @@

    public void testConsumeRequiredRaw() throws UnableToCompleteException {
      assertEquals("attr1Value", elm.consumeRequiredRawAttribute("attr1"));
+    assertNull(logger.died);
      try {
        elm.consumeRequiredRawAttribute("unsetthing");
        fail("Should have thrown UnableToCompleteException");
@@ -259,7 +249,7 @@
        assertNotNull(logger.died);
      }
    }
-
+
    public void testConsumeRequired() throws UnableToCompleteException {
      assertEquals("\"attr1Value\"", elm.consumeRequiredAttribute("attr1",
          types.findType("java.lang.String")));
@@ -273,8 +263,10 @@
      assertEquals("-1", elm.consumeRequiredDoubleAttribute("minus-one"));
      assertEquals("123.45", elm.consumeRequiredDoubleAttribute("plus"));
      assertEquals("-123.45", elm.consumeRequiredDoubleAttribute("minus"));
-    assertEquals("(double)foo.bar().baz()",  
elm.consumeRequiredDoubleAttribute("ref"));
-
+    assertEquals("(double)foo.bar().baz()",
+        elm.consumeRequiredDoubleAttribute("ref"));
+
+    assertNull(logger.died);
      try {
        elm.consumeRequiredDoubleAttribute("fnord");
        fail("Should throw UnableToCompleteException on misparse");
@@ -282,6 +274,7 @@
        assertNotNull(logger.died);
      }

+    logger.died = null;
      try {
        elm.consumeRequiredDoubleAttribute("plus-one");
        fail("Should throw UnableToCompleteException consumed attribute");
@@ -289,6 +282,7 @@
        assertNotNull(logger.died);
      }

+    logger.died = null;
      try {
        elm.consumeRequiredDoubleAttribute("empty");
        fail("Should throw UnableToCompleteException on no such attribute");
@@ -299,6 +293,7 @@

    public void testConsumeSingleChildElementEmpty() throws SAXException,
        IOException, UnableToCompleteException {
+    assertNull(logger.died);
      try {
        elm.consumeSingleChildElement();
        fail("Should throw on single child element");
@@ -310,7 +305,9 @@
      assertEquals("Hi.",
          elm.consumeSingleChildElement().consumeUnescapedInnerText());

+    logger.died = null;
      init("<doc><elm  
id='elm'><child>Hi.</child><child>Ho.</child></elm></doc>");
+    assertNull(logger.died);
      try {
        elm.consumeSingleChildElement();
        fail("Should throw on too many children");
@@ -329,8 +326,8 @@
      assertEquals("", elm.consumeUnescapedInnerText());
    }

-  public void testEmptyStringOnMissingAttribute() {
-    assertEquals("", elm.consumeRawAttribute("fnord"));
+  public void testNullOnMissingAttribute() {
+    assertNull(elm.consumeRawAttribute("fnord"));
    }

    public void testIterator() {
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java      
 
Wed Nov 25 07:45:15 2009
+++ /trunk/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java      
 
Wed Nov 25 09:15:38 2009
@@ -224,6 +224,10 @@
      assertEquals("They might show up in body text that has been marked  
for "
          + "translation: funny characters \" \" ' ' & < > > { }", t);
    }
+
+  public void testEmptyAttributesOkay() {
+    assertEquals("", widgetUi.styleLess.getStyleName());
+  }

    public void testMixOfWidgetsAndElementsInUiMsg() {
      assertEquals("single translatable message",  
widgetUi.mixedMessageWidget.getText());
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java     
 
Wed Nov 25 07:45:15 2009
+++ /trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java     
 
Wed Nov 25 09:15:38 2009
@@ -34,6 +34,7 @@
  import com.google.gwt.user.client.ui.Composite;
  import com.google.gwt.user.client.ui.DisclosurePanel;
  import com.google.gwt.user.client.ui.DockPanel;
+import com.google.gwt.user.client.ui.HTML;
  import com.google.gwt.user.client.ui.HTMLPanel;
  import com.google.gwt.user.client.ui.HasHTML;
  import com.google.gwt.user.client.ui.Image;
@@ -143,14 +144,15 @@
    @UiField FooLabel objectBooleanIntoPrimitive;
    @UiField FooLabel allObjectBoolean;
    @UiField FooLabel allPrimitiveBoolean;
-  @UiField(provided = true)
+  @UiField(provided = true) @SuppressWarnings("uibinder")
    FakeBundle2 legacyValuesForBeans = new FakeBundle2();
-  @UiField(provided = true)
+  @UiField(provided = true) @SuppressWarnings("uibinder")
    FakeBundle3 legacyValuesForHtml = new FakeBundle3();
    @UiField Label bundledLabelLegacy;
    @UiField DivElement bundledDivLegacy;
    @UiField ToggleButton toggle;
-
+  @UiField HTML styleLess;
+
    public WidgetBasedUi() {
      external.style().ensureInjected();
      initWidget(binder.createAndBindUi(this));
=======================================
---  
/trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml       
 
Wed Nov 25 07:45:15 2009
+++  
/trunk/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml       
 
Wed Nov 25 09:15:38 2009
@@ -140,7 +140,7 @@

  <gwt:DockPanel ui:field="root" width="100%" verticalAlignment="ALIGN_TOP">
    <gwt:Dock direction='NORTH'>
-    <gwt:HTML>
+    <gwt:HTML ui:field='styleLess' styleName=''>
        <div style='border: 4px solid gray; padding: 4px; margin: 4px;'>
          <img src='http://www.google.com/images/logo_sm.gif' alt="logo" />
          <span ui:field="trimmedMessage"><ui:msg description='"title" of  
the doc'

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to