Package com.google.gdt.eclipse.designer.uibinder.model.widgets

Source Code of com.google.gdt.eclipse.designer.uibinder.model.widgets.WidgetTest

/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* 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.gdt.eclipse.designer.uibinder.model.widgets;

import com.google.gdt.eclipse.designer.core.GTestUtils;
import com.google.gdt.eclipse.designer.model.widgets.support.GwtState;
import com.google.gdt.eclipse.designer.uibinder.IExceptionConstants;
import com.google.gdt.eclipse.designer.uibinder.model.UiBinderModelTest;

import org.eclipse.wb.core.model.broadcast.EditorActivatedListener;
import org.eclipse.wb.core.model.broadcast.EditorActivatedRequest;
import org.eclipse.wb.draw2d.geometry.Rectangle;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.util.PropertyUtils;
import org.eclipse.wb.internal.core.utils.exception.DesignerException;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.xml.model.XmlObjectInfo;
import org.eclipse.wb.internal.core.xml.model.description.ComponentDescription;
import org.eclipse.wb.tests.designer.Expectations;
import org.eclipse.wb.tests.designer.Expectations.RectValue;
import org.eclipse.wb.tests.designer.core.annotations.DisposeProjectAfter;

import org.eclipse.jdt.core.IType;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;

import static org.fest.assertions.Assertions.assertThat;

