Repository: incubator-beam
Updated Branches:
  refs/heads/master 05c6c2749 -> b304d037f


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/75c8bb8d/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTest.java
 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTest.java
index 447b993..fc468c9 100644
--- 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTest.java
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTest.java
@@ -17,10 +17,11 @@
  */
 package org.apache.beam.sdk.transforms.reflect;
 
+import static 
org.apache.beam.sdk.transforms.reflect.DoFnSignaturesTestUtils.errors;
+
 import com.google.common.reflect.TypeToken;
-import java.lang.reflect.Method;
-import java.util.List;
 import org.apache.beam.sdk.transforms.DoFn;
+import org.apache.beam.sdk.transforms.reflect.DoFnSignaturesTestUtils.FakeDoFn;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -33,257 +34,21 @@ public class DoFnSignaturesTest {
 
   @Rule public ExpectedException thrown = ExpectedException.none();
 
-  private static class FakeDoFn extends DoFn<Integer, String> {}
-
-  @SuppressWarnings({"unused"})
-  private void missingProcessContext() {}
-
-  @Test
-  public void testMissingProcessContext() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        getClass().getName()
-            + "#missingProcessContext() must take a ProcessContext<> as its 
first argument");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        getClass().getDeclaredMethod("missingProcessContext"),
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  @SuppressWarnings({"unused"})
-  private void badProcessContext(String s) {}
-
-  @Test
-  public void testBadProcessContextType() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        getClass().getName()
-            + "#badProcessContext(String) must take a ProcessContext<> as its 
first argument");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        getClass().getDeclaredMethod("badProcessContext", String.class),
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  @SuppressWarnings({"unused"})
-  private void badExtraContext(DoFn<Integer, String>.Context c, int n) {}
-
   @Test
   public void testBadExtraContext() throws Exception {
     thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        getClass().getName()
-            + "#badExtraContext(Context, int) must have a single argument of 
type Context");
+    thrown.expectMessage("Must take a single argument of type Context");
 
     DoFnSignatures.analyzeBundleMethod(
+        errors(),
         TypeToken.of(FakeDoFn.class),
-        getClass().getDeclaredMethod("badExtraContext", DoFn.Context.class, 
int.class),
+        new DoFnSignaturesTestUtils.AnonymousMethod() {
+          void method(DoFn<Integer, String>.Context c, int n) {}
+        }.getMethod(),
         TypeToken.of(Integer.class),
         TypeToken.of(String.class));
   }
 
-  @SuppressWarnings({"unused"})
-  private void badExtraProcessContext(DoFn<Integer, String>.ProcessContext c, 
Integer n) {}
-
-  @Test
-  public void testBadExtraProcessContextType() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        "Integer is not a valid context parameter for method "
-            + getClass().getName()
-            + "#badExtraProcessContext(ProcessContext, Integer)"
-            + ". Should be one of [BoundedWindow]");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        getClass()
-            .getDeclaredMethod("badExtraProcessContext", 
DoFn.ProcessContext.class, Integer.class),
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  @SuppressWarnings("unused")
-  private int badReturnType() {
-    return 0;
-  }
-
-  @Test
-  public void testBadReturnType() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(getClass().getName() + "#badReturnType() must have a 
void return type");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        getClass().getDeclaredMethod("badReturnType"),
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  @SuppressWarnings("unused")
-  private void goodConcreteTypes(
-      DoFn<Integer, String>.ProcessContext c,
-      DoFn.InputProvider<Integer> input,
-      DoFn.OutputReceiver<String> output) {}
-
-  @Test
-  public void testGoodConcreteTypes() throws Exception {
-    Method method =
-        getClass()
-            .getDeclaredMethod(
-                "goodConcreteTypes",
-                DoFn.ProcessContext.class,
-                DoFn.InputProvider.class,
-                DoFn.OutputReceiver.class);
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        method,
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  private static class GoodTypeVariables<InputT, OutputT> extends DoFn<InputT, 
OutputT> {
-    @ProcessElement
-    @SuppressWarnings("unused")
-    public void goodTypeVariables(
-        DoFn<InputT, OutputT>.ProcessContext c,
-        DoFn.InputProvider<InputT> input,
-        DoFn.OutputReceiver<OutputT> output) {}
-  }
-
-  @Test
-  public void testGoodTypeVariables() throws Exception {
-    DoFnSignatures.INSTANCE.getOrParseSignature(GoodTypeVariables.class);
-  }
-
-  private static class IdentityFn<T> extends DoFn<T, T> {
-    @ProcessElement
-    @SuppressWarnings("unused")
-    public void processElement(ProcessContext c, InputProvider<T> input, 
OutputReceiver<T> output) {
-      c.output(c.element());
-    }
-  }
-
-  private static class IdentityListFn<T> extends IdentityFn<List<T>> {}
-
-  @Test
-  public void testIdentityFnApplied() throws Exception {
-    DoFnSignatures.INSTANCE.getOrParseSignature(new IdentityFn<String>() 
{}.getClass());
-  }
-
-  @SuppressWarnings("unused")
-  private void badGenericTwoArgs(
-      DoFn<Integer, String>.ProcessContext c,
-      DoFn.InputProvider<Integer> input,
-      DoFn.OutputReceiver<Integer> output) {}
-
-  @Test
-  public void testBadGenericsTwoArgs() throws Exception {
-    Method method =
-        getClass()
-            .getDeclaredMethod(
-                "badGenericTwoArgs",
-                DoFn.ProcessContext.class,
-                DoFn.InputProvider.class,
-                DoFn.OutputReceiver.class);
-
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        "Wrong type of OutputReceiver parameter "
-            + "for method "
-            + getClass().getName()
-            + "#badGenericTwoArgs(ProcessContext, InputProvider, 
OutputReceiver): "
-            + "OutputReceiver<Integer>, should be "
-            + "OutputReceiver<String>");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        method,
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  @SuppressWarnings("unused")
-  private void badGenericWildCards(
-      DoFn<Integer, String>.ProcessContext c,
-      DoFn.InputProvider<Integer> input,
-      DoFn.OutputReceiver<? super Integer> output) {}
-
-  @Test
-  public void testBadGenericWildCards() throws Exception {
-    Method method =
-        getClass()
-            .getDeclaredMethod(
-                "badGenericWildCards",
-                DoFn.ProcessContext.class,
-                DoFn.InputProvider.class,
-                DoFn.OutputReceiver.class);
-
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        "Wrong type of OutputReceiver parameter for method "
-            + getClass().getName()
-            + "#badGenericWildCards(ProcessContext, InputProvider, 
OutputReceiver): "
-            + "OutputReceiver<? super Integer>, should be "
-            + "OutputReceiver<String>");
-
-    DoFnSignatures.analyzeProcessElementMethod(
-        TypeToken.of(FakeDoFn.class),
-        method,
-        TypeToken.of(Integer.class),
-        TypeToken.of(String.class));
-  }
-
-  static class BadTypeVariables<InputT, OutputT> extends DoFn<InputT, OutputT> 
{
-    @ProcessElement
-    @SuppressWarnings("unused")
-    public void badTypeVariables(
-        DoFn<InputT, OutputT>.ProcessContext c,
-        DoFn.InputProvider<InputT> input,
-        DoFn.OutputReceiver<InputT> output) {}
-  }
-
-  @Test
-  public void testBadTypeVariables() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage(
-        "Wrong type of OutputReceiver parameter for method "
-            + BadTypeVariables.class.getName()
-            + "#badTypeVariables(ProcessContext, InputProvider, 
OutputReceiver): "
-            + "OutputReceiver<InputT>, should be "
-            + "OutputReceiver<OutputT>");
-
-    DoFnSignatures.INSTANCE.getOrParseSignature(BadTypeVariables.class);
-  }
-
-  @Test
-  public void testNoProcessElement() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("No method annotated with @ProcessElement found");
-    thrown.expectMessage(getClass().getName() + "$");
-    DoFnSignatures.INSTANCE.getOrParseSignature(new DoFn<String, String>() 
{}.getClass());
-  }
-
-  @Test
-  public void testMultipleProcessElement() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("Found multiple methods annotated with 
@ProcessElement");
-    thrown.expectMessage("foo()");
-    thrown.expectMessage("bar()");
-    thrown.expectMessage(getClass().getName() + "$");
-    DoFnSignatures.INSTANCE.getOrParseSignature(
-        new DoFn<String, String>() {
-          @ProcessElement
-          public void foo() {}
-
-          @ProcessElement
-          public void bar() {}
-        }.getClass());
-  }
-
   @Test
   public void testMultipleStartBundleElement() throws Exception {
     thrown.expect(IllegalArgumentException.class);
@@ -325,21 +90,10 @@ public class DoFnSignaturesTest {
   }
 
   @Test
-  public void testPrivateProcessElement() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("process() must be public");
-    thrown.expectMessage(getClass().getName() + "$");
-    DoFnSignatures.INSTANCE.getOrParseSignature(
-        new DoFn<String, String>() {
-          @ProcessElement
-          private void process() {}
-        }.getClass());
-  }
-
-  @Test
   public void testPrivateStartBundle() throws Exception {
     thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("startBundle() must be public");
+    thrown.expectMessage("startBundle()");
+    thrown.expectMessage("Must be public");
     thrown.expectMessage(getClass().getName() + "$");
     DoFnSignatures.INSTANCE.getOrParseSignature(
         new DoFn<String, String>() {
@@ -354,7 +108,8 @@ public class DoFnSignaturesTest {
   @Test
   public void testPrivateFinishBundle() throws Exception {
     thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("finishBundle() must be public");
+    thrown.expectMessage("finishBundle()");
+    thrown.expectMessage("Must be public");
     thrown.expectMessage(getClass().getName() + "$");
     DoFnSignatures.INSTANCE.getOrParseSignature(
         new DoFn<String, String>() {

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/75c8bb8d/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTestUtils.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTestUtils.java
 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTestUtils.java
new file mode 100644
index 0000000..88dc423
--- /dev/null
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/DoFnSignaturesTestUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.beam.sdk.transforms.reflect;
+
+import com.google.common.reflect.TypeToken;
+import java.lang.reflect.Method;
+import java.util.NoSuchElementException;
+import org.apache.beam.sdk.transforms.DoFn;
+
+/** Utilities for use in {@link DoFnSignatures} tests. */
+class DoFnSignaturesTestUtils {
+  /** An empty base {@link DoFn} class. */
+  static class FakeDoFn extends DoFn<Integer, String> {}
+
+  /** An error reporter. */
+  static DoFnSignatures.ErrorReporter errors() {
+    return new DoFnSignatures.ErrorReporter(null, "[test]");
+  }
+
+  /**
+   * A class for testing utilities that take {@link Method} objects. Use like 
this:
+   *
+   * <pre>{@code
+   * Method m = new AnonymousMethod() {
+   *   SomeReturnValue method(SomeParameters...) { ... }
+   * }.getMethod();  // Will return the Method for "method".
+   * }</pre>
+   */
+  static class AnonymousMethod {
+    final Method getMethod() throws Exception {
+      for (Method method : getClass().getDeclaredMethods()) {
+        if (method.getName().equals("method")) {
+          return method;
+        }
+      }
+      throw new NoSuchElementException("No method named 'method' defined on " 
+ getClass());
+    }
+  }
+
+  static DoFnSignature.ProcessElementMethod 
analyzeProcessElementMethod(AnonymousMethod method)
+      throws Exception {
+    return DoFnSignatures.analyzeProcessElementMethod(
+        errors(),
+        TypeToken.of(FakeDoFn.class),
+        method.getMethod(),
+        TypeToken.of(Integer.class),
+        TypeToken.of(String.class));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/75c8bb8d/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/testhelper/DoFnInvokersTestHelper.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/testhelper/DoFnInvokersTestHelper.java
 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/testhelper/DoFnInvokersTestHelper.java
new file mode 100644
index 0000000..c20a788
--- /dev/null
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/reflect/testhelper/DoFnInvokersTestHelper.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.beam.sdk.transforms.reflect.testhelper;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.verify;
+
+import org.apache.beam.sdk.transforms.DoFn;
+import org.apache.beam.sdk.transforms.reflect.DoFnInvokersTest;
+
+/**
+ * Test helper for {@link DoFnInvokersTest}, which needs to test 
package-private access to DoFns in
+ * other packages.
+ */
+public class DoFnInvokersTestHelper {
+
+  private static class StaticPrivateDoFn extends DoFn<String, String> {
+    @ProcessElement
+    public void process(ProcessContext c) {}
+  }
+
+  private class InnerPrivateDoFn extends DoFn<String, String> {
+    @ProcessElement
+    public void process(ProcessContext c) {}
+  }
+
+  static class StaticPackagePrivateDoFn extends DoFn<String, String> {
+    @ProcessElement
+    public void process(ProcessContext c) {}
+  }
+
+  class InnerPackagePrivateDoFn extends DoFn<String, String> {
+    @ProcessElement
+    public void process(ProcessContext c) {}
+  }
+
+  public static DoFn<String, String> newStaticPackagePrivateDoFn() {
+    return new StaticPackagePrivateDoFn();
+  }
+
+  public static void verifyStaticPackagePrivateDoFn(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) {
+    verify((StaticPackagePrivateDoFn) fn).process(context);
+  }
+
+  public DoFn<String, String> newInnerPackagePrivateDoFn() {
+    return new InnerPackagePrivateDoFn();
+  }
+
+  public static void verifyInnerPackagePrivateDoFn(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) {
+    verify((InnerPackagePrivateDoFn) fn).process(context);
+  }
+
+  public static DoFn<String, String> newStaticPrivateDoFn() {
+    return new StaticPrivateDoFn();
+  }
+
+  public static void verifyStaticPrivateDoFn(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) {
+    verify((StaticPrivateDoFn) fn).process(context);
+  }
+
+  public DoFn<String, String> newInnerPrivateDoFn() {
+    return new InnerPrivateDoFn();
+  }
+
+  public static void verifyInnerPrivateDoFn(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) {
+    verify((InnerPrivateDoFn) fn).process(context);
+  }
+
+  public DoFn<String, String> newInnerAnonymousDoFn() {
+    return new DoFn<String, String>() {
+      @ProcessElement
+      public void process(ProcessContext c) {}
+    };
+  }
+
+  public static void verifyInnerAnonymousDoFn(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) 
throws Exception {
+    DoFn<String, String> verifier = verify(fn);
+    verifier.getClass().getMethod("process", 
DoFn.ProcessContext.class).invoke(verifier, context);
+  }
+
+  public static DoFn<String, String> newStaticAnonymousDoFn() {
+    return new DoFn<String, String>() {
+      private DoFn<String, String>.ProcessContext invokedContext;
+
+      @ProcessElement
+      public void process(ProcessContext c) {
+        assertNull("Should have been invoked just once", invokedContext);
+        invokedContext = c;
+      }
+
+      @SuppressWarnings("unused")
+      public void verify(DoFn<String, String>.ProcessContext context) {
+        assertEquals(context, invokedContext);
+      }
+    };
+  }
+
+  public static void verifyStaticAnonymousDoFnInvoked(
+      DoFn<String, String> fn, DoFn<String, String>.ProcessContext context) 
throws Exception {
+
+    fn.getClass().getMethod("verify", DoFn.ProcessContext.class).invoke(fn, 
context);
+  }
+}

Reply via email to