JUnitified the TCK

git-svn-id: https://atinject.googlecode.com/svn/trunk@38 3bc8319c-20ab-11de-9edc-3f40a397ab60
diff --git a/tck/org/atinject/tck/Tester.java b/tck/org/atinject/tck/Tester.java
deleted file mode 100644
index c989c22..0000000
--- a/tck/org/atinject/tck/Tester.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2009 The JSR-330 Expert Group
- *
- * 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.atinject.tck;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class Tester {
-    private final List<String> problems = new ArrayList<String>();
-
-    /**
-     * @param problem a brief description of what went wrong.
-     */
-    public void addProblem(String problem) {
-        problems.add(problem);
-    }
-
-    /**
-     * Adds a problem if {@code condition} is not true.
-     *
-     * @param problem a brief description of what went wrong.
-     */
-    public void test(boolean condition, String problem) {
-        if (!condition) {
-            problems.add(problem);
-        }
-    }
-
-    public boolean hasProblems() {
-        return !problems.isEmpty();
-    }
-
-    public Iterable<String> problems() {
-        return problems;
-    }
-
-    public void addProblems(Collection<String> problems) {
-        this.problems.addAll(problems);
-    }
-}
diff --git a/tck/org/atinject/tck/auto/Car.java b/tck/org/atinject/tck/auto/Car.java
index 7441fc1..d312ee5 100644
--- a/tck/org/atinject/tck/auto/Car.java
+++ b/tck/org/atinject/tck/auto/Car.java
@@ -16,12 +16,6 @@
 
 package org.atinject.tck.auto;
 
-import org.atinject.tck.Tester;
-
 public interface Car {
 
-    /**
-     * Validates that this object was injected correctly.
-     */
-    void check(Tester tester);
 }
diff --git a/tck/org/atinject/tck/auto/Convertible.java b/tck/org/atinject/tck/auto/Convertible.java
index 06b8b1b..50c6b3c 100644
--- a/tck/org/atinject/tck/auto/Convertible.java
+++ b/tck/org/atinject/tck/auto/Convertible.java
@@ -16,17 +16,13 @@
 
 package org.atinject.tck.auto;
 
-import org.atinject.tck.Tester;
-import org.atinject.tck.auto.accessories.SpareTire;
-import org.atinject.tck.auto.accessories.Cupholder;
-
 import junit.framework.TestCase;
+import org.atinject.tck.auto.accessories.Cupholder;
+import org.atinject.tck.auto.accessories.SpareTire;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Provider;
-import java.util.ArrayList;
-import java.util.List;
 
 public class Convertible implements Car {
 
@@ -40,8 +36,6 @@
     private boolean methodWithMultipleParamsInjected;
     private boolean methodWithNonVoidReturnInjected;
 
-    private List<String> moreProblems = new ArrayList<String>();
-
     private Seat constructorPlainSeat;
     private Seat constructorDriversSeat;
     private Tire constructorPlainTire;
@@ -175,92 +169,6 @@
         };
     }
 
