diff --git a/README.md b/README.md
index 347c21f..151646a 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ Release version
contracts-cmdline
-----------------
-contracts-cmdline is the model that encompasses the command line tools that will generate reports equivalent ot the maven contracts plugin.
+contracts-cmdline is the model that encompasses the command line tools that will generate reports equivalent to the maven contracts plugin.
Release version
@@ -540,12 +540,28 @@ Indicates that the method is a getter that provides the IProducer to inject or a
ContractImpl
------------
-Indentifies the implementation class that is being tested. The argument is the class for which an instance will be created. The __ignore__ property may specify contract tests that should not be executed.
+Identifies the implementation class that is being tested.
+
+ContractImpl has two attributes that can remove tests.
+
+* skip is an array of interface classes that should not be tested. All contract tests for the interfaces will be skipped.
+
+* ignore list any @Contract annotated tests that should be ignored. This allows removal of broken
+tests that are outside the control of the developer of the @ContractImpl test.
+
+ContractExclude
+---------------
+
+ContractExclude is intended to be used with @ContractImpl. The annotation has 2 arguments
+1. value is the name of the class that contains the test to exclude.
+2. methods is a list of method names in the test class to exclude.
+
+This annotation will remove the tests only for the ContractImpl it is associated with.
ContractTest
------------
-Like a JUnit Test annotation but requries that the test be run within the ContractSuite runner.
+Like a JUnit Test annotation but requires that the test be run within the ContractSuite runner. Contract tests may be annotated with the standard JUnit @Ignore annotation to disable the test for all contract suites.
Dynamic.Inject
--------------
diff --git a/junit/README.md b/junit/README.md
index 49a907c..a0d14d2 100644
--- a/junit/README.md
+++ b/junit/README.md
@@ -4,7 +4,7 @@ junit-contracts: A contract test suite runner
A suite runner for use with JUnit @RunWith annotation to run contract tests for interfaces. Handles merging multiple tests from individual
contract tests into a single test suite for concrete implementations of one or more interfaces.
-Introduces six annotations:
+Introduces seven annotations:
* @Contract - To map contract tests to the interfaces they test.
* @Contract.Inject - To identify the producer of the object under test.
@@ -13,6 +13,7 @@ Introduces six annotations:
* @Dynamic.Inject - To identify the master producer for dynamic suites.
* @NoContractTest - To identify interfaces that should not or do not yet have contract tests. This only applies to interfaces that have methods as pure marker
interfaces are automatically ignored.
+* @ContractExclude - To exclude specific tests from being executed.
Introduces one class
@@ -20,7 +21,7 @@ Introduces one class
Introduces two interfaces
-* Producer - defines a producer that creates new instances of the object under test and can clean up after the test is run.
+* IProducer - defines a producer that creates new instances of the object under test and can clean up after the test is run.
* Dynamic - defines a dynamic test suite. Dynamic test suites produce a list of tests after the suite is instantiated.
Maven Repository Info
@@ -66,10 +67,19 @@ The @ContractImpl has two attributes that can remove tests.
* ignore list any @Contract annotated tests that should be ignored. This allows removal of broken
tests that are outside the control of the developer of the @ContractImpl test.
+@ContractExclude
+----------------
+
+The @ContractExclude annotation is intended to be used with @ContractImpl. The annotation has 2 arguments
+1. value is the name of the class that contains the test to exclude.
+2. methods is a list of method names in the test class to exclude.
+
+This annotation will remove the tests only for the ContractImpl it is associated with.
+
@Contract tests
---------------
-The @Contract tests may be removed by adding the standard junit @Ignore annotation.
+The @Contract tests may be removed by adding the standard junit @Ignore annotation. This will remove it from all contract testing.
diff --git a/junit/src/main/java/org/xenei/junit/contract/ContractExclude.java b/junit/src/main/java/org/xenei/junit/contract/ContractExclude.java
new file mode 100644
index 0000000..54aa230
--- /dev/null
+++ b/junit/src/main/java/org/xenei/junit/contract/ContractExclude.java
@@ -0,0 +1,50 @@
+package org.xenei.junit.contract;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to exclude specific test methods from the contract suite.
+ * May be used multiple times.
+ *
+ * For example
+ *
+ *
+ *
+ * @RunWith( ContractSuite.class )
+ * @ContractImpl( FooImpl.class )
+ * @ContractExclude( ExpertFooTests.class, fns="{barTest,bazTest} )
+ * public class Foo_Test {...}
+ *
+ *
+ * Declares that in the ExpertFooTests
class the
+ * barTest
, and bazTest
methods should not
+ * be executed.
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(ContractExcludes.class)
+public @interface ContractExclude
+{
+ /**
+ * The Contract test implementation (annotated with
+ * @Contract) that declares the methods that should not be executed.
+ *
+ * @return The Contract test class.
+ */
+ Class> value();
+
+ /**
+ * The list of interface classes for which tests should be skipped.
+ * This list are interfaces that the class under tests implements but that should
+ * not be tested.
+ *
+ * @return The interfaces to skip testing.
+ */
+ String[] methods();
+
+}
diff --git a/junit/src/main/java/org/xenei/junit/contract/ContractExcludes.java b/junit/src/main/java/org/xenei/junit/contract/ContractExcludes.java
new file mode 100644
index 0000000..57ae10d
--- /dev/null
+++ b/junit/src/main/java/org/xenei/junit/contract/ContractExcludes.java
@@ -0,0 +1,22 @@
+package org.xenei.junit.contract;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The container for repeated ContractExclude annotations.
+ *
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ContractExcludes
+{
+ /**
+ *
+ * The list of ContractExclude annotations.
+ */
+ ContractExclude[] value();
+}
diff --git a/junit/src/main/java/org/xenei/junit/contract/ContractImpl.java b/junit/src/main/java/org/xenei/junit/contract/ContractImpl.java
index 08f51ca..91de5e7 100644
--- a/junit/src/main/java/org/xenei/junit/contract/ContractImpl.java
+++ b/junit/src/main/java/org/xenei/junit/contract/ContractImpl.java
@@ -65,14 +65,18 @@
/**
* The list of interface classes for which tests should be skipped.
+ * This list are interfaces that the class under tests implements but that should
+ * not be tested.
*
- * @return The interfaces to skip.
+ * @return The interfaces to skip testing.
*/
Class>[] skip() default {};
/**
- * The list of implementations to skip. These are implementations of
- * interface tests.
+ * The list of implementations to skip.
+ * This list is a list of test implementations that apply to the class under test
+ * but that should not be executed. This is often
+ * because the tests are not applicable to this implementation.
*
* @return the list of interface test implementations to skip.
*/
diff --git a/junit/src/main/java/org/xenei/junit/contract/ContractSuite.java b/junit/src/main/java/org/xenei/junit/contract/ContractSuite.java
index 1cf919f..c701027 100644
--- a/junit/src/main/java/org/xenei/junit/contract/ContractSuite.java
+++ b/junit/src/main/java/org/xenei/junit/contract/ContractSuite.java
@@ -18,6 +18,7 @@
package org.xenei.junit.contract;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -52,6 +53,7 @@
import org.xenei.junit.contract.info.TestInfo;
import org.xenei.junit.contract.info.TestInfoErrorRunner;
+
/**
* Class that runs the Contract annotated tests.
*
@@ -146,8 +148,6 @@ public ContractSuite(final Class> contractTest, final RunnerBuilder builder)
*
* @param cls
* The class to look on
- * @param errors
- * The list of errors to add to if there is an error
* @return ContractImpl or null if not found.
* @throws InitializationError
*/
@@ -161,6 +161,38 @@ private ContractImpl getContractImpl(final Class> cls) throws InitializationEr
return impl;
}
+ /**
+ * Get the ContractExclude annotation and extract the list of methods from it.
+ *
+ * logs error if method is not found on the class specified in the annotation.
+ *
+ * @param cls
+ * The class on which to for the annotation.
+ * @param errors
+ * The list of errors to add to if there is an error
+ * @return A list of methods. May be empty.
+ * @throws InitializationError
+ */
+ private List getExcludedMethods(final Class> cls) {
+
+ List lst = new ArrayList();
+ for (ContractExclude exclude : cls.getAnnotationsByType(ContractExclude.class))
+ {
+ Class> clazz = exclude.value();
+ for (String mthdName : exclude.methods())
+ {
+ try
+ {
+ lst.add(clazz.getDeclaredMethod(mthdName));
+ } catch (NoSuchMethodException | SecurityException e)
+ {
+ LOG.warn( String.format( "ContractExclude annotation on %s incorrect", cls), e);
+ }
+ }
+ }
+ return lst;
+ }
+
/**
* Add dynamic classes to the suite.
*
@@ -283,17 +315,20 @@ private List addAnnotatedClasses(final Class> baseClass, final RunnerB
private void addSpecifiedClasses(final List runners, final Class> testClass, final RunnerBuilder builder,
final ContractTestMap contractTestMap, final Object baseObj, final TestInfo parentTestInfo)
throws InitializationError {
+
+
// this is the list of all the JUnit runners in the suite.
-
final Set testClasses = new LinkedHashSet();
+
// we have a RunWith annotated class: Klass
// see if it is in the annotatedClasses
-
final BaseClassRunner bcr = new BaseClassRunner(testClass);
if (bcr.computeTestMethods().size() > 0) {
runners.add(bcr);
}
+ List excludeMethods = getExcludedMethods(getTestClass().getJavaClass());
+
/*
* get all the annotated classes that test the interfaces that
* parentTestInfo implements and iterate over them
@@ -308,7 +343,7 @@ private void addSpecifiedClasses(final List runners, final Class> test
runner.logErrors(LOG);
runners.add(runner);
} else {
- runners.add(new ContractTestRunner(baseObj, parentTestInfo, testInfo));
+ runners.add(new ContractTestRunner(baseObj, parentTestInfo, testInfo, excludeMethods));
}
}
}
@@ -341,9 +376,9 @@ protected void runChild(final Runner child, final RunNotifier notifier) {
private class BaseClassRunner extends BlockJUnit4ClassRunner {
private List testMethods = null;
-
+
public BaseClassRunner(final Class> cls) throws InitializationError {
- super(cls);
+ super(cls);
}
@Override
@@ -367,8 +402,10 @@ protected void validateInstanceMethods(final List errors) {
protected List computeTestMethods() {
if (testMethods == null) {
testMethods = new ArrayList();
+ List excludeMethods = getExcludedMethods(getTestClass().getJavaClass());
for (final FrameworkMethod mthd : super.getTestClass().getAnnotatedMethods(ContractTest.class)) {
- if (mthd.getMethod().getDeclaringClass().getAnnotation(Contract.class) == null) {
+ if (mthd.getMethod().getDeclaringClass().getAnnotation(Contract.class) == null &&
+ ! excludeMethods.contains(mthd.getMethod())) {
testMethods.add(mthd);
}
}
diff --git a/junit/src/main/java/org/xenei/junit/contract/ContractTestRunner.java b/junit/src/main/java/org/xenei/junit/contract/ContractTestRunner.java
index 0edb9b4..ef3c5fb 100644
--- a/junit/src/main/java/org/xenei/junit/contract/ContractTestRunner.java
+++ b/junit/src/main/java/org/xenei/junit/contract/ContractTestRunner.java
@@ -20,9 +20,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import org.junit.Ignore;
import org.junit.runner.Description;
+import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
@@ -43,6 +47,7 @@ public class ContractTestRunner extends BlockJUnit4ClassRunner {
private final Object getterObj;
// the getter method to call.
private final Method getter;
+ private final List excludedMethods;
/**
* Create a test runner within the ContractTestSuite.
@@ -54,24 +59,29 @@ public class ContractTestRunner extends BlockJUnit4ClassRunner {
* The test info for the parent.
* @param testInfo
* The test info for this test.
+ * @param excludedMethods
+ * A list of test methods that should not be executed.
*
* @throws InitializationError
* on error.
*/
public ContractTestRunner(Object getterObj, TestInfo parentTestInfo,
- TestInfo testInfo) throws InitializationError {
+ TestInfo testInfo, List excludedMethods) throws InitializationError {
super(testInfo.getContractTestClass());
this.parentTestInfo = parentTestInfo;
this.testInfo = testInfo;
this.getterObj = getterObj;
this.getter = parentTestInfo.getMethod();
+ this.excludedMethods = excludedMethods;
}
/**
* Create a test runner for stand alone test
*
* @param testClass
- * The ContractTest annoated class.
+ * The ContractTest annotated class.
+ * @param excludedMethods
+ * A list of test methods that should not be executed.
*
* @throws InitializationError
* on error.
@@ -82,6 +92,7 @@ public ContractTestRunner(Class> testClass) throws InitializationError {
this.testInfo = null;
this.getterObj = null;
this.getter = null;
+ this.excludedMethods = Collections.emptyList();
}
/**
@@ -117,6 +128,16 @@ protected Object createTest() throws InstantiationException,
return retval;
}
+
+ @Override
+ protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
+ Description description = describeChild(method);
+ if (method.getAnnotation(Ignore.class) != null || excludedMethods.contains( method.getMethod())) {
+ notifier.fireTestIgnored(description);
+ } else {
+ runLeaf(methodBlock(method), description, notifier);
+ }
+ }
/**
* Adds to {@code errors} if the test class has more than one constructor,
@@ -161,8 +182,13 @@ protected Description describeChild(FrameworkMethod method) {
*/
@Override
protected List computeTestMethods() {
- // this is call during construction. testInfo is not yet available.
+ // this is call during construction. testInfo and excludedMethods is not yet available.
return getTestClass().getAnnotatedMethods(ContractTest.class);
}
+
+ @Override
+ public String toString() {
+ return "ContractTest"+testInfo==null?"":testInfo.toString();
+ }
}
diff --git a/junit/src/main/java/org/xenei/junit/contract/info/ContractTestMap.java b/junit/src/main/java/org/xenei/junit/contract/info/ContractTestMap.java
index b48449f..e563391 100644
--- a/junit/src/main/java/org/xenei/junit/contract/info/ContractTestMap.java
+++ b/junit/src/main/java/org/xenei/junit/contract/info/ContractTestMap.java
@@ -52,19 +52,6 @@ public class ContractTestMap {
private static final Log LOG = LogFactory.getLog(ContractTestMap.class);
- /**
- * Create an instance of ContractTestMap using the specified class loader.
- *
- * Contract tests must be annotated with @Contract and must not be annotated
- * with @Ignore
- *
- * @param classLoader
- * The class loader to use.
- * @param packages
- * A list of package names to report
- * @return A ContractTestMap.
- */
-
/**
* Constructor
*
diff --git a/junit/src/main/java/org/xenei/junit/contract/info/TestInfo.java b/junit/src/main/java/org/xenei/junit/contract/info/TestInfo.java
index 701b482..aebb404 100644
--- a/junit/src/main/java/org/xenei/junit/contract/info/TestInfo.java
+++ b/junit/src/main/java/org/xenei/junit/contract/info/TestInfo.java
@@ -140,7 +140,7 @@ public Class>[] getSkipTests() {
}
/**
- * Get the package name of the cla under test..
+ * Get the package name of the class under test..
*
* @return The contract class package name.
*/
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/B.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/B.java
index 4b70a91..a3d1003 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/B.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/B.java
@@ -26,8 +26,12 @@ public interface B {
/**
*
- * @return the B Bane
+ * @return the B name;
*/
public String getBName();
+ /**
+ * @return the B int
+ */
+ public int getBInt();
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImpl.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImpl.java
index 173b3d7..117821c 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImpl.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImpl.java
@@ -33,4 +33,12 @@ public String getBName() {
public String toString() {
return "BImpl";
}
+
+ @Override
+ public int getBInt()
+ {
+ return 1;
+ }
+
+
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplContractTest.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplContractTest.java
index 703e36f..4bce74f 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplContractTest.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplContractTest.java
@@ -95,7 +95,9 @@ public static void beforeClass() {
@AfterClass
public static void afterClass() {
String[] expected = { "BImplContractTest.producer.newInstance()",
- "bname", "BImplContractTest.producer.cleanUp()" };
+ "bname", "BImplContractTest.producer.cleanUp()",
+ "BImplContractTest.producer.newInstance()",
+ "BInt=1", "BImplContractTest.producer.cleanUp()" };
List l = Listener.get();
Assert.assertEquals(l, Arrays.asList(expected));
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplTest.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplTest.java
index 1892942..9db62b9 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplTest.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BImplTest.java
@@ -78,7 +78,9 @@ public static void beforeClass() {
@AfterClass
public static void afterClass() {
String[] expected = { "BImplTest.producer.newInstance()", "bname",
- "BImplTest.producer.cleanUp()" };
+ "BImplTest.producer.cleanUp()",
+ "BImplTest.producer.newInstance()",
+ "BInt=1", "BImplTest.producer.cleanUp()" };
List l = Listener.get();
Assert.assertEquals(l, Arrays.asList(expected));
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BT.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BT.java
index e0d8b22..60c6cdc 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/BT.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/BT.java
@@ -68,6 +68,14 @@ public void testGetBName() {
Listener.add(getProducer().newInstance().getBName());
}
+ /**
+ * Test getBInt()
+ */
+ @ContractTest
+ public void testGetBInt() {
+ Listener.add( "BInt="+getProducer().newInstance().getBInt());
+ }
+
/**
* Clean up the producer.
*/
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl.java
index 0ce79f0..8ac26ee 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl.java
@@ -42,4 +42,11 @@ public String getBName() {
public String toString() {
return "CImpl";
}
+
+ @Override
+ public int getBInt()
+ {
+ return 2;
+ }
+
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2.java
index 04506ad..b1c60c5 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2.java
@@ -42,6 +42,13 @@ public String getBName() {
public String toString() {
return "CImpl2";
}
+
+ @Override
+ public int getBInt()
+ {
+ return 3;
+ }
+
/**
* An extra method in this implementation that is not defined in C.
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2ContractTest.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2ContractTest.java
index becbd1c..dddfb1d 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2ContractTest.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl2ContractTest.java
@@ -106,7 +106,7 @@ public static void beforeClass() {
private static void verifyTest( List expectedTests, List results) {
Assert.assertEquals( "CImpl2ContractTest.producer.newInstance()", results.get(0));
- Assert.assertTrue( expectedTests.contains( results.get(1)));
+ Assert.assertTrue( "Missing "+results.get(1), expectedTests.contains( results.get(1)));
expectedTests.remove( results.get(1));
Assert.assertEquals( "CImpl2ContractTest.producer.cleanUp()", results.get(2));
@@ -116,7 +116,7 @@ private static void verifyTest( List expectedTests, List results
*/
@AfterClass
public static void afterClass() {
- final String[] testNames = {"called Extra Method","cname", "cname version of aname", "cname version of bname" };
+ final String[] testNames = {"called Extra Method","cname", "cname version of aname", "BInt=3", "cname version of bname" };
final List expectedTests = new ArrayList(Arrays.asList(testNames));
@@ -127,7 +127,7 @@ public static void afterClass() {
int j = i*3;
verifyTest( expectedTests, l.subList(j, j+3));
}
-
+ Assert.assertTrue( expectedTests.isEmpty());
}
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl3.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl3.java
index fc6e37d..d93163c 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl3.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImpl3.java
@@ -28,4 +28,10 @@ public String getBName() {
return null;
}
+ @Override
+ public int getBInt()
+ {
+ return 4;
+ }
+
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTest.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTest.java
index cc99987..c57bef7 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTest.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTest.java
@@ -87,7 +87,7 @@ public static void beforeClass() {
private static void verifyTest( List expectedTests, List results) {
Assert.assertEquals( "CImplContractTest.producer.newInstance()", results.get(0));
- Assert.assertTrue( expectedTests.contains( results.get(1)));
+ Assert.assertTrue( "Missing "+results.get(1), expectedTests.contains( results.get(1)));
expectedTests.remove( results.get(1));
Assert.assertEquals( "CImplContractTest.producer.cleanUp()", results.get(2));
@@ -97,7 +97,7 @@ private static void verifyTest( List expectedTests, List results
*/
@AfterClass
public static void afterClass() {
- final String[] testNames = {"cname", "cname version of aname", "cname version of bname" };
+ final String[] testNames = {"cname", "cname version of aname", "cname version of bname", "BInt=2" };
final List expectedTests = new ArrayList(Arrays.asList(testNames));
@@ -108,7 +108,8 @@ public static void afterClass() {
int j = i*3;
verifyTest( expectedTests, l.subList(j, j+3));
}
-
+ Assert.assertTrue( expectedTests.isEmpty() );
+
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTestWithExclude.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTestWithExclude.java
new file mode 100644
index 0000000..8bde73e
--- /dev/null
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/CImplContractTestWithExclude.java
@@ -0,0 +1,115 @@
+/*
+ * 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.xenei.junit.contract.exampleTests;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.xenei.junit.bad.BadNoInject;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractExclude;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.IProducer;
+
+/**
+ * Run the C tests using the contract suite runner.
+ *
+ * This will run the tests defined in CT as well as AT (A contract tests) and BT
+ * (B contract tests). Compare this to CImplTest.
+ *
+ * Note that producer used for the AT and BT classes will be the
+ * IProducer<CImpl$gt; from this class.
+ *
+ * The use of the Listener interface in the before and after methods are to
+ * track that the tests are run correctly and in the proper order. This would
+ * not be used in a production test but are part of our testing of
+ * junit-contracts.
+ *
+ */
+// run as a contract test
+@RunWith(ContractSuite.class)
+// testing the CImpl class.
+@ContractImpl( value=CImpl.class, ignore = { BadNoInject.class })
+@ContractExclude( value=BT.class, methods={"testGetBInt"})
+public class CImplContractTestWithExclude {
+ // the producer to use for all the tests
+ private IProducer producer = new IProducer() {
+ @Override
+ public CImpl newInstance() {
+ Listener.add("CImplContractTest.producer.newInstance()");
+ return new CImpl();
+ }
+
+ @Override
+ public void cleanUp() {
+ Listener.add("CImplContractTest.producer.cleanUp()");
+ }
+ };
+
+ /**
+ * The method to inject the producer into the test classes.
+ *
+ * @return The producer we want to use for the tests.
+ */
+ @Contract.Inject
+ public IProducer getProducer() {
+ return producer;
+ }
+
+ /**
+ * Clean up the listener for the tests.
+ */
+ @BeforeClass
+ public static void beforeClass() {
+ Listener.clear();
+ }
+
+ private static void verifyTest( List expectedTests, List results) {
+ Assert.assertEquals( "CImplContractTest.producer.newInstance()", results.get(0));
+ Assert.assertTrue( "Missing "+results.get(1), expectedTests.contains( results.get(1)));
+ expectedTests.remove( results.get(1));
+ Assert.assertEquals( "CImplContractTest.producer.cleanUp()", results.get(2));
+
+ }
+ /**
+ * Verify that the Listener recorded all the expected events.
+ */
+ @AfterClass
+ public static void afterClass() {
+ final String[] testNames = {"cname", "cname version of bname", "cname version of aname" };
+ final List expectedTests = new ArrayList(Arrays.asList(testNames));
+
+
+ final List l = Listener.get();
+
+ for (int i=0;i expectedTests, List results) {
Assert.assertEquals( "CImplContractTest.producer.newInstance()", results.get(0));
- Assert.assertTrue( expectedTests.contains( results.get(1)));
+ Assert.assertTrue( "Missing "+results.get(1), expectedTests.contains( results.get(1)));
expectedTests.remove( results.get(1));
Assert.assertEquals( "CImplContractTest.producer.cleanUp()", results.get(2));
@@ -95,7 +95,7 @@ private static void verifyTest( List expectedTests, List results
*/
@AfterClass
public static void afterClass() {
- final String[] testNames = {"cname", "cname version of bname" };
+ final String[] testNames = {"cname", "cname version of bname", "BInt=2" };
final List expectedTests = new ArrayList(Arrays.asList(testNames));
@@ -106,7 +106,7 @@ public static void afterClass() {
int j = i*3;
verifyTest( expectedTests, l.subList(j, j+3));
}
-
+ Assert.assertTrue( expectedTests.isEmpty() );
}
}
diff --git a/junit/src/test/java/org/xenei/junit/contract/exampleTests/FImpl.java b/junit/src/test/java/org/xenei/junit/contract/exampleTests/FImpl.java
index 2ac2386..03b92dc 100644
--- a/junit/src/test/java/org/xenei/junit/contract/exampleTests/FImpl.java
+++ b/junit/src/test/java/org/xenei/junit/contract/exampleTests/FImpl.java
@@ -32,4 +32,10 @@ public String getFName() {
return null;
}
+ @Override
+ public int getBInt()
+ {
+ return 5;
+ }
+
}