Revision: 6425
Author: [email protected]
Date: Tue Oct 20 11:31:25 2009
Log: Adding a feature that allows users to define compile properties on  
test methods in GwtTestCases.  A synthetic module will be created using the  
test module plus the specified properties.

Patch by: pmuetschard           
Review by: jlabanca


http://code.google.com/p/google-web-toolkit/source/detail?r=6425

Added:
  /trunk/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java
  /trunk/user/src/com/google/gwt/junit/client/WithProperties.java
  /trunk/user/test/com/google/gwt/junit/JUnitTestWithProperties.gwt.xml
  /trunk/user/test/com/google/gwt/junit/PropertyDefiningStrategyTest.java
  /trunk/user/test/com/google/gwt/junit/client/PropertyDefiningGWTTest.java
Modified:
  /trunk/user/src/com/google/gwt/benchmarks/client/Benchmark.java
  /trunk/user/src/com/google/gwt/junit/CompileStrategy.java
  /trunk/user/src/com/google/gwt/junit/JUnitShell.java
  /trunk/user/src/com/google/gwt/junit/client/GWTTestCase.java
  /trunk/user/src/com/google/gwt/junit/tools/GWTTestSuite.java
  /trunk/user/test/com/google/gwt/junit/JUnitSuite.java

=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java  Tue  
Oct 20 11:31:25 2009
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2009 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.junit;
+
+import com.google.gwt.dev.cfg.BindingProperty;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.Properties;
+import com.google.gwt.dev.util.Util;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.junit.client.WithProperties;
+import com.google.gwt.junit.client.WithProperties.Property;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * A {...@link JUnitShell.Strategy} that will alter the module the tests are  
run
+ * in by defining module properties as requested by annotations on the  
tests.
+ */
+public class PropertyDefiningStrategy extends GWTTestCase.BaseStrategy {
+  private TestCase testCase;
+  private Set<Property> properties;
+
+  public PropertyDefiningStrategy(TestCase testCase) {
+    this.testCase = testCase;
+  }
+
+  protected String getBaseModuleExtension() {
+    return super.getSyntheticModuleExtension();
+  }
+
+  @Override
+  public String getSyntheticModuleExtension() {
+    String extension = getBaseModuleExtension();
+    computePropertiesMap();
+    if (properties.size() > 0) {
+      StringBuilder sb = new StringBuilder();
+      for (Property property : properties) {
+        sb.append(".").append(property.name()).append(
+            "$").append(property.value());
+      }
+      extension += sb.toString();
+    }
+    return extension;
+  }
+
+  @Override
+  public void processModule(ModuleDef module) {
+    super.processModule(module);
+    computePropertiesMap();
+    if (properties.size() > 0) {
+      Properties props = module.getProperties();
+      for (Property property : properties) {
+        BindingProperty binding = props.createBinding(property.name());
+        if (!binding.isDefinedValue(property.value())) {
+          binding.addDefinedValue(
+              binding.getRootCondition(), property.value());
+        }
+        binding.setAllowedValues(
+            binding.getRootCondition(), property.value());
+      }
+    }
+  }
+
+  private Property checkProperty(Property property) {
+    String[] tokens = (property.name() + ". ").split("\\.");
+    for (int i = 0; i < tokens.length - 1; i++) {
+      if (!Util.isValidJavaIdent(tokens[i])) {
+        throw new AssertionError(
+            "Property name invalid: " + property.name());
+      }
+    }
+
+    if (!Util.isValidJavaIdent(property.value())) {
+      throw new AssertionError(
+          "Property value invalid: " + property.value());
+    }
+
+    return property;
+  }
+
+  private void computePropertiesMap() {
+    if (properties == null) {
+      Set<Property> props = new TreeSet<Property>(
+          new Comparator<Property>() {
+        public int compare(Property p1, Property p2) {
+          int r = p1.name().compareTo(p2.name());
+          if (r == 0) {
+            r = p1.value().compareTo(p2.value());
+          }
+          return r;
+        }
+      });
+      try {
+        String name = testCase.getName();
+        if (name != null) {
+          Method testMethod =  
testCase.getClass().getMethod(testCase.getName());
+          if (testMethod.isAnnotationPresent(WithProperties.class)) {
+            WithProperties annotation =
+              testMethod.getAnnotation(WithProperties.class);
+            for (Property property : annotation.value()) {
+              props.add(checkProperty(property));
+            }
+          }
+        }
+      } catch (SecurityException e) {
+        // should not happen
+        e.printStackTrace();
+      } catch (NoSuchMethodException e) {
+        // should not happen
+        e.printStackTrace();
+      }
+      properties = props;
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/junit/client/WithProperties.java     Tue Oct 
 
20 11:31:25 2009
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 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.junit.client;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation indicating that a test method inside a {...@link GWTTestCase}
+ * requires a set of binding properties to be set in its module.
+ */
+...@target(ElementType.METHOD)
+...@retention(RetentionPolicy.RUNTIME)
+public @interface WithProperties {
+  Property[] value();
+
+  /**
+   * Annotation defining a binding property.
+   */
+  @Retention(RetentionPolicy.RUNTIME)
+  public static @interface Property {
+    String name();
+
+    String value();
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/junit/JUnitTestWithProperties.gwt.xml       
 
Tue Oct 20 11:31:25 2009
@@ -0,0 +1,37 @@
+<!--                                                                         
-->
+<!-- Copyright 2009 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   -->
+<!-- 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. License for the specific language governing permissions  
and   -->
+<!-- limitations under the  
License.                                         -->
+
+<!-- This module is for the PropertyDefiningGWTTest -->
+<module>
+  <inherits name="com.google.gwt.user.User" />
+  <define-property name="my.property" values="one,two" />
+
+  <replace-with  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest$TestImplOne">
+    <when-type-is  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest$TestInterface" />
+    <when-property-is name="my.property" value="one" />
+  </replace-with>
+  <replace-with  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest.TestImplOne">
+    <when-type-is  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest.TestInterface" />
+    <when-property-is name="my.property" value="one" />
+  </replace-with>
+
+  <replace-with  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest$TestImplTwo">
+    <when-type-is  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest$TestInterface" />
+    <when-property-is name="my.property" value="two" />
+  </replace-with>
+  <replace-with  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest.TestImplTwo">
+    <when-type-is  
class="com.google.gwt.junit.client.PropertyDefiningGWTTest.TestInterface" />
+    <when-property-is name="my.property" value="two" />
+  </replace-with>
+</module>
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/junit/PropertyDefiningStrategyTest.java     
 
Tue Oct 20 11:31:25 2009
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2009 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.junit;
+
+import com.google.gwt.dev.cfg.BindingProperty;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.junit.client.WithProperties;
+import com.google.gwt.junit.client.WithProperties.Property;
+
+import junit.framework.TestCase;
+
+import java.util.SortedSet;
+
+/**
+ * Tests the {...@link PropertyDefiningStrategy}.
+ */
+public class PropertyDefiningStrategyTest extends TestCase {
+  private static class PropertyValue {
+    public String name, value;
+
+    public PropertyValue(String name, String value) {
+      this.name = name;
+      this.value = value;
+    }
+  }
+
+  @WithProperties({...@property(name = "name", value = "value")})
+  public void methodWithSingleProperty() {
+  }
+
+  @WithProperties({
+      @Property(name = "name2", value = "value2"),
+      @Property(name = "name1", value = "value1")})
+  public void methodWithTwoProperties() {
+  }
+
+  public void methodWithoutProperties() {
+  }
+
+  public void testGetSyntheticModuleExtension() {
+    assertEquals("JUnit.name$value",
+        getStrategyForSingleProperty().getSyntheticModuleExtension());
+    assertEquals("JUnit.name1$value1.name2$value2",
+        getStrategyForTwoProperties().getSyntheticModuleExtension());
+    assertEquals("JUnit",
+        getStrategyForNoProperty().getSyntheticModuleExtension());
+  }
+
+  public void testProcessModuleForTestCaseWithSingleProperty() {
+    ModuleDef module = new ModuleDef("myModule");
+    getStrategyForSingleProperty().processModule(module);
+    assertProperties(module, p("name", "value"));
+  }
+
+  public void testProcessModuleForTestCaseWithTwoProperties() {
+    ModuleDef module = new ModuleDef("myModule");
+    getStrategyForTwoProperties().processModule(module);
+    assertProperties(module, p("name1", "value1"), p("name2", "value2"));
+  }
+
+  public void testProcessModuleForTestCaseWithoutProperties() {
+    ModuleDef module = new ModuleDef("myModule");
+    getStrategyForNoProperty().processModule(module);
+    assertProperties(module);
+  }
+
+  private void assertProperties(ModuleDef module, PropertyValue... props) {
+    SortedSet<BindingProperty> properties =  
module.getProperties().getBindingProperties();
+    assertEquals(props.length, properties.size());
+    int i = 0;
+    for (BindingProperty property : properties) {
+      assertEquals("property " + i, props[i].name, property.getName());
+      assertEquals("property " + i, props[i].value,
+          property.getConstrainedValue());
+      i++;
+    }
+  }
+
+  private static PropertyValue p(String name, String value) {
+    return new PropertyValue(name, value);
+  }
+
+  private PropertyDefiningStrategy getStrategyForSingleProperty() {
+    TestCase result = new PropertyDefiningStrategyTest();
+    result.setName("methodWithSingleProperty");
+    return new PropertyDefiningStrategy(result);
+  }
+
+  private PropertyDefiningStrategy getStrategyForTwoProperties() {
+    TestCase result = new PropertyDefiningStrategyTest();
+    result.setName("methodWithTwoProperties");
+    return new PropertyDefiningStrategy(result);
+  }
+
+  private PropertyDefiningStrategy getStrategyForNoProperty() {
+    TestCase result = new PropertyDefiningStrategyTest();
+    result.setName("methodWithoutProperties");
+    return new PropertyDefiningStrategy(result);
+  }
+}
=======================================
--- /dev/null
+++  
/trunk/user/test/com/google/gwt/junit/client/PropertyDefiningGWTTest.java       
 
Tue Oct 20 11:31:25 2009
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009 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.junit.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.junit.client.WithProperties.Property;
+
+import java.util.Date;
+
+/**
+ * A {...@link GWTTestCase} that defines module properties.
+ */
+public class PropertyDefiningGWTTest extends GWTTestCase {
+  /**
+   * Base interface used for testing.
+   */
+  public static interface TestInterface {
+    String value();
+  }
+
+  /**
+   * Implementation used in one deferred binding.
+   */
+  public static class TestImplOne implements TestInterface {
+    public String value() {
+      return "one";
+    }
+  }
+
+  /**
+   * Implementation used in the other deferred binding.
+   */
+  public static class TestImplTwo implements TestInterface {
+    public String value() {
+      return "two";
+    }
+  }
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.junit.JUnitTestWithProperties";
+  }
+
+  @WithProperties({
+    @Property(name = "locale", value = "en_US"),
+    @Property(name = "my.property", value = "one")
+  })
+  public void testInUSLocaleAndPropertyOne() {
+    assertEquals("June", DateTimeFormat.getFormat("MMMM").format(new  
Date(99, 5, 13)));
+    assertEquals("one", GWT.<TestInterface>  
create(TestInterface.class).value());
+  }
+
+  @WithProperties({
+    @Property(name = "locale", value = "de_CH"),
+    @Property(name = "my.property", value = "two")
+  })
+  public void testInSwissLocaleAndPropertyTwo() {
+    assertEquals("Juni", DateTimeFormat.getFormat("MMMM").format(new  
Date(99, 5, 13)));
+    assertEquals("two", GWT.<TestInterface>  
create(TestInterface.class).value());
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/benchmarks/client/Benchmark.java     Tue Sep 
 
15 11:52:45 2009
+++ /trunk/user/src/com/google/gwt/benchmarks/client/Benchmark.java     Tue Oct 
 
20 11:31:25 2009
@@ -17,6 +17,7 @@

  import com.google.gwt.benchmarks.BenchmarkShell;
  import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
+import com.google.gwt.junit.PropertyDefiningStrategy;
  import com.google.gwt.junit.JUnitShell.Strategy;
  import com.google.gwt.junit.client.GWTTestCase;
  import com.google.gwt.junit.client.impl.JUnitResult;
@@ -107,31 +108,34 @@
    /**
     * The {...@link Strategy} used for benchmarking.
     */
-  private static Strategy BENCHMARK_STRATEGY = new Strategy() {
+  public static class BenchmarkStrategy extends PropertyDefiningStrategy {
+    public BenchmarkStrategy(TestCase test) {
+      super(test);
+    }
+
+    @Override
      public String getModuleInherit() {
        return "com.google.gwt.benchmarks.Benchmarks";
      }

-    public String getSyntheticModuleExtension() {
-      return "Benchmarks";
-    }
-
+    @Override
      public void processResult(TestCase testCase, JUnitResult result) {
+      super.processResult(testCase, result);
        if (result instanceof BenchmarkResults) {
          BenchmarkShell.getReport().addBenchmarkResults(testCase,
              (BenchmarkResults) result);
        }
      }
-  };
-
-  /**
-   * Get the {...@link Strategy} to use when compiling and running this test.
-   *
-   * @return the test {...@link Strategy}
-   */
+
+    @Override
+    protected String getBaseModuleExtension() {
+      return "Benchmarks";
+    }
+  }
+
    @Override
-  public Strategy getStrategy() {
-    return BENCHMARK_STRATEGY;
+  protected Strategy createStrategy() {
+    return new BenchmarkStrategy(this);
    }

    /**
=======================================
--- /trunk/user/src/com/google/gwt/junit/CompileStrategy.java   Tue Oct 13  
16:57:19 2009
+++ /trunk/user/src/com/google/gwt/junit/CompileStrategy.java   Tue Oct 20  
11:31:25 2009
@@ -182,6 +182,8 @@
          "junit.moduleName", false);
      moduleNameProp.setValue(syntheticModuleName);

+    strategy.processModule(moduleDef);
+
      junitShell.maybeCompileForWebMode(syntheticModuleName);

      return moduleDef;
=======================================
--- /trunk/user/src/com/google/gwt/junit/JUnitShell.java        Tue Oct 13  
16:57:19 2009
+++ /trunk/user/src/com/google/gwt/junit/JUnitShell.java        Tue Oct 20  
11:31:25 2009
@@ -94,6 +94,8 @@

      String getSyntheticModuleExtension();

+    void processModule(ModuleDef module);
+
      void processResult(TestCase testCase, JUnitResult result);
    }

=======================================
--- /trunk/user/src/com/google/gwt/junit/client/GWTTestCase.java        Wed Sep 
30  
12:07:05 2009
+++ /trunk/user/src/com/google/gwt/junit/client/GWTTestCase.java        Tue Oct 
20  
11:31:25 2009
@@ -15,7 +15,9 @@
   */
  package com.google.gwt.junit.client;

+import com.google.gwt.dev.cfg.ModuleDef;
  import com.google.gwt.junit.JUnitShell;
+import com.google.gwt.junit.PropertyDefiningStrategy;
  import com.google.gwt.junit.JUnitShell.Strategy;
  import com.google.gwt.junit.client.impl.JUnitResult;
  import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
@@ -43,6 +45,25 @@
   * </p>
   */
  public abstract class GWTTestCase extends TestCase {
+
+  /**
+   * The base class for strategies to use for tests.
+   */
+  public static class BaseStrategy implements Strategy {
+    public String getModuleInherit() {
+      return "com.google.gwt.junit.JUnit";
+    }
+
+    public String getSyntheticModuleExtension() {
+      return "JUnit";
+    }
+
+    public void processModule(ModuleDef module) {
+    }
+
+    public void processResult(TestCase testCase, JUnitResult result) {
+    }
+  }

    /**
     * Information about a synthetic module used for testing.
@@ -103,22 +124,6 @@
     */
    private static final Object ALL_GWT_TESTS_LOCK = new Object();

-  /**
-   * The default strategy to use for tests.
-   */
-  private static final Strategy DEFAULT_STRATEGY = new Strategy() {
-    public String getModuleInherit() {
-      return "com.google.gwt.junit.JUnit";
-    }
-
-    public String getSyntheticModuleExtension() {
-      return "JUnit";
-    }
-
-    public void processResult(TestCase testCase, JUnitResult result) {
-    }
-  };
-
    /**
     * Get the names of all test modules.
     *
@@ -158,6 +163,11 @@
     */
    protected TestResult testResult = null;

+  /**
+   * The {...@link Strategy} used by this test.
+   */
+  private Strategy strategy;
+
    /**
     * A new instance of your subclass is constructed for each test method  
that is
     * to be run. You should avoid running code in your subclass constructor,
@@ -246,7 +256,10 @@
     * @return the test {...@link Strategy}
     */
    public Strategy getStrategy() {
-    return DEFAULT_STRATEGY;
+    if (strategy == null) {
+      strategy = createStrategy();
+    }
+    return strategy;
    }

    /**
@@ -289,6 +302,13 @@
            new TestInfo(syntheticModuleName, getClass().getName(),  
getName()));
      }
    }
+
+  /**
+   * Creates the test strategy to use (see {...@link #getStrategy()}).
+   */
+  protected Strategy createStrategy() {
+    return new PropertyDefiningStrategy(this);
+  }

    /**
     * Put the current test in asynchronous mode. If the test method  
completes
=======================================
--- /trunk/user/src/com/google/gwt/junit/tools/GWTTestSuite.java        Tue Jun 
23  
17:40:28 2009
+++ /trunk/user/src/com/google/gwt/junit/tools/GWTTestSuite.java        Tue Oct 
20  
11:31:25 2009
@@ -80,7 +80,7 @@

      if (test instanceof GWTTestCase) {
        GWTTestCase gwtTest = (GWTTestCase) test;
-      String moduleName = gwtTest.getModuleName();
+      String moduleName = gwtTest.getSyntheticModuleName();
        if (moduleName != null) {
          TestSuite suite = moduleSuites.get(moduleName);
          if (suite == null) {
=======================================
--- /trunk/user/test/com/google/gwt/junit/JUnitSuite.java       Thu Oct  1  
10:34:33 2009
+++ /trunk/user/test/com/google/gwt/junit/JUnitSuite.java       Tue Oct 20  
11:31:25 2009
@@ -16,6 +16,7 @@
  package com.google.gwt.junit;

  import com.google.gwt.junit.client.GWTTestCaseTest;
+import com.google.gwt.junit.client.PropertyDefiningGWTTest;
  import com.google.gwt.junit.tools.GWTTestSuite;

  import junit.framework.Test;
@@ -50,6 +51,9 @@
      // Run manually only, launches servers that die on port contention
      // suite.addTestSuite(BrowserManagerServerTest.class);

+    suite.addTestSuite(PropertyDefiningStrategyTest.class);
+    suite.addTestSuite(PropertyDefiningGWTTest.class);
+
      return suite;
    }
  }

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

Reply via email to