-    public void check(Tester tester) {
-        tester.addProblems(moreProblems);
-
-        tester.test(methodWithZeroParamsInjected, "Zero-parmeter method not injected");
-        tester.test(methodWithMultipleParamsInjected, "Multi-parameter method not injected");
-        tester.test(methodWithNonVoidReturnInjected, "Non-void method not injected");
-        tester.test(driversSeatA != driversSeatB, "@Singleton inherited from supertype");
-
-        testInjectedValues(tester);
-        testProviders(tester);
-
-        Engine engine = engineProvider.get();
-
-        if (spareTire == null || cupholder == null || engineProvider == null) {
-            tester.addProblem("Fields not injected");
-        } else {
-            spareTire.check(tester);
-            cupholder.check(tester);
-
-            if (engine == null) {
-                tester.addProblem("Provider returned null");
-            } else {
-                engine.check(tester);
-            }
-        }
-    }
-
-    private void testInjectedValues(Tester tester) {
-        testExpectedValues(tester, "injected constructor",
-                constructorPlainSeat, constructorDriversSeat, constructorPlainTire, constructorSpareTire);
-        testExpectedValues(tester, "provider injected into a constructor", constructorPlainSeatProvider.get(),
-                constructorDriversSeatProvider.get(), constructorPlainTireProvider.get(), constructorSpareTireProvider.get());
-        testExpectedValues(tester, "injected field",
-                fieldPlainSeat, fieldDriversSeat, fieldPlainTire, fieldSpareTire);
-        testExpectedValues(tester, "provider injected into a field", fieldPlainSeatProvider.get(),
-                fieldDriversSeatProvider.get(), fieldPlainTireProvider.get(), fieldSpareTireProvider.get());
-        testExpectedValues(tester, "injected method",
-                methodPlainSeat, methodDriversSeat, methodPlainTire, methodSpareTire);
-        testExpectedValues(tester, "provider injected into a method", methodPlainSeatProvider.get(),
-                methodDriversSeatProvider.get(), methodPlainTireProvider.get(), methodSpareTireProvider.get());
-        testExpectedValues(tester, "injected static field",
-                staticFieldPlainSeat, staticFieldDriversSeat, staticFieldPlainTire, staticFieldSpareTire);
-        testExpectedValues(tester, "provider injected into a static field", staticFieldPlainSeatProvider.get(),
-                staticFieldDriversSeatProvider.get(), staticFieldPlainTireProvider.get(), staticFieldSpareTireProvider.get());
-        testExpectedValues(tester, "injected static method",
-                staticMethodPlainSeat, staticMethodDriversSeat, staticMethodPlainTire, staticMethodSpareTire);
-        testExpectedValues(tester, "provider injected into a static method", staticMethodPlainSeatProvider.get(),
-                staticMethodDriversSeatProvider.get(), staticMethodPlainTireProvider.get(), staticMethodSpareTireProvider.get());
-    }
-
-    private void testProviders(Tester tester) {
-        testProviderProvidesNewValuesEachTime(tester,
-                constructorDriversSeatProvider, constructorPlainTireProvider, constructorSpareTireProvider);
-        testProviderProvidesNewValuesEachTime(tester,
-                fieldDriversSeatProvider, fieldPlainTireProvider, fieldSpareTireProvider);
-        testProviderProvidesNewValuesEachTime(tester,
-                methodDriversSeatProvider, methodPlainTireProvider, methodSpareTireProvider);
-        testProviderProvidesSameValueEachTime(tester, constructorPlainSeatProvider);
-        testProviderProvidesSameValueEachTime(tester, fieldPlainSeatProvider);
-        testProviderProvidesSameValueEachTime(tester, methodPlainSeatProvider);
-    }
-
-    private void testProviderProvidesSameValueEachTime(Tester tester, Provider<Seat> provider) {
-        tester.test(provider.get() == provider.get(),
-                "Different instance returned by repeated calls to Provider.get()");
-    }
-
-    private void testExpectedValues(Tester tester, String injectionMechanism,
-                Seat plainSeat, Seat driversSeat, Tire plainTire, Tire spareTire) {
-        tester.test(!(plainSeat instanceof DriversSeat),
-                "Wrong value injected for " + injectionMechanism);
-        tester.test(driversSeat instanceof DriversSeat,
-                "Wrong value injected for qualified " + injectionMechanism);
-        tester.test(!(plainTire instanceof SpareTire),
-                "Wrong value injected for " + injectionMechanism);
-        tester.test(spareTire instanceof SpareTire,
-                "Wrong value injected for @Named " + injectionMechanism);
-    }
-
-    private void testProviderProvidesNewValuesEachTime(Tester tester, Provider<?>... providers) {
-        for (Provider provider : providers) {
-            tester.test(provider.get() != provider.get(),
-                    "Same instance returned by repeated calls to Provider.get()");
-        }
-    }
-
     /**
      * Tests against the Convertible instance.
      */
@@ -269,13 +177,369 @@
         public static ThreadLocal<Convertible> localConvertible
                 = new ThreadLocal<Convertible>();
 
-        private final Car car = localConvertible.get();
+        private final Convertible car = localConvertible.get();
+        private final Cupholder cupholder = car.cupholder;
+        private final SpareTire spareTire = car.spareTire;
+        private final Engine engine = car.engineProvider.get();
 
