[Clirr-devel] CVS: clirr/core/src/test/net/sf/clirr/core/internal/checks AbstractCheckTestCase.java,
Status: Alpha
Brought to you by:
lkuehne
From: <lk...@us...> - 2004-07-11 10:29:33
|
Update of /cvsroot/clirr/clirr/core/src/test/net/sf/clirr/core/internal/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15487/test/net/sf/clirr/core/internal/checks Added Files: AbstractCheckTestCase.java ClassHierarchyCheckTest.java ClassModifierCheckTest.java ClassScopeCheckTest.java ExpectedDiff.java FieldSetCheckTest.java GenderChangeCheckTest.java MethodSetCheckTest.java TestDiffListener.java Log Message: Whoops - forgot to add tests after moving sources to core subproject --- NEW FILE --- package net.sf.clirr.core.internal.checks; import junit.framework.TestCase; import net.sf.clirr.core.Checker; import net.sf.clirr.core.ClassSelector; import net.sf.clirr.core.ApiDifference; import net.sf.clirr.core.CheckerFactory; import net.sf.clirr.core.internal.ClassChangeCheck; import org.apache.bcel.util.ClassSet; import java.io.File; import java.net.URL; import java.net.URLClassLoader; /** * Abstract Baseclass to test individual Checks. * @author lkuehne */ public abstract class AbstractCheckTestCase extends TestCase { protected final File getTestInputDir() { // property is set in project.properties return new File(System.getProperty("testinput")); } protected void verify( Checker checker, ClassSet baseline, ClassSet current, ApiDifference[] expected) { } protected File[] getBaseLine() { return new File[]{ new File(getTestInputDir(), "testlib-v1.jar") }; } protected File[] getCurrent() { return new File[]{ new File(getTestInputDir(), "testlib-v2.jar") }; } protected void verify(ExpectedDiff[] expected) throws Exception { TestDiffListener tdl = new TestDiffListener(); Checker checker = CheckerFactory.createChecker(createCheck(tdl)); ClassSelector classSelector = createClassSelector(); checker.reportDiffs( getBaseLine(), getCurrent(), new URLClassLoader(new URL[]{}), new URLClassLoader(new URL[]{}), classSelector); tdl.checkExpected(expected); } /** * Creates an object which selects the appropriate classes from the * test jars for this test. * <p> * This base implementation returns a selector which selects all classes * in the base "testlib" package (but no sub-packages). Tests which wish * to select different classes from the test jars should override this * method. */ protected ClassSelector createClassSelector() { // only check classes in the base "testlib" package of the jars ClassSelector classSelector = new ClassSelector(ClassSelector.MODE_IF); classSelector.addPackage("testlib"); return classSelector; } /** * Creates a check and sets it up so ApiDifferences are reported to the test diff listener. * * @param tdl the test diff listener that records the recognized api changes. * @return the confiured check */ protected abstract ClassChangeCheck createCheck(TestDiffListener tdl); } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.internal.checks.ClassHierarchyCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; import net.sf.clirr.core.Severity; /** * @author lkuehne */ public class ClassHierarchyCheckTest extends AbstractCheckTestCase { public void testHierarchyChangesAreReported() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { new ExpectedDiff("Added java.util.NoSuchElementException to the list of superclasses", Severity.WARNING, "testlib.ApplicationException", null, null), new ExpectedDiff("Removed java.awt.event.MouseAdapter from the list of superclasses", Severity.ERROR, "testlib.ChangingHierarchy", null, null), new ExpectedDiff("Added java.awt.event.WindowAdapter to the list of superclasses", Severity.INFO, "testlib.ChangingHierarchy", null, null), }; verify(expected); } protected ClassChangeCheck createCheck(TestDiffListener tdl) { return new ClassHierarchyCheck(tdl); } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.Severity; import net.sf.clirr.core.ClassSelector; import net.sf.clirr.core.internal.checks.ClassModifierCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; /** * Tests for the ClassModifierCheck class. */ public class ClassModifierCheckTest extends AbstractCheckTestCase { public void testAll() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { new ExpectedDiff("Added final modifier to class", Severity.ERROR, "testlib.modifiers.NonFinalBecomesFinal", null, null), new ExpectedDiff("Added final modifier to class, but class was effectively final anyway", Severity.INFO, "testlib.modifiers.EffectivelyFinal", null, null), }; verify(expected); } protected ClassChangeCheck createCheck(TestDiffListener tdl) { return new ClassModifierCheck(tdl); } protected ClassSelector createClassSelector() { // only apply the check to classes in the testlib.modifiers package. ClassSelector classSelector = new ClassSelector(ClassSelector.MODE_IF); classSelector.addPackage("testlib.modifiers"); return classSelector; } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.Severity; import net.sf.clirr.core.ClassSelector; import net.sf.clirr.core.ScopeSelector; import net.sf.clirr.core.internal.checks.ClassScopeCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; /** * Tests for the ClassScopeCheck test. * * @author Simon Kitching */ public class ClassScopeCheckTest extends AbstractCheckTestCase { public void testAccessChangesAreReported() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { new ExpectedDiff("Decreased visibility of class from public to protected", Severity.ERROR, "testlib.scope.ClassScopeChange$A2", null, null), new ExpectedDiff("Decreased visibility of class from public to package", Severity.ERROR, "testlib.scope.ClassScopeChange$A3", null, null), new ExpectedDiff("Decreased visibility of class from public to private", Severity.ERROR, "testlib.scope.ClassScopeChange$A4", null, null), new ExpectedDiff("Increased visibility of class from protected to public", Severity.INFO, "testlib.scope.ClassScopeChange$B2", null, null), new ExpectedDiff("Decreased visibility of class from protected to package", Severity.ERROR, "testlib.scope.ClassScopeChange$B3", null, null), new ExpectedDiff("Decreased visibility of class from protected to private", Severity.ERROR, "testlib.scope.ClassScopeChange$B4", null, null), new ExpectedDiff("Increased visibility of class from package to public", Severity.INFO, "testlib.scope.ClassScopeChange$C2", null, null), new ExpectedDiff("Increased visibility of class from package to protected", Severity.INFO, "testlib.scope.ClassScopeChange$C3", null, null), new ExpectedDiff("Decreased visibility of class from package to private", Severity.ERROR, "testlib.scope.ClassScopeChange$C4", null, null), new ExpectedDiff("Increased visibility of class from private to public", Severity.INFO, "testlib.scope.ClassScopeChange$D2", null, null), new ExpectedDiff("Increased visibility of class from private to protected", Severity.INFO, "testlib.scope.ClassScopeChange$D3", null, null), new ExpectedDiff("Increased visibility of class from private to package", Severity.INFO, "testlib.scope.ClassScopeChange$D4", null, null), }; verify(expected); } protected ClassChangeCheck createCheck(TestDiffListener tdl) { ScopeSelector scopeSelector = new ScopeSelector(ScopeSelector.SCOPE_PRIVATE); return new ClassScopeCheck(tdl, scopeSelector); } protected ClassSelector createClassSelector() { // only check the testlib/scope/ClassScopeChange class. ClassSelector classSelector = new ClassSelector(ClassSelector.MODE_IF); classSelector.addClass("testlib.scope.ClassScopeChange"); return classSelector; } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.ApiDifference; import net.sf.clirr.core.MessageTranslator; import net.sf.clirr.core.Severity; /** * Describes an expected API change. */ public final class ExpectedDiff { private static MessageTranslator translator = new MessageTranslator(); private String report; private Severity binaryCompatibilitySeverity; private Severity sourceCompatibilitySeverity; private String affectedClass; private String affectedMethod; private String affectedField; /** * Create a new API difference representation. * * @param report a human readable string describing the change that was made, must be non-null. * @param severity the severity in terms of binary and source code compatibility, must be non-null. * @param clazz the fully qualified class name where the change occured, must be non-null. * @param method the method signature of the method that changed, <code>null</code> * if no method was affected. * @param field the field name where the change occured, <code>null</code> * if no field was affected. */ public ExpectedDiff(String report, Severity severity, String clazz, String method, String field) { this(report, severity, severity, clazz, method, field); } /** * Create a new API difference representation. * * @param report a human readable string describing the change that was made, must be non-null. * @param binarySeverity the severity in terms of binary compatibility, must be non-null. * @param sourceSeverity the severity in terms of source code compatibility, must be non-null. * @param clazz the fully qualified class name where the change occured, must be non-null. * @param method the method signature of the method that changed, <code>null</code> * if no method was affected. * @param field the field name where the change occured, <code>null</code> * if no field was affected. */ public ExpectedDiff(String report, Severity binarySeverity, Severity sourceSeverity, String clazz, String method, String field) { checkNonNull(report); checkNonNull(binarySeverity); checkNonNull(sourceSeverity); checkNonNull(clazz); this.report = report; this.binaryCompatibilitySeverity = binarySeverity; this.sourceCompatibilitySeverity = sourceSeverity; this.affectedClass = clazz; this.affectedField = field; this.affectedMethod = method; } /** * Trivial utility method to verify that a specific object is non-null. */ private void checkNonNull(Object o) { if (o == null) { throw new IllegalArgumentException(); } } /** * {@inheritDoc} */ public String toString() { return report + " (" + binaryCompatibilitySeverity + ") - " + affectedClass + '[' + affectedField + '/' + affectedMethod + ']'; } /** * Returns true if the provided ApiDifference object matches the * expected value. */ public boolean matches(ApiDifference diff) { if (!report.equals(diff.getReport(translator))) { return false; } if (!binaryCompatibilitySeverity.equals(diff.getBinaryCompatibilitySeverity())) { return false; } if (!sourceCompatibilitySeverity.equals(diff.getSourceCompatibilitySeverity())) { return false; } final String otherClass = diff.getAffectedClass(); if (!affectedClass.equals(otherClass)) { return false; } final String otherMethod = diff.getAffectedMethod(); if (affectedMethod != null ? !affectedMethod.equals(otherMethod) : otherMethod != null) { return false; } final String otherField = diff.getAffectedField(); if (affectedField != null ? !affectedField.equals(otherField) : otherField != null) { return false; } return true; } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.Severity; import net.sf.clirr.core.ScopeSelector; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.internal.checks.FieldSetCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; import net.sf.clirr.core.internal.checks.ExpectedDiff; /** * Tests FieldSetCheck. * * @author lkuehne */ public class FieldSetCheckTest extends AbstractCheckTestCase { public void testFieldCheck() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { new ExpectedDiff("Removed field stat7", Severity.ERROR, "testlib.MembersChange", null, "stat7"), new ExpectedDiff("Accessability of field fin2 has been weakened from public to protected", Severity.ERROR, "testlib.MembersChange", null, "fin2"), new ExpectedDiff("Accessability of field stat4 has been weakened from public to protected", Severity.ERROR, "testlib.MembersChange", null, "stat4"), new ExpectedDiff("Accessability of field priv2 has been increased from private to public", Severity.INFO, "testlib.MembersChange", null, "priv2"), new ExpectedDiff("Accessability of field stat5 has been weakened from public to private", Severity.ERROR, "testlib.MembersChange", null, "stat5"), new ExpectedDiff("Field stat2 is now final", Severity.ERROR, "testlib.MembersChange", null, "stat2"), new ExpectedDiff("Field pub3 is now final", Severity.ERROR, "testlib.MembersChange", null, "pub3"), new ExpectedDiff("Accessability of field stat6 has been weakened from public to package", Severity.ERROR, "testlib.MembersChange", null, "stat6"), new ExpectedDiff("Field stat3 is now non-static", Severity.ERROR, "testlib.MembersChange", null, "stat3"), new ExpectedDiff("Field fin3 is now non-static", Severity.ERROR, "testlib.MembersChange", null, "fin3"), new ExpectedDiff("Added public field stat8", Severity.INFO, "testlib.MembersChange", null, "stat8"), new ExpectedDiff("Field fin4 is now non-final", Severity.INFO, "testlib.MembersChange", null, "fin4"), new ExpectedDiff("Field pub2 is now static", Severity.ERROR, "testlib.MembersChange", null, "pub2"), new ExpectedDiff("Changed type of field obj1 from java.lang.Object to java.lang.String", Severity.ERROR, "testlib.MembersChange", null, "obj1"), new ExpectedDiff("Changed type of field obj2 from java.lang.Boolean to java.lang.String", Severity.ERROR, "testlib.MembersChange", null, "obj2"), new ExpectedDiff("Value of field fin6 is no longer a compile-time constant", Severity.WARNING, "testlib.MembersChange", null, "fin6"), new ExpectedDiff("Value of compile-time constant fin5 has been changed", Severity.WARNING, "testlib.MembersChange", null, "fin5"), }; verify(expected); } protected final ClassChangeCheck createCheck(TestDiffListener tdl) { ScopeSelector scopeSelector = new ScopeSelector(); return new FieldSetCheck(tdl, scopeSelector); } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.Severity; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.internal.checks.GenderChangeCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; import net.sf.clirr.core.internal.checks.ExpectedDiff; public class GenderChangeCheckTest extends AbstractCheckTestCase { public void testGenderChangeCheckTest() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { new ExpectedDiff("Changed from class to interface", Severity.ERROR, "testlib.ClassBecomesInterface", null, null), new ExpectedDiff("Changed from interface to class", Severity.ERROR, "testlib.InterfaceBecomesClass", null, null), }; verify(expected); } protected final ClassChangeCheck createCheck(TestDiffListener tdl) { return new GenderChangeCheck(tdl); } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import net.sf.clirr.core.internal.ClassChangeCheck; import net.sf.clirr.core.Severity; import net.sf.clirr.core.ScopeSelector; import net.sf.clirr.core.internal.checks.MethodSetCheck; import net.sf.clirr.core.internal.checks.AbstractCheckTestCase; import net.sf.clirr.core.internal.checks.ExpectedDiff; /** * TODO: Docs. * * @author lkuehne */ public class MethodSetCheckTest extends AbstractCheckTestCase { public void testMethodCheck() throws Exception { ExpectedDiff[] expected = new ExpectedDiff[] { // method addition and removal new ExpectedDiff("Method 'public void removedMethod(java.lang.String)' has been removed", Severity.ERROR, "testlib.MethodsChange", "public void removedMethod(java.lang.String)", null), new ExpectedDiff("Accessability of method 'public int getPriv2()' has been decreased from public to private", Severity.ERROR, "testlib.MethodsChange", "public int getPriv2()", null), new ExpectedDiff("Method 'protected MethodsChange(int, boolean)' has been added", Severity.INFO, "testlib.MethodsChange", "protected MethodsChange(int, boolean)", null), new ExpectedDiff("Method 'public java.lang.Long getPrivSquare()' has been added", Severity.INFO, "testlib.MethodsChange", "public java.lang.Long getPrivSquare()", null), new ExpectedDiff("Method 'public void moveToSuper()' has been added", Severity.INFO, "testlib.ComplexMethodMoveBase", "public void moveToSuper()", null), new ExpectedDiff("Method 'public void moveToSuper()' is now implemented in superclass testlib.ComplexMethodMoveBase", Severity.INFO, "testlib.ComplexMethodMoveSub", "public void moveToSuper()", null), new ExpectedDiff("Abstract method 'public void method()' is now specified by implemented interface testlib.BaseInterface", Severity.INFO, "testlib.AbstractImpl", "public void method()", null), // Constructor changes new ExpectedDiff("Parameter 1 of 'protected MethodsChange(int)' has changed its type to java.lang.Integer", Severity.ERROR, "testlib.MethodsChange", "protected MethodsChange(int)", null), // return type changes new ExpectedDiff("Return type of method 'public java.lang.Number getPrivAsNumber()' has been changed to java.lang.Integer", Severity.ERROR, "testlib.MethodsChange", "public java.lang.Number getPrivAsNumber()", null), // TODO: INFO if method is final new ExpectedDiff("Return type of method 'public java.lang.Integer getPrivAsInteger()' has been changed to java.lang.Number", Severity.ERROR, "testlib.MethodsChange", "public java.lang.Integer getPrivAsInteger()", null), // parameter list changes // Note: This is the current behaviour, not necessarily the spec of the desired behaviour // TODO: need to check assignability of types (and check if method or class is final?) new ExpectedDiff("In method 'public void printPriv()' the number of arguments has changed", Severity.ERROR, "testlib.MethodsChange", "public void printPriv()", null), new ExpectedDiff("Parameter 1 of 'public void strengthenParamType(java.lang.Object)' has changed its type to java.lang.String", Severity.ERROR, "testlib.MethodsChange", "public void strengthenParamType(java.lang.Object)", null), new ExpectedDiff("Parameter 1 of 'public void weakenParamType(java.lang.String)' has changed its type to java.lang.Object", Severity.ERROR, "testlib.MethodsChange", "public void weakenParamType(java.lang.String)", null), new ExpectedDiff("Parameter 1 of 'public void changeParamType(java.lang.String)' has changed its type to java.lang.Integer", Severity.ERROR, "testlib.MethodsChange", "public void changeParamType(java.lang.String)", null), // deprecation changes new ExpectedDiff("Method 'public void becomesDeprecated()' has been deprecated", Severity.INFO, "testlib.MethodsChange", "public void becomesDeprecated()", null), new ExpectedDiff("Method 'public void becomesUndeprecated()' is no longer deprecated", Severity.INFO, "testlib.MethodsChange", "public void becomesUndeprecated()", null), // declared exceptions // TODO }; verify(expected); } protected final ClassChangeCheck createCheck(TestDiffListener tdl) { return new MethodSetCheck(tdl, new ScopeSelector()); } } --- NEW FILE --- package net.sf.clirr.core.internal.checks; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import net.sf.clirr.core.internal.ApiDiffDispatcher; import net.sf.clirr.core.internal.checks.ExpectedDiff; import net.sf.clirr.core.ApiDifference; import net.sf.clirr.core.MessageTranslator; import junit.framework.TestCase; class TestDiffListener implements ApiDiffDispatcher { private MessageTranslator translator = new MessageTranslator(); private Set diffs = new HashSet(); public void fireDiff(ApiDifference difference) { diffs.add(difference); } public void checkExpected(ExpectedDiff[] expectedDiffs) { for (int i=0; i<expectedDiffs.length; ++i) { ExpectedDiff expected = expectedDiffs[i]; // now see if the expected diff is in fact in the set of // diffs that occurred during the test comparison boolean found = false; for(Iterator j = diffs.iterator(); j.hasNext() && !found;) { ApiDifference actual = (ApiDifference) j.next(); found = expected.matches(actual); } if (!found) { TestCase.fail("expected diff " + expected + " was not generated: " + diffs); } } for (Iterator it = diffs.iterator(); it.hasNext();) { ApiDifference actual = (ApiDifference) it.next(); // see if the generated diff is in fact in the expected set boolean found = false; for(int i=0; i<expectedDiffs.length && !found; ++i) { found = expectedDiffs[i].matches(actual); } if (!found) { TestCase.fail("unexpected diff " + actual); } } } } |