Package com.google.gwt.editor.rebind.model

Source Code of com.google.gwt.editor.rebind.model.EditorModelTest

/*
* Copyright 2010 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.editor.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.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.editor.client.CompositeEditor;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDriver;
import com.google.gwt.editor.client.EditorError;
import com.google.gwt.editor.client.HasEditorDelegate;
import com.google.gwt.editor.client.HasEditorErrors;
import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.ValueAwareEditor;
import com.google.gwt.editor.client.adapters.SimpleEditor;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.TakesValue;
import com.google.gwt.user.client.ui.HasText;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;

import junit.framework.TestCase;

import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.validation.ConstraintViolation;

/**
* Test case for {@link EditorModel} that uses mock CompilationStates.
*/
public class EditorModelTest extends TestCase {

  /**
   * Constructs an empty interface representation of a type.
   */
  private static class EmptyMockJavaResource extends MockJavaResource {
    private final StringBuilder code = new StringBuilder();

    public EmptyMockJavaResource(Class<?> clazz) {
      super(clazz.getName());

      code.append("package ").append(clazz.getPackage().getName()).append(";\n");
      code.append("public interface ").append(clazz.getSimpleName());

      int numParams = clazz.getTypeParameters().length;
      if (numParams != 0) {
        code.append("<");
        for (int i = 0; i < numParams; i++) {
          if (i != 0) {
            code.append(",");
          }
          code.append("T").append(i);
        }
        code.append(">");
      }

      code.append("{}\n");
    }

    @Override
    public CharSequence getContent() {
      return code;
    }
  }

  /**
   * Loads the actual source of a type. This should be used only for types
   * directly tested by this test. Note that use of this class requires your
   * source files to be on your classpath.
   */
  private static class RealJavaResource extends
      MockJavaResource {
    public RealJavaResource(Class<?> clazz) {
      super(clazz.getName());
    }

    @Override
    public CharSequence getContent() {
      String resourceName = getTypeName().replace('.', '/') + ".java";
      InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(
          resourceName);
      return Util.readStreamAsString(stream);
    }
  }