-        public void testAll() {
-            Tester tester = new Tester();
-            car.check(tester);
-            assertFalse(tester.problems().toString(),
-                    tester.problems().iterator().hasNext());
+
+        // smoke tests: if these fail all bets are off
+
+        public void testFieldsInjected() {
+            assertTrue(cupholder != null && spareTire != null);
         }
+
+        public void testProviderReturnedValues() {
+            assertTrue(engine != null);
+        }
+
+
+        // injecting different kinds of members
+
+        public void testMethodWithZeroParametersInjected() {
+            assertTrue(car.methodWithZeroParamsInjected);
+        }
+
+        public void testMethodWithMultipleParametersInjected() {
+            assertTrue(car.methodWithMultipleParamsInjected);
+        }
+
+        public void testNonVoidMethodInjected() {
+            assertTrue(car.methodWithNonVoidReturnInjected);
+        }
+
+        public void testPublicNoArgsConstructorInjected() {
+            assertTrue(engine.publicNoArgsConstructorInjected);
+        }
+
+        public void testSubtypeFieldsInjected() {
+            assertTrue(spareTire.hasSpareTireBeenFieldInjected());
+        }
+
+        public void testSubtypeMethodsInjected() {
+            assertTrue(spareTire.hasSpareTireBeenMethodInjected());
+        }
+
+        public void testSupertypeFieldsInjected() {
+            assertTrue(spareTire.hasTireBeenFieldInjected());
+        }
+
+        public void testSupertypeMethodsInjected() {
+            assertTrue(spareTire.hasTireBeenMethodInjected());
+        }
+
+        public void testSubtypeStaticFieldsInjected() {
+            assertTrue(SpareTire.hasBeenStaticFieldInjected());
+        }
+
+        public void testSubtypeStaticMethodsInjected() {
+            assertTrue(SpareTire.hasBeenStaticMethodInjected());
+        }
+
+        public void testSupertypeStaticFieldsInjected() {
+            assertTrue(Tire.hasBeenStaticFieldInjected());
+        }
+
+        public void testSupertypeStaticMethodsInjected() {
+            assertTrue(Tire.hasBeenStaticMethodInjected());
+        }
+
+        public void testTwiceOverriddenMethodInjectedWhenMiddleLacksAnnotation() {
+            assertTrue(engine.overriddenTwiceWithOmissionInMiddleInjected);
+        }
+
+        // injected values
+
+        public void testQualifiersNotInheritedFromOverriddenMethod() {
+            assertFalse(engine.qualifiersInheritedFromOverriddenMethod);
+        }
+
+        public void testConstructorInjectionWithValues() {
+            assertFalse("Expected unqualified value",
+                    car.constructorPlainSeat instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.constructorPlainTire instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.constructorDriversSeat instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.constructorSpareTire instanceof SpareTire);
+        }
+
+        public void testFieldInjectionWithValues() {
+            assertFalse("Expected unqualified value",
+                    car.fieldPlainSeat instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.fieldPlainTire instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.fieldDriversSeat instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.fieldSpareTire instanceof SpareTire);
+        }
+
+        public void testMethodInjectionWithValues() {
+            assertFalse("Expected unqualified value",
+                    car.methodPlainSeat instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.methodPlainTire instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.methodDriversSeat instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.methodSpareTire instanceof SpareTire);
+        }
+
+        public void testStaticFieldInjectionWithValues() {
+            assertFalse("Expected unqualified value",
+                    staticFieldPlainSeat instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    staticFieldPlainTire instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    staticFieldDriversSeat instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    staticFieldSpareTire instanceof SpareTire);
+        }
+
+        public void testStaticMethodInjectionWithValues() {
+            assertFalse("Expected unqualified value",
+                    staticMethodPlainSeat instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    staticMethodPlainTire instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    staticMethodDriversSeat instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    staticMethodSpareTire instanceof SpareTire);
+        }
+
+
+        // injected providers
+
+        public void testConstructorInjectionWithProviders() {
+            assertFalse("Expected unqualified value",
+                    car.constructorPlainSeatProvider.get() instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.constructorPlainTireProvider.get() instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.constructorDriversSeatProvider.get() instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.constructorSpareTireProvider.get() instanceof SpareTire);
+        }
+
+        public void testFieldInjectionWithProviders() {
+            assertFalse("Expected unqualified value",
+                    car.fieldPlainSeatProvider.get() instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.fieldPlainTireProvider.get() instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.fieldDriversSeatProvider.get() instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.fieldSpareTireProvider.get() instanceof SpareTire);
+        }
+
+        public void testMethodInjectionWithProviders() {
+            assertFalse("Expected unqualified value",
+                    car.methodPlainSeatProvider.get() instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    car.methodPlainTireProvider.get() instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    car.methodDriversSeatProvider.get() instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    car.methodSpareTireProvider.get() instanceof SpareTire);
+        }
+
+        public void testStaticFieldInjectionWithProviders() {
+            assertFalse("Expected unqualified value",
+                    staticFieldPlainSeatProvider.get() instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    staticFieldPlainTireProvider.get() instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    staticFieldDriversSeatProvider.get() instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    staticFieldSpareTireProvider.get() instanceof SpareTire);
+        }
+
+        public void testStaticMethodInjectionWithProviders() {
+            assertFalse("Expected unqualified value",
+                    staticMethodPlainSeatProvider.get() instanceof DriversSeat);
+            assertFalse("Expected unqualified value",
+                    staticMethodPlainTireProvider.get() instanceof SpareTire);
+            assertTrue("Expected qualified value",
+                    staticMethodDriversSeatProvider.get() instanceof DriversSeat);
+            assertTrue("Expected qualified value",
+                    staticMethodSpareTireProvider.get() instanceof SpareTire);
+        }
+
+
+        // singletons
+
+        public void testConstructorInjectedProviderYieldsSingleton() {
+            assertSame("Expected same value",
+                    car.constructorPlainSeatProvider.get(), car.constructorPlainSeatProvider.get());
+        }
+
+        public void testFieldInjectedProviderYieldsSingleton() {
+            assertSame("Expected same value",
+                    car.fieldPlainSeatProvider.get(), car.fieldPlainSeatProvider.get());
+        }
+
+        public void testMethodInjectedProviderYieldsSingleton() {
+            assertSame("Expected same value",
+                    car.methodPlainSeatProvider.get(), car.methodPlainSeatProvider.get());
+        }
+
+        public void testCircularlyDependentSingletons() {
+            // uses provider.get() to get around circular deps
+            assertSame(cupholder.seatProvider.get().getCupholder(), cupholder);
+        }
+
+
+        // non singletons
+
+        public void testSingletonAnnotationNotInheritedFromSupertype() {
+            assertNotSame(car.driversSeatA, car.driversSeatB);
+        }
+
+        public void testConstructorInjectedProviderYieldsDistinctValues() {
+            assertNotSame("Expected distinct values",
+                    car.constructorDriversSeatProvider.get(), car.constructorDriversSeatProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.constructorPlainTireProvider.get(), car.constructorPlainTireProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.constructorSpareTireProvider.get(), car.constructorSpareTireProvider.get());
+        }
+
+        public void testFieldInjectedProviderYieldsDistinctValues() {
+            assertNotSame("Expected distinct values",
+                    car.fieldDriversSeatProvider.get(), car.fieldDriversSeatProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.fieldPlainTireProvider.get(), car.fieldPlainTireProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.fieldSpareTireProvider.get(), car.fieldSpareTireProvider.get());
+        }
+
+        public void testMethodInjectedProviderYieldsDistinctValues() {
+            assertNotSame("Expected distinct values",
+                    car.methodDriversSeatProvider.get(), car.methodDriversSeatProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.methodPlainTireProvider.get(), car.methodPlainTireProvider.get());
+            assertNotSame("Expected distinct values",
+                    car.methodSpareTireProvider.get(), car.methodSpareTireProvider.get());
+        }
+
+
+        // mix inheritance + visibility
+
+        public void testSupertypePrivateMethodInjected() {
+            assertTrue(spareTire.superPrivateMethodInjected);
+            assertTrue(spareTire.subPrivateMethodInjected);
+        }
+
+        public void testPackagePrivateMethodInjectedSamePackage() {
+            assertTrue(engine.subPackagePrivateMethodInjected);
+            assertFalse(engine.superPackagePrivateMethodInjected);
+        }
+
+        public void testPackagePrivateMethodInjectedDifferentPackages() {
+            assertTrue(spareTire.subPackagePrivateMethodInjected);
+            assertTrue(spareTire.superPackagePrivateMethodInjected);
+        }
+
+        public void testOverriddenProtectedMethodInjection() {
+            assertTrue(spareTire.subProtectedMethodInjected);
+            assertFalse(spareTire.superProtectedMethodInjected);
+        }
+
+        public void testOverriddenPublicMethodNotInjected() {
+            assertTrue(spareTire.subPublicMethodInjected);
+            assertFalse(spareTire.superPublicMethodInjected);
+        }
+
+
+        // inject in order
+
+        public void testFieldsInjectedBeforeMethods() {
+            assertFalse(spareTire.methodInjectedBeforeFields);
+        }
+
+        public void testStaticFieldsInjectedBeforeMethods() {
+            assertFalse(SpareTire.staticMethodInjectedBeforeStaticFields);
+        }
+
+        public void testSupertypeFieldsInjectedBeforeSubtypeMethods() {
+            assertFalse(spareTire.subtypeFieldInjectedBeforeSupertypeMethods);
+        }
+
+        public void testSupertypeMethodsInjectedBeforeSubtypeMethods() {
+            assertFalse(spareTire.subtypeMethodInjectedBeforeSupertypeMethods);
+        }
+
+        public void testSupertypeStaticMethodsInjectedBeforeSubtypeStaticFields() {
+            assertFalse(SpareTire.subtypeStaticFieldInjectedBeforeSupertypeStaticMethods);
+        }
+
+        public void testSupertypeStaticMethodsInjectedBeforeSubtypeStaticMethods() {
+            assertFalse(SpareTire.subtypeStaticMethodInjectedBeforeSupertypeStaticMethods);
+        }
+
+
+        // necessary injections occur
+
+        public void testPrivateMethodInjectedEvenWhenSimilarMethodLacksAnnotation() {
+            assertTrue(spareTire.subPrivateMethodForOverrideInjected);
+        }
+
+        public void testPackagePrivateMethodInjectedEvenWhenSimilarMethodLacksAnnotation() {
+            assertTrue(spareTire.subPackagePrivateMethodForOverrideInjected);
+        }
+
+
+        // override or similar method without @Inject
+
+        public void testPrivateMethodNotInjectedWhenSupertypeHasAnnotatedSimilarMethod() {
+            assertFalse(spareTire.superPrivateMethodForOverrideInjected);
+        }
+
+        public void testPackagePrivateMethodNotInjectedWhenOverrideLacksAnnotation() {
+            assertFalse(engine.subPackagePrivateMethodForOverrideInjected);
+            assertFalse(engine.superPackagePrivateMethodForOverrideInjected);
+        }
+
+        public void testPackagePrivateMethodNotInjectedWhenSupertypeHasAnnotatedSimilarMethod() {
+            assertFalse(spareTire.superPackagePrivateMethodForOverrideInjected);
+        }
+
+        public void testProtectedMethodNotInjectedWhenOverrideNotAnnotated() {
+            assertFalse(spareTire.protectedMethodForOverrideInjected);
+        }
+
+        public void testPublicMethodNotInjectedWhenOverrideNotAnnotated() {
+            assertFalse(spareTire.publicMethodForOverrideInjected);
+        }
+
+        public void testTwiceOverriddenMethodNotInjectedWhenOverrideLacksAnnotation() {
+            assertFalse(engine.overriddenTwiceWithOmissionInSubclassInjected);
+        }
+
+
+        // inject only once
+
+        public void testOverriddenPackagePrivateMethodInjectedOnlyOnce() {
+            assertFalse(engine.overriddenPackagePrivateMethodInjectedTwice);
+        }
+
+        public void testSimilarPrivateMethodInjectedOnlyOnce() {
+            assertFalse(spareTire.similarPrivateMethodInjectedTwice);
+        }
+
+        public void testSimilarPackagePrivateMethodInjectedOnlyOnce() {
+            assertFalse(spareTire.similarPackagePrivateMethodInjectedTwice);
+        }
+
+        public void testOverriddenProtectedMethodInjectedOnlyOnce() {
+            assertFalse(spareTire.overriddenProtectedMethodInjectedTwice);
+        }
+
+        public void testOverriddenPublicMethodInjectedOnlyOnce() {
+            assertFalse(spareTire.overriddenPublicMethodInjectedTwice);
+        }
+
     }
 }