/**
* Test for {@link WidgetInfo}.
*
* @author scheglov_ke
*/
public class WidgetTest extends UiBinderModelTest {
  ////////////////////////////////////////////////////////////////////////////
  //
  // Exit zone :-) XXX
  //
  ////////////////////////////////////////////////////////////////////////////
  public void _test_exit() throws Exception {
    System.exit(0);
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Tests
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * We should check that GWT includes patches for UiBinder support in GWT Designer.
   */
  @DisposeProjectAfter
  public void test_wrongVersion() throws Exception {
    configureForGWT_version(GTestUtils.getLocation_20());
    // parse will fail because GWT 2.0.4 does not support UiBinder WYSIWYG
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel/>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.WRONG_VERSION, e.getCode());
    }
  }

  /**
   * Test (not direct, will be checked after test class) that {@link GwtState} is disposed even if
   * GWT module definition was incorrect.
   */
  @DisposeProjectAfter
  public void test_wrongModule() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/Module.gwt.xml",
        getSourceDQ(
            "<!-- filler filler filler filler filler -->",
            "<!-- filler filler filler filler filler -->",
            "<module>",
            "  <badTagName/>",
            "</module>"));
    // parse will fail because of wrong module
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel/>",
          "</ui:UiBinder>");
    } catch (Throwable e) {
      assertEquals("com.google.gwt.core.ext.UnableToCompleteException", e.getClass().getName());
    }
  }

  public void test_emptyFlowPanel() throws Exception {
    WidgetInfo panel =
        parse(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>");
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
    refresh();
    //
    assertEquals(new Rectangle(0, 0, 450, 300), panel.getBounds());
  }

  public void test_FlowPanel_withButton() throws Exception {
    WidgetInfo panel =
        parse(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel>",
            "    <g:Button wbp:name='button' text='AAA'/>",
            "  </g:FlowPanel>",
            "</ui:UiBinder>");
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>",
        "  <g:Button wbp:name='button' text='AAA'>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // bounds
    assertEquals(new Rectangle(0, 0, 450, 300), panel.getBounds());
    {
      Rectangle expected =
          Expectations.get(
              new Rectangle(0, 0, 49, 24),
              new RectValue[]{new RectValue("scheglov-macpro", new Rectangle(0, 0, 49, 26))});
      assertEquals(expected, button.getBounds());
    }
    // property value
    assertEquals("AAA", button.getPropertyByTitle("text").getValue());
  }

  /**
   * Test that <code>HasHTML.setHTML(String)</code> has nice title "html", not just default "hTML".
   */
  public void test_setHTML() throws Exception {
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:Button wbp:name='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    WidgetInfo button = getObjectByName("button");
    // "html" property
    assertNotNull(button.getPropertyByTitle("html"));
    assertNull(button.getPropertyByTitle("hTML"));
    assertNull(button.getPropertyByTitle("HTML"));
    // set value
    button.getPropertyByTitle("html").setValue("newValue");
    assertXML(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:Button wbp:name='button'>newValue</g:Button>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
  }

  /**
   * For property "width" there are no getter, so it will has value only it remembered as attribute
   * value. See {@link XmlObjectInfo#registerAttributeValue(String, Object)}.
   */
  public void test_propertyValue() throws Exception {
    parse(
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:Button wbp:name='button' width='5cm'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // property value
    assertEquals("5cm", button.getPropertyByTitle("width").getValue());
  }

  /**
   * UiBinder templates use "UTF-8" charset, so we should use this encoding for values.
   */
  public void test_setPropertyValue_UTF8() throws Exception {
    parse(
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:Button wbp:name='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // XML model should use "UTF-8"
    assertEquals("UTF-8", button.getElement().getModel().getCharset());
    // set value
    button.getPropertyByTitle("text").setValue("\u0410\u0411\u0412");
    assertXML(
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:Button wbp:name='button' text='\u0410\u0411\u0412'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
  }

  /**
   * "PushButton" has "setDown()" method, but it is protected, so we should not create
   * {@link Property} for it.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47725
   */
  public void test_noPropertyForProtectedMethod() throws Exception {
    parse(
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:PushButton wbp:name='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // no "down" property
    String[] propertyTitles = PropertyUtils.getTitles(button.getProperties());
    assertThat(propertyTitles).excludes("down");
  }

  /**
   * "TextBox" has "setDirectionEstimator(boolean)" and "setDirectionEstimator(DirectionEstimator)"
   * methods, but UiBinder does not allow such ambiguous setters, so we should not create
   * {@link Property} for it.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47769
   */
  public void test_noAmbiguousProperties() throws Exception {
    parse(
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <g:TextBox wbp:name='textBox'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo textBox = getObjectByName("textBox");
    // no "directionEstimator" property
    String[] propertyTitles = PropertyUtils.getTitles(textBox.getProperties());
    assertThat(propertyTitles).excludes("directionEstimator", "directionEstimator(boolean)");
  }

  /**
   * Test that custom widget can be rendered as "root".
   */
  public void test_customWidget() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/MyPanel.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "public class MyPanel extends FlowPanel {",
            "  public MyPanel() {",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    WidgetInfo panel =
        parse(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <t:MyPanel/>",
            "</ui:UiBinder>");
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<t:MyPanel>");
    refresh();
    //
    assertEquals("test.client.MyPanel", panel.getObject().getClass().getName());
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // @UiField rendering
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Test that for GWT before 2.1.1 we don't support @UiField(provided=true).
   */
  @DisposeProjectAfter
  public void test_UiField_noProvidedSupport() throws Exception {
    configureForGWT_version(GTestUtils.getLocation_2_1_0());
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) Button button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel>",
          "    <g:Button wbp:name='button' ui:field='button'/>",
          "  </g:FlowPanel>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.UI_FIELD_FACTORY_FEATURE, e.getCode());
    }
  }

  /**
   * Test that we support @UiField(provided=true).
   * <p>
   * {@link ComponentDescription} provides special "UiBinder.createInstance" creation script.
   */
  @DisposeProjectAfter
  public void test_UiField_useScript() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "    setText(text);",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/MyButton.wbp-component.xml",
        getSourceDQ(
            "<component xmlns='http://www.eclipse.org/wb/WBPComponent'>",
            "  <parameters>",
            "    <parameter name='UiBinder.createInstance'>new test.client.MyButton('abc')</parameter>",
            "  </parameters>",
            "</component>"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) MyButton button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button' ui:field='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals("abc", ReflectionUtils.invokeMethod(buttonObject, "getText()"));
  }

  /**
   * Test that we support @UiField(provided=true).
   * <p>
   * Has default constructor, so use it.
   */
  @DisposeProjectAfter
  public void test_UiField_useDefaultConstructor() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton() {",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) MyButton button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button' ui:field='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    assertEquals("test.client.MyButton", button.getObject().getClass().getName());
  }

  /**
   * Test that we support @UiField(provided=true).
   * <p>
   * Has default constructor, so use it. But it causes exception, show it in good way.
   */
  @DisposeProjectAfter
  public void test_UiField_useDefaultConstructor_causesException() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton() {",
            "    throw new Error();",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) MyButton button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel>",
          "    <t:MyButton wbp:name='button' ui:field='button'/>",
          "  </g:FlowPanel>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.UI_FIELD_EXCEPTION, e.getCode());
    }
  }

  /**
   * Test that we support @UiField(provided=true).
   * <p>
   * No default constructor, so use shortest constructor with default values as arguments.
   */
  @DisposeProjectAfter
  public void test_UiField_useConstructor_defaultArguments() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "    setText(text);",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) MyButton button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button' ui:field='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals("<dynamic>", ReflectionUtils.invokeMethod(buttonObject, "getText()"));
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // @UiFactory rendering
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Test that for GWT before 2.1.1 we don't support @UiFactory.
   */
  @DisposeProjectAfter
  public void test_UiFactory_noSupport() throws Exception {
    configureForGWT_version(GTestUtils.getLocation_2_1_0());
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiFactory Button fooMethod() {",
            "    return new Button();",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel>",
          "    <g:Button wbp:name='button'/>",
          "  </g:FlowPanel>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.UI_FIELD_FACTORY_FEATURE, e.getCode());
    }
  }

  /**
   * Test that we support @UiFactory.
   * <p>
   * {@link ComponentDescription} provides special "UiBinder.createInstance" creation script.
   */
  @DisposeProjectAfter
  public void test_UiFactory_useScript() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "    setText(text);",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/MyButton.wbp-component.xml",
        getSourceDQ(
            "<component xmlns='http://www.eclipse.org/wb/WBPComponent'>",
            "  <parameters>",
            "    <parameter name='UiBinder.createInstance'>",
            "      new test.client.MyButton(args[0] + ':' + args[1])",
            "    </parameter>",
            "  </parameters>",
            "</component>"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiFactory MyButton fooMethod(String text, int level) {",
            "    return new MyButton(text + level);",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button' text='abc' level='2'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals("abc:2", ReflectionUtils.invokeMethod(buttonObject, "getText()"));
  }

  /**
   * Test that we support @UiFactory.
   * <p>
   * Has default constructor, so use it.
   */
  @DisposeProjectAfter
  public void test_UiFactory_useDefaultConstructor() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiFactory MyButton fooMethod() {",
            "    return new MyButton('abc');",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals("", ReflectionUtils.invokeMethod(buttonObject, "getText()"));
  }

  /**
   * Test that we support @UiFactory.
   * <p>
   * Has default constructor, so use it. But it causes exception, show it in good way.
   */
  @DisposeProjectAfter
  public void test_UiFactory_useDefaultConstructor_causesException() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "    throw new Error();",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiFactory MyButton fooMethod() {",
            "    return new MyButton('abc');",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel>",
          "    <t:MyButton wbp:name='button'/>",
          "  </g:FlowPanel>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.UI_FACTORY_EXCEPTION, e.getCode());
    }
  }

  /**
   * Test that we support @UiFactory.
   * <p>
   * No default constructor, so use shortest constructor with default values as arguments.
   */
  @DisposeProjectAfter
  public void test_UiFactory_useConstructor_defaultArguments() throws Exception {
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(String text) {",
            "    setText(text);",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiFactory MyButton fooMethod() {",
            "    return new MyButton('abc');",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals("<dynamic>", ReflectionUtils.invokeMethod(buttonObject, "getText()"));
  }

  /**
   * Test that we support @UiField(provided=true).
   * <p>
   * Use constructor, but try also "INSTANCE" field for argument types.
   */
  @DisposeProjectAfter
  public void test_UiField_useConstructor_fieldInstance() throws Exception {
    setFileContentSrc(
        "test/client/MyParameter.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyParameter {",
            "  static MyParameter INSTANCE = new MyParameter();",
            "}"));
    setFileContentSrc(
        "test/client/MyButton.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyButton extends Button {",
            "  public MyButton(MyParameter parameter) {",
            "    setEnabled(parameter != null);",
            "  }",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  @UiField(provided=true) MyButton button;",
            "}"));
    waitForAutoBuild();
    // parse
    dontUseSharedGWTState();
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel>",
        "    <t:MyButton wbp:name='button' ui:field='button'/>",
        "  </g:FlowPanel>",
        "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // we have actual object
    Object buttonObject = button.getObject();
    assertEquals("test.client.MyButton", buttonObject.getClass().getName());
    assertEquals(true, ReflectionUtils.invokeMethod(buttonObject, "isEnabled()"));
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Binder interface
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * There was shortcut - use always "Binder" class. It seems that sometimes user use different
   * names.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47575
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_differentName() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "public class Test extends Composite {",
            "  interface MyTemplate extends UiBinder<Widget, Test> {}",
            "  private static final MyTemplate binder = GWT.create(MyTemplate.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel/>",
        "</ui:UiBinder>");
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * We should support @UiTemplate annotation.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47917
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_UiTemplate_localName() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "public class Test extends Composite {",
            "  @UiTemplate('MyTemplate.ui.xml')",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    _parse(
        "src/test/client/MyTemplate.ui.xml",
        getTestSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>"));
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * We should support @UiTemplate annotation.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47917
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_UiTemplate_qualifiedName() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "public class Test extends Composite {",
            "  @UiTemplate('test.client.templates.MyTemplate.ui.xml')",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    _parse(
        "src/test/client/templates/MyTemplate.ui.xml",
        getTestSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>"));
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * If there is {@link IType} with same name as template, but it has NOT "Binder" interface, then
   * we should not fail and should try to find @UiTemplate annotation.
   * <p>
   * https://groups.google.com/forum/#!topic/google-web-toolkit/gfc0Ggft9iA
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_UiTemplate_hasFormInterface() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/MyTemplate.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class MyTemplate {",
            "}"));
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "public class Test extends Composite {",
            "  @UiTemplate('MyTemplate.ui.xml')",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    _parse(
        "src/test/client/MyTemplate.ui.xml",
        getTestSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>"));
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * We should support opening <code>*.ui.xml</code> templates in Maven "resources" folder.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47855
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_maven() throws Exception {
    dontUseSharedGWTState();
    GTestUtils.configureMavenProject();
    // prepare Java source
    setFileContent(
        "src/main/java/test/client/Test.java",
        getJavaSource(
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    _parse(
        "src/main/resources/test/client/Test.ui.xml",
        getTestSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>"));
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * Test for case when there are no "companion" form class.
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_noForm() throws Exception {
    dontUseSharedGWTState();
    getFileSrc("test/client/Test.java").delete(true, null);
    waitForAutoBuild();
    // parse
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel/>",
          "</ui:UiBinder>");
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NO_FORM_TYPE, e.getCode());
    }
  }

  /**
   * Test for case when there are no "Binder" class.
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_noBinder() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "public class Test extends Composite {",
            "  public Test() {",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <g:FlowPanel/>",
          "</ui:UiBinder>");
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NO_FORM_TYPE, e.getCode());
    }
  }

  /**
   * We should support @UiTemplate annotation, even for Binder in inner class.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?48532
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_inInnerClass() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "public class Test extends PopupPanel {",
            "  public static class InfoWidget extends Composite {",
            "    @UiTemplate('MyTemplate.ui.xml')",
            "    interface Binder extends UiBinder<Widget, InfoWidget> {}",
            "    private static final Binder binder = GWT.create(Binder.class);",
            "    public InfoWidget() {",
            "      initWidget(binder.createAndBindUi(this));",
            "    }",
            "  }",
            "}",
            ""));
    waitForAutoBuild();
    // parse
    _parse(
        "src/test/client/MyTemplate.ui.xml",
        getTestSource(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel/>",
            "</ui:UiBinder>"));
    assertHierarchy(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<g:FlowPanel>");
  }

  /**
   * Some users try to open "html" file in "war", which is not in Java package.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47654
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_notInPackage() throws Exception {
    try {
      _parse(
          "war/Test.ui.xml",
          getTestSource(
              "// filler filler filler filler filler",
              "// filler filler filler filler filler",
              "<ui:UiBinder>",
              "  <g:FlowPanel/>",
              "</ui:UiBinder>"));
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NO_FORM_PACKAGE, e.getCode());
    }
  }

  /**
   * Some users try to open "ui.xml" file in project root.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?48266
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_notPackage_inProjectRoot() throws Exception {
    try {
      _parse(
          "Test.ui.xml",
          getTestSource(
              "// filler filler filler filler filler",
              "// filler filler filler filler filler",
              "<ui:UiBinder>",
              "  <g:FlowPanel/>",
              "</ui:UiBinder>"));
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NO_FORM_PACKAGE, e.getCode());
    }
  }

  /**
   * Some users try to open "ui.xml" file in source folder.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?48312
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_notPackage_inSourceFolder() throws Exception {
    try {
      _parse(
          "src/Test.ui.xml",
          getTestSource(
              "// filler filler filler filler filler",
              "// filler filler filler filler filler",
              "<ui:UiBinder>",
              "  <g:FlowPanel/>",
              "</ui:UiBinder>"));
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NO_FORM_PACKAGE, e.getCode());
    }
  }

  /**
   * Some users try to open "ui.xml" file which is directly in module package, not in client
   * package. This can not work because we will not able to load "UiBinder" interface from this non
   * client package.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?48156
   */
  @DisposeProjectAfter
  public void test_interfaceBinder_notInClientPackage() throws Exception {
    try {
      _parse(
          "src/test/Test.ui.xml",
          getTestSource(
              "// filler filler filler filler filler",
              "// filler filler filler filler filler",
              "<ui:UiBinder>",
              "  <g:FlowPanel/>",
              "</ui:UiBinder>"));
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.NOT_CLIENT_PACKAGE, e.getCode());
    }
  }

  /**
   * Right now we support only widgets based UiBinder.
   * <p>
   * http://fogbugz.instantiations.com/fogbugz/default.asp?47790
   */
  @DisposeProjectAfter
  public void test_onlyBeWidgetBased() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "import com.google.gwt.dom.client.Element;",
            "public class Test extends UIObject {",
            "  interface Binder extends UiBinder<Element, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    setElement(binder.createAndBindUi(this));",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    try {
      parse(
          "// filler filler filler filler filler",
          "// filler filler filler filler filler",
          "<ui:UiBinder>",
          "  <div/>",
          "</ui:UiBinder>");
      fail();
    } catch (DesignerException e) {
      assertEquals(IExceptionConstants.ONLY_WIDGET_BASED, e.getCode());
    }
  }

  /**
   * Compilation error in form class should not cause {@link Class} absence, so "Binder" absence and
   * crash during rendering or UiBinder template.
   * <p>
   * TODO remove or introduce this feature back into GWT trunk
   */
  @DisposeProjectAfter
  public void _test_whenCompilationError_inFormClass() throws Exception {
    dontUseSharedGWTState();
    setFileContentSrc(
        "test/client/Test.java",
        getJavaSource(
            "import com.google.gwt.dom.client.Element;",
            "public class Test extends Composite {",
            "  interface Binder extends UiBinder<Widget, Test> {}",
            "  private static final Binder binder = GWT.create(Binder.class);",
            "  public Test() {",
            "    initWidget(binder.createAndBindUi(this));",
            "  }",
            "  private void foo() {",
            "    button.bar();",
            "  }",
            "}"));
    waitForAutoBuild();
    // parse
    parse(
        "// filler filler filler filler filler",
        "// filler filler filler filler filler",
        "<ui:UiBinder>",
        "  <g:FlowPanel/>",
        "</ui:UiBinder>");
    refresh();
    assertNoErrors();
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // CSS
  //
  ////////////////////////////////////////////////////////////////////////////
  @DisposeProjectAfter
  public void test_reparseOnCss() throws Exception {
    dontUseSharedGWTState();
    ComplexPanelInfo panel =
        parse(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:FlowPanel>",
            "    <g:Button wbp:name='button' styleName='test'/>",
            "  </g:FlowPanel>",
            "</ui:UiBinder>");
    refresh();
    WidgetInfo button = getObjectByName("button");
    // initially "button" is narrow
    assertThat(button.getBounds().width).isLessThan(100);
    // initially no refresh required
    {
      EditorActivatedRequest request = new EditorActivatedRequest();
      panel.getBroadcast(EditorActivatedListener.class).invoke(request);
      assertFalse(request.isReparseRequested());
      assertFalse(request.isRefreshRequested());
    }
    // update CSS
    setFileContent(
        "war/Module.css",
        getSourceDQ(
            "/* filler filler filler filler filler */",
            "/* filler filler filler filler filler */",
            "/* filler filler filler filler filler */",
            ".test {",
            "  width: 200px;",
            "}"));
    waitForAutoBuild();
    // now refresh required
    {
      EditorActivatedRequest request = new EditorActivatedRequest();
      panel.getBroadcast(EditorActivatedListener.class).invoke(request);
      assertFalse(request.isReparseRequested());
      assertTrue(request.isRefreshRequested());
    }
    // do refresh, as requested
    refresh();
    assertThat(button.getBounds().width).isEqualTo(200);
  }

  @DisposeProjectAfter
  public void test_reparseOnCss_andDontHurtCoordinates() throws Exception {
    dontUseSharedGWTState();
    ComplexPanelInfo panel =
        parse(
            "// filler filler filler filler filler",
            "// filler filler filler filler filler",
            "<ui:UiBinder>",
            "  <g:AbsolutePanel styleName='test'/>",
            "</ui:UiBinder>");
    refresh();
    // update CSS
    setFileContent(
        "war/Module.css",
        getSourceDQ(
            "/* filler filler filler filler filler */",
            "/* filler filler filler filler filler */",
            "/* filler filler filler filler filler */",
            ".test {",
            "  border: red 10px solid;",
            "}"));
    waitForAutoBuild();
    // now refresh required
    {
      EditorActivatedRequest request = new EditorActivatedRequest();
      panel.getBroadcast(EditorActivatedListener.class).invoke(request);
      assertFalse(request.isReparseRequested());
      assertTrue(request.isRefreshRequested());
    }
    // do refresh, as requested
    refresh();
    // assert that screen shot is correct and border is fully included
    {
      Image image = panel.getImage();
      System.out.println(image.getBounds());
      {
        ImageLoader imageLoader = new ImageLoader();
        imageLoader.data = new ImageData[]{image.getImageData()};
        imageLoader.save("c:/temp/1.png", SWT.IMAGE_PNG);
      }
      int width = image.getBounds().width;
      int height = image.getBounds().height;
      assertRGB(getPixelRGB(image, 0, 0), 0xFF, 0, 0);
      assertRGB(getPixelRGB(image, width - 1, 0), 0xFF, 0, 0);
      assertRGB(getPixelRGB(image, 0, height - 1), 0xFF, 0, 0);
      assertRGB(getPixelRGB(image, width - 1, height - 1), 0xFF, 0, 0);
    }
  }
}
TOP

Related Classes of com.google.gdt.eclipse.designer.uibinder.model.widgets.WidgetTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.