  private static TreeLogger createCompileLogger() {
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
        System.err, true));
    logger.setMaxDetail(TreeLogger.ERROR);
    return logger;
  }

  private TreeLogger logger;
  private JClassType rfedType;
  private TypeOracle types;

  @Override
  public void setUp() throws Exception {
    super.setUp();
    logger = createCompileLogger();
    CompilationState state =
        CompilationStateBuilder.buildFrom(logger, new CompilerContext(), getJavaResources());
    types = state.getTypeOracle();
    rfedType = types.findType(RequestFactoryEditorDriver.class.getName());
    assertNotNull(rfedType);
  }

  /**
   * Test the simple getters on the Model object.
   */
  public void testBasicAttributes() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.PersonEditorDriver"), rfedType);

    assertEquals(types.findType("t.PersonEditor"), m.getEditorType());
    assertEquals(types.findType("t.PersonProxy"), m.getProxyType());
  }

  /**
   * Verify that we correctly descend into a subeditor of a CompositeEditor that
   * also is a LeafValueEditor (as is the case of OptionalFieldEditor).
   */
  public void testCompositeAndLeafValueEditor()
      throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.CompositeAndLeafEditorDriver"), rfedType);

    assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AProxy"),
        m.getProxyType());
    assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AEditor"),
        m.getEditorType());

    EditorData[] data = m.getEditorData();
    assertEquals(1, data.length);

    assertTrue(data[0].isCompositeEditor());

    EditorData composed = data[0].getComposedData();
    assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BProxy"),
        composed.getEditedType());
    assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BEditor"),
        composed.getEditorType());

    // Nonsensical for the optional editor to have any data
    EditorData[] optionalEditorData = m.getEditorData(data[0].getEditorType());
    assertEquals(0, optionalEditorData.length);

    // Make sure we have EditorData for the sub-editor
    EditorData[] subEditorData = m.getEditorData(composed.getEditorType());
    assertEquals(1, subEditorData.length);
  }

  public void testCompositeDriver() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.CompositeEditorDriver"), rfedType);

    EditorData[] data = m.getEditorData();
    assertEquals(9, data.length);

    String[] paths = new String[data.length];
    String[] expressions = new String[data.length];
    for (int i = 0, j = paths.length; i < j; i++) {
      paths[i] = data[i].getPath();
      expressions[i] = data[i].getExpression();
    }
    assertEquals(Arrays.asList("address", "address.city", "address.street", "person", "person.has",
        "person.is", "person.lastModified", "person.name", "person.readonly"), Arrays.asList(paths));
    // address is a property, person is a method in CompositeEditor
    assertEquals(Arrays.asList("address", "address.city", "address.street", "person()",
        "person().has", "person().is", "person().lastModified", "person().name",
        "person().readonly"), Arrays.asList(expressions));
    assertTrue(data[0].isDelegateRequired());
    assertFalse(data[0].isLeafValueEditor() || data[0].isValueAwareEditor());
    assertTrue(data[3].isDelegateRequired());
    assertFalse(data[3].isLeafValueEditor() || data[3].isValueAwareEditor());
    int fieldNum = 4;
    checkPersonHasHas(data[fieldNum++]);
    checkPersonIsIs(data[fieldNum++]);
    checkPersonLastModified(data[fieldNum++]);
    checkPersonName(data[fieldNum++]);
    checkPersonReadonly(data[fieldNum++]);
  }

  public void testCyclicDriver() {
    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError(
        EditorModel.cycleErrorMessage(
            types.findType("t.CyclicEditorDriver.AEditor"), "<Root Object>",
            "b.a"), null);
    builder.expectError(EditorModel.poisonedMessage(), null);
    UnitTestTreeLogger testLogger = builder.createLogger();
    try {
      new EditorModel(testLogger, types.findType("t.CyclicEditorDriver"),
          rfedType);
      fail("Should have complained about cycle");
    } catch (UnableToCompleteException expected) {
    }
    testLogger.assertCorrectLogEntries();
  }

  public void testDottedPath() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.DottedPathEditorDriver"), rfedType);
    EditorData[] fields = m.getEditorData();
    assertEquals(2, fields.length);
    assertEquals("name", fields[0].getPath());
    assertFalse(fields[0].isDeclaredPathNested());
    assertEquals("", fields[0].getBeanOwnerExpression());
    assertEquals("true", fields[0].getBeanOwnerGuard("object"));
    assertEquals(".getName()", fields[0].getGetterExpression());
    assertEquals("address.street", fields[1].getPath());
    assertEquals(".getAddress()", fields[1].getBeanOwnerExpression());
    assertEquals("object.getAddress() != null",
        fields[1].getBeanOwnerGuard("object"));
    assertEquals(".getStreet()", fields[1].getGetterExpression());
    assertEquals("setStreet", fields[1].getSetterName());
    assertEquals("street", fields[1].getPropertyName());
    assertTrue(fields[1].isDeclaredPathNested());
    assertEquals(types.findType("t.AddressProxy"),
        fields[1].getPropertyOwnerType());
  }

  /**
   * Make sure we find all field-based editors.
   */
  public void testFieldEditors() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.PersonEditorDriver"), rfedType);
    EditorData[] fields = m.getEditorData();
    assertEquals(5, fields.length);

    int fieldNum = 0;
    // hasHas
    checkPersonHasHas(fields[fieldNum++]);
    // isIs
    checkPersonIsIs(fields[fieldNum++]);
    // lastModified
    checkPersonLastModified(fields[fieldNum++]);
    // name
    checkPersonName(fields[fieldNum++]);
    // readonly
    checkPersonReadonly(fields[fieldNum++]);
  }

  public void testFlatData() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.CompositeEditorDriver"), rfedType);

    assertNotNull(m.getEditorData(types.getJavaLangObject()));
    assertEquals(0, m.getEditorData(types.getJavaLangObject()).length);

    EditorData[] composite = m.getEditorData(types.findType("t.CompositeEditor"));
    assertEquals(2, composite.length);
    assertEquals("address", composite[0].getPropertyName());
    assertEquals("person", composite[1].getPropertyName());

    EditorData[] person = m.getEditorData(types.findType("t.PersonEditor"));
    assertEquals(5, person.length);
    int fieldNum = 0;
    assertEquals("has", person[fieldNum++].getPropertyName());
    assertEquals("is", person[fieldNum++].getPropertyName());
    assertEquals("lastModified", person[fieldNum++].getPropertyName());
    assertEquals("name", person[fieldNum++].getPropertyName());
    assertEquals("readonly", person[fieldNum++].getPropertyName());

    EditorData[] address = m.getEditorData(types.findType("t.AddressEditor"));
    assertEquals("city", address[0].getPropertyName());
    assertEquals("street", address[1].getPropertyName());
  }

  /**
   * Tests a plain IsEditor that allows the editor instance to be swapped in by
   * a view object.
   */
  public void testIsEditor() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.UsesIsEditorDriver"), rfedType);

    EditorData[] data = m.getEditorData();
    assertNotNull(data);
    assertEquals(2, data.length);
    assertEquals(Arrays.asList("b", "b.string"),
        Arrays.asList(data[0].getPath(), data[1].getPath()));
    assertEquals(
        Arrays.asList("bEditor().asEditor()", "stringEditor()"),
        Arrays.asList(data[0].getSimpleExpression(),
            data[1].getSimpleExpression()));
  }

  /**
   * Tests the case where an IsEditor also implements the Editor interface.
   */
  public void testIsEditorAndEditor() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.UsesIsEditorAndEditorDriver"), rfedType);

    EditorData[] data = m.getEditorData();
    assertNotNull(data);
    assertEquals(4, data.length);
    assertEquals(Arrays.asList("b", "b.string", "b", "b.string"),
        Arrays.asList(data[0].getPath(), data[1].getPath(), data[2].getPath(),
            data[3].getPath()));
    assertEquals(Arrays.asList("bEditor().asEditor()",
        "bEditor().asEditor().coEditor()", "bEditor()",
        "bEditor().viewEditor()"), Arrays.asList(data[0].getExpression(),
        data[1].getExpression(), data[2].getExpression(),
        data[3].getExpression()));
    assertEquals(
        Arrays.asList(true, false, true, false),
        Arrays.asList(data[0].isDelegateRequired(),
            data[1].isDelegateRequired(), data[2].isDelegateRequired(),
            data[3].isDelegateRequired()));
  }

  public void testListDriver() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.ListEditorDriver"), rfedType);
    assertEquals(types.findType("t.PersonProxy"), m.getProxyType());
    assertEquals(types.findType("t.ListEditor"), m.getEditorType());

    EditorData data = m.getRootData();
    assertTrue(data.isCompositeEditor());

    EditorData composed = data.getComposedData();
    assertEquals(types.findType("t.AddressProxy"), composed.getEditedType());
    assertEquals(types.findType("t.AddressEditor"), composed.getEditorType());

    // Nonsensical for the list editor to have any data
    EditorData[] listEditorData = m.getEditorData(m.getEditorType());
    assertEquals(0, listEditorData.length);

    // Make sure we have EditorData for the sub-editor
    EditorData[] subEditorData = m.getEditorData(composed.getEditorType());
    assertEquals(2, subEditorData.length);
  }

  /**
   * Make sure we can find all method-based editors.
   */
  public void testMethodEditors() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.PersonEditorDriverUsingMethods"), rfedType);
    EditorData[] fields = m.getEditorData();
    assertEquals(2, fields.length);

    // nameEditor()
    checkPersonName(fields[0]);
    checkPersonReadonly(fields[1]);
  }

  /**
   * Tests the case where an Editor wants to editor a property that is not
   * provided by its associated Proxy type.
   */
  public void testMissingGetter() {
    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError(
        EditorModel.noGetterMessage("missing",
            types.findType("t.MissingGetterEditorDriver.AProxy")), null);
    builder.expectError(
        EditorModel.noGetterMessage("yetAgain",
            types.findType("t.MissingGetterEditorDriver.AProxy")), null);
    builder.expectError(EditorModel.poisonedMessage(), null);
    UnitTestTreeLogger testLogger = builder.createLogger();
    try {
      new EditorModel(testLogger,
          types.findType("t.MissingGetterEditorDriver"), rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expecetd) {
    }
    testLogger.assertCorrectLogEntries();
  }

  /**
   * Tests the sanity-check error messages emitted by the constructor.
   */
  public void testSanityErrorMessages() {
    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError(
        EditorModel.unexpectedInputTypeMessage(rfedType,
            types.getJavaLangObject()), null);
    builder.expectError(EditorModel.mustExtendMessage(rfedType), null);
    builder.expectError(
        EditorModel.tooManyInterfacesMessage(types.findType("t.TooManyInterfacesEditorDriver")),
        null);
    builder.expectError(EditorModel.foundPrimitiveMessage(JPrimitiveType.LONG,
        "", "lastModified.foo"), null);
    builder.expectError(EditorModel.poisonedMessage(), null);
    UnitTestTreeLogger testLogger = builder.createLogger();

    try {
      new EditorModel(testLogger, types.getJavaLangObject(), rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expected) {
    }
    try {
      new EditorModel(testLogger, rfedType, rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expected) {
    }
    try {
      new EditorModel(testLogger,
          types.findType("t.TooManyInterfacesEditorDriver"), rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expected) {
    }
    try {
      new EditorModel(testLogger,
          types.findType("t.PersonEditorWithBadPrimitiveAccessDriver"),
          rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expected) {
    }
    testLogger.assertCorrectLogEntries();
  }

  public void testUnparameterizedEditor() {
    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError(
        EditorModel.noEditorParameterizationMessage(
            types.findType(Editor.class.getName()),
            types.findType(SimpleEditor.class.getName()).isGenericType().getRawType()),
        null);
    UnitTestTreeLogger testLogger = builder.createLogger();
    try {
      new EditorModel(testLogger,
          types.findType("t.UnparameterizedEditorEditorDriver"), rfedType);
      fail("Should have thrown exception");
    } catch (UnableToCompleteException expecetd) {
    }
    testLogger.assertCorrectLogEntries();
  }

  /**
   * Verify that {@code @Path("")} is valid.
   */
  public void testZeroLengthPath() throws UnableToCompleteException {
    EditorModel m = new EditorModel(logger,
        types.findType("t.PersonEditorWithAliasedSubEditorsDriver"), rfedType);
    EditorData[] fields = m.getEditorData();
    assertEquals(12, fields.length);
  }

  private void checkPersonHasHas(EditorData editorField) {
    assertNotNull(editorField);
    assertEquals(types.findType(SimpleEditor.class.getName()),
        editorField.getEditorType().isParameterized().getBaseType());
    assertTrue(editorField.isLeafValueEditor());
    assertFalse(editorField.isDelegateRequired());
    assertFalse(editorField.isValueAwareEditor());
    assertEquals(".hasHas()", editorField.getGetterExpression());
    assertEquals("setHas", editorField.getSetterName());
  }

  private void checkPersonIsIs(EditorData editorField) {
    assertNotNull(editorField);
    assertEquals(types.findType(SimpleEditor.class.getName()),
        editorField.getEditorType().isParameterized().getBaseType());
    assertTrue(editorField.isLeafValueEditor());
    assertFalse(editorField.isDelegateRequired());
    assertFalse(editorField.isValueAwareEditor());
    assertEquals(".isIs()", editorField.getGetterExpression());
    assertEquals("setIs", editorField.getSetterName());
  }

  private void checkPersonLastModified(EditorData editorField) {
    assertNotNull(editorField);
    assertEquals(types.findType(SimpleEditor.class.getName()),
        editorField.getEditorType().isParameterized().getBaseType());
    assertTrue(editorField.isLeafValueEditor());
    assertFalse(editorField.isDelegateRequired());
    assertFalse(editorField.isValueAwareEditor());
    assertEquals(".getLastModified()", editorField.getGetterExpression());
    assertEquals("setLastModified", editorField.getSetterName());
  }

  private void checkPersonName(EditorData editorField) {
    assertNotNull(editorField);
    assertEquals(types.findType(SimpleEditor.class.getName()),
        editorField.getEditorType().isParameterized().getBaseType());
    assertTrue(editorField.isLeafValueEditor());
    assertFalse(editorField.isDelegateRequired());
    assertFalse(editorField.isValueAwareEditor());
    assertEquals(".getName()", editorField.getGetterExpression());
    assertEquals("setName", editorField.getSetterName());
  }

  /**
   * @param editorField
   */
  private void checkPersonReadonly(EditorData editorField) {
    assertNotNull(editorField);
    assertEquals(types.findType(SimpleEditor.class.getName()),
        editorField.getEditorType().isParameterized().getBaseType());
    assertTrue(editorField.isLeafValueEditor());
    assertFalse(editorField.isDelegateRequired());
    assertFalse(editorField.isValueAwareEditor());
    assertEquals(".getReadonly()", editorField.getGetterExpression());
    assertNull(editorField.getSetterName());
  }

  @SuppressWarnings("deprecation")
  private Set<Resource> getDeprecatedResources() {
    return Collections.<Resource> singleton(new EmptyMockJavaResource(
        com.google.web.bindery.requestfactory.shared.Violation.class));
  }

  private Set<Resource> getJavaResources() {
    MockJavaResource[] javaFiles = {new MockJavaResource("t.AddressProxy") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("interface AddressProxy extends EntityProxy {\n");
        code.append("String getCity();\n");
        code.append("void setCity(String city);\n");
        code.append("String getStreet();\n");
        code.append("void setStreet(String street);\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.AddressEditor") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("class AddressEditor implements Editor<AddressProxy> {\n");
        code.append("public SimpleEditor<String> city;\n");
        code.append("public SimpleEditor<String> street;\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.CompositeProxy") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("interface CompositeProxy extends EntityProxy {\n");
        code.append("AddressProxy getAddress();\n");
        code.append("PersonProxy getPerson();\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.CompositeEditor") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("class CompositeEditor implements Editor<CompositeProxy> {\n");
        code.append("AddressEditor address;\n");
        code.append("PersonEditor person(){return null;}\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.CompositeEditorDriver") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface CompositeEditorDriver extends RequestFactoryEditorDriver<CompositeProxy, CompositeEditor> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.CyclicEditorDriver") {
        // Tests error-detection when the editor graph isn't a DAG
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface CyclicEditorDriver extends"
            + " RequestFactoryEditorDriver<CyclicEditorDriver.AProxy,"
            + " CyclicEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy { BProxy getB(); }");
        code.append("  interface BProxy extends EntityProxy { AProxy getA(); }");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    BEditor bEditor();");
        code.append("  }");
        code.append("  interface BEditor extends Editor<BProxy> {");
        code.append("    AEditor aEditor();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.DottedPathEditorDriver") {
        // Tests error-detection when the editor graph isn't a DAG
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("interface DottedPathEditorDriver extends"
            + " RequestFactoryEditorDriver<PersonProxy,"
            + " DottedPathEditorDriver.PersonEditor> {\n");
        code.append("  interface PersonEditor extends Editor<PersonProxy> {");
        code.append("  SimpleEditor<String> nameEditor();");
        code.append("  @Editor.Path(\"address.street\")");
        code.append("  SimpleEditor<String> streetEditor();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.ListEditor") {
        // Tests error-detection when the editor graph isn't a DAG
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + CompositeEditor.class.getName() + ";\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("interface ListEditor extends CompositeEditor<PersonProxy, AddressProxy, AddressEditor>, Editor<PersonProxy> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.ListEditorDriver") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface ListEditorDriver extends RequestFactoryEditorDriver<PersonProxy, ListEditor> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.MissingGetterEditorDriver") {
        // Tests error-detection when the editor structure doesn't match the
        // proxy
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("interface MissingGetterEditorDriver extends"
            + " RequestFactoryEditorDriver<MissingGetterEditorDriver.AProxy,"
            + " MissingGetterEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy {}");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    SimpleEditor<String> missingEditor();");
        code.append("    SimpleEditor<String> yetAgain();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonProxy") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("interface PersonProxy extends EntityProxy {\n");
        code.append("AddressProxy getAddress();\n");
        code.append("String getName();\n");
        code.append("long getLastModified();\n");
        code.append("String getReadonly();\n");
        code.append("boolean hasHas();\n");
        code.append("boolean isIs();\n");
        code.append("void setHas(boolean has);\n");
        code.append("void setIs(boolean is);\n");
        code.append("void setName(String name);\n");
        code.append("void setLastModified(long value);\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditor") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("class PersonEditor implements Editor<PersonProxy> {\n");
        code.append("SimpleEditor<Boolean> has;\n");
        code.append("SimpleEditor<Boolean> is;\n");
        code.append("SimpleEditor<Long> lastModified;\n");
        code.append("public SimpleEditor<String> name;\n");
        code.append("SimpleEditor<String> readonly;\n");
        code.append("public static SimpleEditor ignoredStatic;\n");
        code.append("private SimpleEditor<String> ignoredPrivate;\n");
        code.append("@Editor.Ignore public SimpleEditor<String> ignoredPublic;\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorWithAliasedSubEditors") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("class PersonEditorWithAliasedSubEditors implements Editor<PersonProxy> {\n");
        code.append("@Path(\"\") PersonEditor e1;\n");
        code.append("@Path(\"\") PersonEditor e2;\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorWithAliasedSubEditorsDriver") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface PersonEditorWithAliasedSubEditorsDriver extends"
            + " RequestFactoryEditorDriver<PersonProxy, t.PersonEditorWithAliasedSubEditors> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccess") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("class PersonEditorWithBadPrimitiveAccess implements Editor<PersonProxy> {\n");
        code.append("@Path(\"lastModified.foo\") SimpleEditor<String> bad;\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccessDriver") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface PersonEditorWithBadPrimitiveAccessDriver extends"
            + " RequestFactoryEditorDriver<PersonProxy, t.PersonEditorWithBadPrimitiveAccess> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorUsingMethods") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("abstract class PersonEditorUsingMethods implements Editor<PersonProxy> {\n");
        code.append("public abstract SimpleEditor<String> nameEditor();\n");
        code.append("protected abstract SimpleEditor<String> readonlyEditor();\n");
        code.append("public static SimpleEditor<String> ignoredStatic() {return null;}\n");
        code.append("private SimpleEditor<String> ignoredPrivate() {return null;}\n");
        code.append("@Editor.Ignore public abstract SimpleEditor<String> ignoredPublic();\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorDriver") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface PersonEditorDriver extends"
            + " RequestFactoryEditorDriver<PersonProxy, PersonEditor> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonEditorDriverUsingMethods") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface PersonEditorDriverUsingMethods extends"
            + " RequestFactoryEditorDriver<PersonProxy, PersonEditorUsingMethods> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.PersonRequestFactory") {
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactory.class.getName() + ";\n");
        code.append("interface PersonRequestFactory extends RequestFactory {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.TooManyInterfacesEditorDriver") {
        // Tests a Driver interface that extends more than RFED
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("interface TooManyInterfacesEditorDriver extends"
            + " RequestFactoryEditorDriver<CompositeProxy, CompositeEditor>,"
            + " java.io.Serializable {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.UnparameterizedEditorEditorDriver") {
        // Tests error-detection when the editor structure doesn't match the
        // proxy
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("interface UnparameterizedEditorEditorDriver extends"
            + " RequestFactoryEditorDriver<UnparameterizedEditorEditorDriver.AProxy,"
            + " UnparameterizedEditorEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy {}");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    SimpleEditor needsParameterization();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.UsesIsEditorDriver") {
        // Tests error-detection when the editor structure doesn't match the
        // proxy
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + IsEditor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("interface UsesIsEditorDriver extends"
            + " RequestFactoryEditorDriver<UsesIsEditorDriver.AProxy,"
            + " UsesIsEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy { BProxy getB();}");
        code.append("  interface BProxy extends EntityProxy { String getString();}");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    BView bEditor();");
        code.append("  }");
        code.append("  interface BView extends IsEditor<BEditor> {");
        code.append("    @Editor.Path(\"string\") BEditor unseen();");
        code.append("  }");
        code.append("  interface BEditor extends Editor<BProxy> {");
        code.append("    SimpleEditor<String> stringEditor();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.UsesIsEditorAndEditorDriver") {
        // Tests error-detection when the editor structure doesn't match the
        // proxy
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + HasEditorErrors.class.getName() + ";\n");
        code.append("import " + IsEditor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("interface UsesIsEditorAndEditorDriver extends"
            + " RequestFactoryEditorDriver<UsesIsEditorAndEditorDriver.AProxy,"
            + " UsesIsEditorAndEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy { BProxy getB();}");
        code.append("  interface BProxy extends EntityProxy { String getString();}");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    BView bEditor();");
        code.append("  }");
        code.append("  interface BView extends IsEditor<BEditor>, Editor<BProxy>, HasEditorErrors {");
        code.append("    @Editor.Path(\"string\") SimpleEditor<String> viewEditor();");
        code.append("  }");
        code.append("  interface BEditor extends Editor<BProxy> {");
        code.append("    @Editor.Path(\"string\") SimpleEditor<String> coEditor();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.CompositeAndLeafEditorDriver") {
      /*
       * Tests that we descend into sub-editor of a CompositeEditor that also is
       * a LeafValueEditor (this is the case for the
       * c.g.g.editor.client.adapters.OptionalFieldEditor). Also test that any
       * editor-like fields within the LeafValueEditor are ignored.
       */
      @Override
      public CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Editor.class.getName() + ";\n");
        code.append("import " + IsEditor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        code.append("import " + RequestFactoryEditorDriver.class.getName()
            + ";\n");
        code.append("import " + SimpleEditor.class.getName() + ";\n");
        code.append("import " + CompositeEditor.class.getName() + ";\n");
        code.append("import " + LeafValueEditor.class.getName() + ";\n");
        code.append("interface CompositeAndLeafEditorDriver extends"
            + " RequestFactoryEditorDriver<CompositeAndLeafEditorDriver.AProxy,"
            + " CompositeAndLeafEditorDriver.AEditor> {\n");
        code.append("  interface AProxy extends EntityProxy { BProxy getB();}");
        code.append("  interface BProxy extends EntityProxy { String getString();}");
        code.append("  interface AEditor extends Editor<AProxy> {");
        code.append("    OptionalBEditor bEditor();");
        code.append("  }");
        code.append("  interface OptionalBEditor extends CompositeEditor<BProxy, BProxy, BEditor>, LeafValueEditor<BProxy> {");
        code.append("    LeafValueEditor<String> ignored();");
        code.append("  }");
        code.append("  interface BEditor extends Editor<BProxy> {");
        code.append("    @Editor.Path(\"string\") SimpleEditor<String> coEditor();");
        code.append("  }");
        code.append("}");
        return code;
      }
    }};

    Set<Resource> toReturn = new HashSet<Resource>(Arrays.asList(javaFiles));
    toReturn.addAll(Arrays.asList(new Resource[] {
        new RealJavaResource(CompositeEditor.class),
        new EmptyMockJavaResource(ConstraintViolation.class),
        new RealJavaResource(Editor.class),
        new EmptyMockJavaResource(EditorDriver.class),
        new RealJavaResource(EditorError.class),
        new EmptyMockJavaResource(EntityProxy.class),
        new EmptyMockJavaResource(EventBus.class),
        new EmptyMockJavaResource(com.google.web.bindery.event.shared.EventBus.class),
        new EmptyMockJavaResource(HasEditorDelegate.class),
        new EmptyMockJavaResource(HasEditorErrors.class),
        new RealJavaResource(HasText.class),
        new RealJavaResource(IsEditor.class),
        new EmptyMockJavaResource(Iterable.class),
        new RealJavaResource(LeafValueEditor.class),
        new EmptyMockJavaResource(RequestFactory.class),
        new RealJavaResource(RequestFactoryEditorDriver.class),
        new EmptyMockJavaResource(Request.class),
        new EmptyMockJavaResource(RequestContext.class),
        new RealJavaResource(SimpleEditor.class),
        new RealJavaResource(TakesValue.class),
        new EmptyMockJavaResource(ValueAwareEditor.class)}));
    toReturn.addAll(getDeprecatedResources());
    toReturn.addAll(Arrays.asList(JavaResourceBase.getStandardResources()));
    return toReturn;
  }
}
TOP

Related Classes of com.google.gwt.editor.rebind.model.EditorModelTest

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.