diff --git a/tck/org/atinject/tck/auto/Engine.java b/tck/org/atinject/tck/auto/Engine.java
index 64ce6fe..e4231e5 100644
--- a/tck/org/atinject/tck/auto/Engine.java
+++ b/tck/org/atinject/tck/auto/Engine.java
@@ -17,20 +17,17 @@
 package org.atinject.tck.auto;
 
 import org.atinject.tck.auto.accessories.SpareTire;
-import org.atinject.tck.Tester;
 
 import javax.inject.Inject;
 import javax.inject.Named;
-import java.util.List;
-import java.util.ArrayList;
 
 public abstract class Engine {
 
-    protected final List<String> moreProblems = new ArrayList<String>();
-
     protected boolean publicNoArgsConstructorInjected;
-    protected boolean packagePrivateMethodInjected;
-    protected boolean packagePrivateMethodForOverrideInjected;
+    protected boolean subPackagePrivateMethodInjected;
+    protected boolean superPackagePrivateMethodInjected;
+    protected boolean subPackagePrivateMethodForOverrideInjected;
+    protected boolean superPackagePrivateMethodForOverrideInjected;
 
     protected boolean overriddenTwiceWithOmissionInMiddleInjected;
     protected boolean overriddenTwiceWithOmissionInSubclassInjected;
@@ -40,12 +37,15 @@
     protected Tire tireA;
     protected Tire tireB;
 
+    public boolean overriddenPackagePrivateMethodInjectedTwice;
+    public boolean qualifiersInheritedFromOverriddenMethod;
+
     @Inject void injectPackagePrivateMethod() {
-        moreProblems.add("Unexpected call to supertype package private method");
+        superPackagePrivateMethodInjected = true;
     }
 
     @Inject void injectPackagePrivateMethodForOverride() {
-        moreProblems.add("Unexpected call to supertype package private method");
+        superPackagePrivateMethodForOverrideInjected = true;
     }
 
     @Inject public void injectQualifiers(@Drivers Seat seatA, Seat seatB,
@@ -54,7 +54,7 @@
                 || (seatB instanceof DriversSeat)
                 || !(tireA instanceof SpareTire)
                 || (tireB instanceof SpareTire)) {
-            moreProblems.add("Qualifiers inherited from overridden methods");
+            qualifiersInheritedFromOverriddenMethod = true;
         }
     }
 
