Revision: 9755
Author: [email protected]
Date: Tue Feb 22 10:50:07 2011
Log: Report ValidationExceptions at compile time for constrained methods
that do not follow the JavaBean naming convention.

[JSR 303 TCK Result] 94 of 257 (36.58%) Pass with 33 Failures and 13 Errors.

Review at http://gwt-code-reviews.appspot.com/1354807

Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=9755

Added:
/trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckCompileTest.gwt.xml /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckCompileTestValidatorFactory.java /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/ValidateCompileTest.java
 /trunk/user/test/org/hibernate/jsr303/tck/util/TckGeneratorTestUtils.java
Modified:
 /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java
 /trunk/user/test/com/google/gwt/validation/tck/ValidationGwtSuite.java
 /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckTest.gwt.xml
/trunk/user/test/org/hibernate/jsr303/tck/tests/validation/ValidateGwtTest.java

=======================================
--- /dev/null
+++ /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckCompileTest.gwt.xml Tue Feb 22 10:50:07 2011
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.1/distro-source/core/src/gwt-module.dtd";>
+<!--
+  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.
+-->
+<module>
+  <inherits name="org.hibernate.jsr303.tck.tests.ValidationTck" />
+  <source path="">
+    <include name="*.java" />
+    <exclude name="*CompileTest.java" />
+  </source>
+ <replace-with class="org.hibernate.jsr303.tck.tests.validation.TckCompileTestValidatorFactory">
+    <when-type-is class="javax.validation.ValidatorFactory"/>
+  </replace-with>
+</module>
=======================================
--- /dev/null
+++ /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckCompileTestValidatorFactory.java Tue Feb 22 10:50:07 2011
@@ -0,0 +1,41 @@
+/*
+ * 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 org.hibernate.jsr303.tck.tests.validation;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.validation.client.AbstractGwtValidatorFactory;
+import com.google.gwt.validation.client.GwtValidation;
+import com.google.gwt.validation.client.impl.AbstractGwtValidator;
+
+import javax.validation.Validator;
+
+/**
+ * {@link AbstractGwtValidatorFactory} implementation that uses
+ * {@link com.google.gwt.validation.client.GwtValidation GwtValidation}.
+ */
+public final class TckCompileTestValidatorFactory extends AbstractGwtValidatorFactory {
+  /**
+   * Marker Interface for {@link GWT#create(Class)}.
+   */
+  @GwtValidation(value = {Boy.class})
+  public static interface GwtValidator extends Validator {
+  }
+
+  @Override
+  public AbstractGwtValidator createValidator() {
+    return GWT.create(GwtValidator.class);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/ValidateCompileTest.java Tue Feb 22 10:50:07 2011
@@ -0,0 +1,56 @@
+/*
+ * 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 org.hibernate.jsr303.tck.tests.validation;
+
+import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.util.UnitTestTreeLogger;
+import com.google.gwt.junit.client.GWTTestCase;
+
+import static org.hibernate.jsr303.tck.util.TckGeneratorTestUtils.assertModuleFails; +import static org.hibernate.jsr303.tck.util.TckGeneratorTestUtils.getFullyQaulifiedModuleName;
+
+import javax.validation.ValidationException;
+
+/**
+ * Test wrapper for {@link ValidateTest} methods that are suppose to fail to
+ * compile.
+ */
+public class ValidateCompileTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return null; // null runs as normal JRE JunitTest
+  }
+
+  public void testValidatedPropertyDoesNotFollowJavaBeansConvention()
+      throws UnableToCompleteException {
+    String moduleName = "TckCompileTest";
+
+    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
+    builder.expect(
+        Type.ERROR,
+ "Unable to create a validator for org.hibernate.jsr303.tck.tests.validation.Boy because " + + "Annotated methods must follow the JavaBeans naming convention. age() does not.",
+        ValidationException.class);
+    builder.setLowestLogLevel(Type.INFO);
+    UnitTestTreeLogger testLogger = builder.createLogger();
+    // TODO (nchalko) create this module in memory just for this test.
+    assertModuleFails(testLogger,
+        getFullyQaulifiedModuleName(getClass(), moduleName),
+        TckCompileTestValidatorFactory.GwtValidator.class);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/org/hibernate/jsr303/tck/util/TckGeneratorTestUtils.java Tue Feb 22 10:50:07 2011
@@ -0,0 +1,88 @@
+/*
+ * 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 org.hibernate.jsr303.tck.util;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+import com.google.gwt.dev.javac.StandardGeneratorContext;
+import com.google.gwt.dev.shell.FailErrorLogger;
+import com.google.gwt.dev.util.UnitTestTreeLogger;
+import com.google.gwt.validation.rebind.ValidatorGenerator;
+
+import junit.framework.Assert;
+
+import java.io.File;
+
+import javax.validation.Validator;
+
+/**
+ * Static utilities useful for testing TCK Generators.
+ */
+public class TckGeneratorTestUtils {
+
+  /**
+   * Asserts that calling
+ * {@link ValidatorGenerator#generate(TreeLogger, com.google.gwt.core.ext.GeneratorContext, String)} + * causes a {@link UnableToCompleteException} with exactly the log messages
+   * specified in {@code testLogger}.
+   *
+   * @param testLogger test logger with expected log messages set.
+   * @param fullyQaulifiedModuleName the gwt Module to load.
+   * @param validatorClass the Validator to generate.
+ * @throws UnableToCompleteException if The module or derived CompilationState
+   *           can not be loaded.
+   */
+  public static void assertModuleFails(UnitTestTreeLogger testLogger,
+      String fullyQaulifiedModuleName,
+      Class<? extends Validator> validatorClass)
+      throws UnableToCompleteException {
+    TreeLogger logger = new FailErrorLogger();
+    ModuleDef module = ModuleDefLoader.loadFromClassPath(logger,
+        fullyQaulifiedModuleName);
+    File genDir = new File(System.getProperty("java.io.tmpdir"));
+    ArtifactSet allGenreatedArtifacts = new ArtifactSet();
+    boolean isProd = false;
+    StandardGeneratorContext context = new StandardGeneratorContext(
+        module.getCompilationState(logger), module, genDir,
+        allGenreatedArtifacts, isProd);
+
+    ValidatorGenerator generator = new ValidatorGenerator();
+    try {
+      generator.generate(testLogger, context,
+          validatorClass.getCanonicalName());
+      Assert.fail("Expected a " + UnableToCompleteException.class);
+    } catch (UnableToCompleteException expected) {
+      // expected
+    }
+    testLogger.assertCorrectLogEntries();
+  }
+
+  /**
+   * Creates the fully qualified GWT module name using the package of
+   * {@code clazz} and the {@code moduleNam}
+   *
+   * @param clazz the class whose package the module is in.
+   * @param moduleName the module name.
+   * @return the fully qualified module name.
+   */
+  public static String getFullyQaulifiedModuleName(Class<?> clazz,
+      String moduleName) {
+    return clazz.getPackage().getName() + "." + moduleName;
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java Mon Feb 7 07:41:58 2011 +++ /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java Tue Feb 22 10:50:07 2011
@@ -18,6 +18,7 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.ext.GeneratorContext;
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.TreeLogger.Type;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JArrayType;
 import com.google.gwt.core.ext.typeinfo.JClassType;
@@ -37,6 +38,7 @@
 import java.util.Map;

 import javax.validation.Validation;
+import javax.validation.ValidationException;
 import javax.validation.Validator;
 import javax.validation.metadata.BeanDescriptor;
 import javax.validation.metadata.PropertyDescriptor;
@@ -45,7 +47,7 @@
* A simple struct for the various values associated with a Bean that can be
  * validated.
  */
-final class BeanHelper {
+public final class BeanHelper {

   public static final Function<BeanHelper, Class<?>> TO_CLAZZ =
       new Function<BeanHelper, Class<?>>() {
@@ -54,32 +56,33 @@
     }
   };

- private static final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();
+  private static final Validator serverSideValidator =
+      Validation.buildDefaultValidatorFactory().getValidator();

   // stash the map in a ThreadLocal, since each GWT module lives in its own
   // thread in DevMode
private static final ThreadLocal<Map<JClassType, BeanHelper>> threadLocalHelperMap =
-      new ThreadLocal<Map<JClassType, BeanHelper>>() {
+        new ThreadLocal<Map<JClassType, BeanHelper>>() {
     @Override
     protected synchronized Map<JClassType, BeanHelper> initialValue() {
       return new HashMap<JClassType, BeanHelper>();
     }
   };
+
+ public static BeanHelper createBeanHelper(Class<?> clazz, TreeLogger logger,
+      GeneratorContext context) throws UnableToCompleteException {
+    JClassType beanType = context.getTypeOracle().findType(
+        clazz.getCanonicalName());
+    return createBeanHelper(clazz, beanType, logger, context);
+  }

   public static Map<JClassType, BeanHelper> getBeanHelpers() {
     return Collections.unmodifiableMap(threadLocalHelperMap.get());
   }

-  protected static BeanHelper createBeanHelper(Class<?> clazz,
+  protected static BeanHelper createBeanHelper(JClassType jType,
       TreeLogger logger, GeneratorContext context)
       throws UnableToCompleteException {
-    JClassType beanType = context.getTypeOracle().findType(
-        clazz.getCanonicalName());
-    return createBeanHelper(clazz, beanType, logger, context);
-  }
-
- protected static BeanHelper createBeanHelper(JClassType jType, TreeLogger logger,
-      GeneratorContext context) throws UnableToCompleteException {
     JClassType erasedType = jType.getErasedType();
     try {
       Class<?> clazz = Class.forName(erasedType.getQualifiedBinaryName());
@@ -92,7 +95,7 @@
   }

   protected static boolean isClassConstrained(Class<?> clazz) {
- return serverSideValidor.getConstraintsForClass(clazz).isBeanConstrained(); + return serverSideValidator.getConstraintsForClass(clazz).isBeanConstrained();
   }

   static BeanHelper getBeanHelper(JClassType beanType) {
@@ -140,12 +143,21 @@
       throws UnableToCompleteException {
     BeanHelper helper = getBeanHelper(beanType);
     if (helper == null) {
-      helper = new BeanHelper(beanType, clazz,
-          serverSideValidor.getConstraintsForClass(clazz));
+      BeanDescriptor bean;
+      try {
+        bean = serverSideValidator.getConstraintsForClass(clazz);
+      } catch (ValidationException e) {
+        logger.log(Type.ERROR,
+            "Unable to create a validator for " + clazz.getCanonicalName()
+                + " because " + e.getMessage(), e);
+        throw new UnableToCompleteException();
+      }
+      helper = new BeanHelper(beanType, clazz, bean);
       addBeanHelper(helper);
       writeInterface(context, logger, helper);
+
       // now recurse on all Cascaded elements
- for (PropertyDescriptor p : helper.getBeanDescriptor().getConstrainedProperties()) {
+      for (PropertyDescriptor p : bean.getConstrainedProperties()) {
         if (p.isCascaded()) {
           createBeanHelper(p, helper, logger, context);
         }
@@ -170,7 +182,7 @@
         createBeanHelper(type.getErasedType(), logger, context);
       }
     } else {
- if (serverSideValidor.getConstraintsForClass(elementClass).isBeanConstrained()) { + if (serverSideValidator.getConstraintsForClass(elementClass).isBeanConstrained()) {
         createBeanHelper(elementClass, logger, context);
       }
     }
@@ -190,8 +202,7 @@
     this.clazz = clazz;
   }

-  public  JClassType getAssociationType(PropertyDescriptor p,
-      boolean useField) {
+ public JClassType getAssociationType(PropertyDescriptor p, boolean useField) {
     JType type = this.getElementType(p, useField);
     JArrayType jArray = type.isArray();
     if (jArray != null) {
=======================================
--- /trunk/user/test/com/google/gwt/validation/tck/ValidationGwtSuite.java Wed Jan 26 05:45:23 2011 +++ /trunk/user/test/com/google/gwt/validation/tck/ValidationGwtSuite.java Tue Feb 22 10:50:07 2011
@@ -18,6 +18,7 @@
 import junit.framework.Test;

 import org.hibernate.jsr303.tck.tests.validation.PropertyPathGwtTest;
+import org.hibernate.jsr303.tck.tests.validation.ValidateCompileTest;
 import org.hibernate.jsr303.tck.tests.validation.ValidateGwtTest;
 import org.hibernate.jsr303.tck.tests.validation.ValidatePropertyGwtTest;
 import org.hibernate.jsr303.tck.tests.validation.ValidateValueGwtTest;
@@ -33,6 +34,7 @@
         "TCK for GWT Validation, validation package");
     suite.addTestSuite(PropertyPathGwtTest.class);
     suite.addTestSuite(ValidateGwtTest.class);
+    suite.addTestSuite(ValidateCompileTest.class);
     suite.addTestSuite(ValidatePropertyGwtTest.class);
     suite.addTestSuite(ValidateValueGwtTest.class);
     suite.addTestSuite(ValidationGwtTest.class);
=======================================
--- /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckTest.gwt.xml Tue Jan 11 14:19:47 2011 +++ /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/TckTest.gwt.xml Tue Feb 22 10:50:07 2011
@@ -19,6 +19,7 @@
   <inherits name="org.hibernate.jsr303.tck.tests.ValidationTck" />
   <source path="">
     <include name="*.java" />
+    <exclude name="*CompileTest.java" />
   </source>
<replace-with class="org.hibernate.jsr303.tck.tests.validation.TckTestValidatorFactory">
     <when-type-is class="javax.validation.ValidatorFactory"/>
=======================================
--- /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/ValidateGwtTest.java Wed Feb 9 08:55:13 2011 +++ /trunk/user/test/org/hibernate/jsr303/tck/tests/validation/ValidateGwtTest.java Tue Feb 22 10:50:07 2011
@@ -84,11 +84,6 @@
       // Expected
     }
   }
-
-  @Failing(issue = 5929)
-  public void testValidatedPropertyDoesNotFollowJavaBeansConvention() {
-    delegate.testValidatedPropertyDoesNotFollowJavaBeansConvention();
-  }

   public void testValidateWithNullGroup() {
     try {
@@ -112,5 +107,4 @@
   public void testValidationIsPolymorphic() {
     delegate.testValidationIsPolymorphic();
   }
-
-}
+}

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

Reply via email to