@@ -65,7 +65,4 @@
     @Inject public void injectTwiceOverriddenWithOmissionInSubclass() {
         overriddenTwiceWithOmissionInSubclassInjected = true;
     }
-
-    public abstract void check(Tester tester);
-
 }
diff --git a/tck/org/atinject/tck/auto/Seat.java b/tck/org/atinject/tck/auto/Seat.java
index 26fa5fe..4d41a20 100644
--- a/tck/org/atinject/tck/auto/Seat.java
+++ b/tck/org/atinject/tck/auto/Seat.java
@@ -18,8 +18,8 @@
 
 import org.atinject.tck.auto.accessories.Cupholder;
 
-import javax.inject.Singleton;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 
 @Singleton
 public class Seat {
diff --git a/tck/org/atinject/tck/auto/Tire.java b/tck/org/atinject/tck/auto/Tire.java
index 2110e82..9d4f665 100644
--- a/tck/org/atinject/tck/auto/Tire.java
+++ b/tck/org/atinject/tck/auto/Tire.java
@@ -52,60 +52,71 @@
     protected boolean protectedMethodForOverrideInjected;
     protected boolean publicMethodForOverrideInjected;
 
+    public boolean methodInjectedBeforeFields;
+    public boolean subtypeFieldInjectedBeforeSupertypeMethods;
+    public boolean subtypeMethodInjectedBeforeSupertypeMethods;
+    public static boolean staticMethodInjectedBeforeStaticFields;
+    public static boolean subtypeStaticFieldInjectedBeforeSupertypeStaticMethods;
+    public static boolean subtypeStaticMethodInjectedBeforeSupertypeStaticMethods;
+    public boolean similarPrivateMethodInjectedTwice;
+    public boolean similarPackagePrivateMethodInjectedTwice;
+    public boolean overriddenProtectedMethodInjectedTwice;
+    public boolean overriddenPublicMethodInjectedTwice;
+
     @Inject public Tire(FuelTank constructorInjection) {
         this.constructorInjection = constructorInjection;
     }
 
     @Inject void supertypeMethodInjection(FuelTank methodInjection) {
         if (!hasTireBeenFieldInjected()) {
-            moreProblems.add("Method injected before fields");
+            methodInjectedBeforeFields = true;
         }
         if (hasSpareTireBeenFieldInjected()) {
-            moreProblems.add("Subtype field injected before supertype method");
+            subtypeFieldInjectedBeforeSupertypeMethods = true;
         }
         if (hasSpareTireBeenMethodInjected()) {
-            moreProblems.add("Subtype method injected before supertype method");
+            subtypeMethodInjectedBeforeSupertypeMethods = true;
         }
         this.methodInjection = methodInjection;
     }
 
     @Inject static void supertypeStaticMethodInjection(FuelTank methodInjection) {
         if (!Tire.hasBeenStaticFieldInjected()) {
-            moreProblems.add("Static method injected before static fields");
+            staticMethodInjectedBeforeStaticFields = true;
         }
         if (SpareTire.hasBeenStaticFieldInjected()) {
-            moreProblems.add("Subtype static field injected before supertype static method");
+            subtypeStaticFieldInjectedBeforeSupertypeStaticMethods = true;
         }
         if (SpareTire.hasBeenStaticMethodInjected()) {
-            moreProblems.add("Subtype static method injected before supertype static method");
+            subtypeStaticMethodInjectedBeforeSupertypeStaticMethods = true;
         }
         staticMethodInjection = methodInjection;
     }
 
     @Inject private void injectPrivateMethod() {
         if (superPrivateMethodInjected) {
-            moreProblems.add("Overridden private method injected twice");
+            similarPrivateMethodInjectedTwice = true;
         }
         superPrivateMethodInjected = true;
     }
 
     @Inject void injectPackagePrivateMethod() {
         if (superPackagePrivateMethodInjected) {
-            moreProblems.add("Overridden package private method injected twice");
+            similarPackagePrivateMethodInjectedTwice = true;
         }
         superPackagePrivateMethodInjected = true;
     }
 
     @Inject protected void injectProtectedMethod() {
         if (superProtectedMethodInjected) {
-            moreProblems.add("Overridden protected method injected twice");
+            overriddenProtectedMethodInjectedTwice = true;
         }
         superProtectedMethodInjected = true;
     }
 
     @Inject public void injectPublicMethod() {
         if (superPublicMethodInjected) {
-            moreProblems.add("Overridden public method injected twice");
+            overriddenPublicMethodInjectedTwice = true;
         }
         superPublicMethodInjected = true;
     }
diff --git a/tck/org/atinject/tck/auto/V8Engine.java b/tck/org/atinject/tck/auto/V8Engine.java
index a721cf9..2dc7473 100644
--- a/tck/org/atinject/tck/auto/V8Engine.java
+++ b/tck/org/atinject/tck/auto/V8Engine.java
@@ -16,7 +16,6 @@
 
 package org.atinject.tck.auto;
 
-import org.atinject.tck.Tester;
 import org.atinject.tck.auto.accessories.SpareTire;
 
 import javax.inject.Inject;
@@ -29,10 +28,10 @@
     }
 
     @Inject void injectPackagePrivateMethod() {
-        if (packagePrivateMethodInjected) {
-            moreProblems.add("Overridden package private method injected twice");
+        if (subPackagePrivateMethodInjected) {
+            overriddenPackagePrivateMethodInjectedTwice = true;
         }
-        packagePrivateMethodInjected = true;
+        subPackagePrivateMethodInjected = true;
     }
 
     /**
@@ -44,12 +43,12 @@
                 || !(seatB instanceof DriversSeat)
                 || (tireA instanceof SpareTire)
                 || !(tireB instanceof SpareTire)) {
-            moreProblems.add("Qualifiers inherited from overridden methods");
+            qualifiersInheritedFromOverriddenMethod = true;
         }
     }
 
     void injectPackagePrivateMethodForOverride() {
-        packagePrivateMethodForOverrideInjected = true;
+        subPackagePrivateMethodForOverrideInjected = true;
     }
 
     @Inject public void injectTwiceOverriddenWithOmissionInMiddle() {
@@ -59,18 +58,4 @@
     public void injectTwiceOverriddenWithOmissionInSubclass() {
         overriddenTwiceWithOmissionInSubclassInjected = true;
     }
-
-    public void check(Tester tester) {
-        tester.addProblems(moreProblems);
-
-        tester.test(publicNoArgsConstructorInjected, "Public no-args constructor not injected");
-        tester.test(packagePrivateMethodInjected, "Packge private method not injected");
-        tester.test(!packagePrivateMethodForOverrideInjected,
-                "Package private method injected, even though its override lacks @Inject");
-
-        tester.test(overriddenTwiceWithOmissionInMiddleInjected,
-                "Twice-overridden method not injected; middle override lacks @Inject");
-        tester.test(!overriddenTwiceWithOmissionInSubclassInjected,
-                "Twice-overridden method injected, even though its override lacks @Inject");
-    }
 }
diff --git a/tck/org/atinject/tck/auto/accessories/Cupholder.java b/tck/org/atinject/tck/auto/accessories/Cupholder.java
index 1a2ca6d..fec70a4 100644
--- a/tck/org/atinject/tck/auto/accessories/Cupholder.java
+++ b/tck/org/atinject/tck/auto/accessories/Cupholder.java
@@ -17,29 +17,18 @@
 package org.atinject.tck.auto.accessories;
 
 import org.atinject.tck.auto.Seat;
-import org.atinject.tck.Tester;
 
-import javax.inject.Singleton;
-import javax.inject.Provider;
 import javax.inject.Inject;
-import java.util.List;
-import java.util.ArrayList;
+import javax.inject.Provider;
+import javax.inject.Singleton;
 
 @Singleton
 public class Cupholder {
 
-    protected final List<String> moreProblems = new ArrayList<String>();
-
-    private final Provider<Seat> seatProvider;
+    public final Provider<Seat> seatProvider;
 
     @Inject
     public Cupholder(Provider<Seat> seatProvider) {
         this.seatProvider = seatProvider;
     }
-
-    public void check(Tester tester) {
-        tester.addProblems(moreProblems);
-
-        tester.test(seatProvider.get().getCupholder() == this, "Circularly dependent singletons not singleton");
-    }
 }
diff --git a/tck/org/atinject/tck/auto/accessories/SpareTire.java b/tck/org/atinject/tck/auto/accessories/SpareTire.java
index 998574f..e9a7eb2 100644
--- a/tck/org/atinject/tck/auto/accessories/SpareTire.java
+++ b/tck/org/atinject/tck/auto/accessories/SpareTire.java
@@ -16,7 +16,6 @@
 
 package org.atinject.tck.auto.accessories;
 
-import org.atinject.tck.Tester;
 import org.atinject.tck.auto.FuelTank;
 import org.atinject.tck.auto.Tire;
 
@@ -37,42 +36,42 @@
 
     @Inject void subtypeMethodInjection(FuelTank methodInjection) {
         if (!hasSpareTireBeenFieldInjected()) {
-            moreProblems.add("Methods injected before fields");
+            methodInjectedBeforeFields = true;
         }
         this.methodInjection = methodInjection;
     }
 
     @Inject static void subtypeStaticMethodInjection(FuelTank methodInjection) {
         if (!hasBeenStaticFieldInjected()) {
-            moreProblems.add("Static methods injected before static fields");
+            staticMethodInjectedBeforeStaticFields = true;
         }
         staticMethodInjection = methodInjection;
     }
 
     @Inject private void injectPrivateMethod() {
         if (subPrivateMethodInjected) {
-            moreProblems.add("Overridden private method injected twice");
+            similarPrivateMethodInjectedTwice = true;
         }
         subPrivateMethodInjected = true;
     }
 
     @Inject void injectPackagePrivateMethod() {
         if (subPackagePrivateMethodInjected) {
-            moreProblems.add("Overridden package private method injected twice");
+            similarPackagePrivateMethodInjectedTwice = true;
         }
         subPackagePrivateMethodInjected = true;
     }
 
     @Inject protected void injectProtectedMethod() {
         if (subProtectedMethodInjected) {
-            moreProblems.add("Overridden protected method injected twice");
+            overriddenProtectedMethodInjectedTwice = true;
         }
         subProtectedMethodInjected = true;
     }
 
     @Inject public void injectPublicMethod() {
         if (subPublicMethodInjected) {
-            moreProblems.add("Overridden public method injected twice");
+            overriddenPublicMethodInjectedTwice = true;
         }
         subPublicMethodInjected = true;
     }
@@ -93,11 +92,11 @@
         publicMethodForOverrideInjected = true;
     }
 
-    protected boolean hasSpareTireBeenFieldInjected() {
+    public boolean hasSpareTireBeenFieldInjected() {
         return fieldInjection != NEVER_INJECTED;
     }
 
-    protected boolean hasSpareTireBeenMethodInjected() {
+    public boolean hasSpareTireBeenMethodInjected() {
         return methodInjection != NEVER_INJECTED;
     }
 
@@ -108,44 +107,4 @@
     public static boolean hasBeenStaticMethodInjected() {
         return staticMethodInjection != NEVER_INJECTED;
     }
-
-    /**
-     * This class is used to check inheritance. By existing in a separate package
-     * from Tire, it can make sure the injector does the right thing with overrides
-     * of package-private methods.
-     */
-    public void check(Tester tester) {
-        tester.addProblems(moreProblems);
-
-        tester.test(hasSpareTireBeenFieldInjected(), "Subtype fields not injected");
-        tester.test(hasSpareTireBeenMethodInjected(), "Subtype methods not injected");
-        tester.test(hasTireBeenFieldInjected(), "Supertype fields not injected");
-        tester.test(hasTireBeenMethodInjected(), "Supertype methods not injected");
-        tester.test(SpareTire.hasBeenStaticFieldInjected(), "Subtype static fields not injected");
-        tester.test(SpareTire.hasBeenStaticMethodInjected(), "Subtype static methods not injected");
-        tester.test(Tire.hasBeenStaticFieldInjected(), "Supertype static fields not injected");
-        tester.test(Tire.hasBeenStaticMethodInjected(), "Supertype static methods not injected");
-
-        tester.test(superPrivateMethodInjected, "Supertype private method not injected");
-        tester.test(superPackagePrivateMethodInjected, "Supertype private method not injected");
-        tester.test(!superProtectedMethodInjected, "Overridden protected method injected!");
-        tester.test(!superPublicMethodInjected, "Overridden public method injected!");
-        tester.test(subPrivateMethodInjected, "Subtype private method not injected");
-        tester.test(subPackagePrivateMethodInjected, "Subtype private method not injected");
-        tester.test(subProtectedMethodInjected, "Subtype protected method not injected");
-        tester.test(subPublicMethodInjected, "Subtype public method not injected");
-
-        tester.test(subPrivateMethodForOverrideInjected,
-                "Private method not injected when a subtype has a similar method that lacks @Inject");
-        tester.test(subPackagePrivateMethodForOverrideInjected,
-                "Package private method not injected when a subtype has a similar method that lacks @Inject");
-        tester.test(!superPrivateMethodForOverrideInjected,
-                "Private method injected when a supertype has a similar method annotated @Inject");
-        tester.test(!superPackagePrivateMethodForOverrideInjected,
-                "Package private method injected when a supertype has a similar method annotated @Inject");
-        tester.test(!protectedMethodForOverrideInjected,
-                "Protected method injected, even though its override lacks @Inject");
-        tester.test(!publicMethodForOverrideInjected,
-                "Public method injected, even though its override lacks @Inject");
-    }
 }