git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271064 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,215 @@ | |||||
| /* | |||||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
| * | |||||
| * This software is published under the terms of the Apache Software License | |||||
| * version 1.1, a copy of which has been included with this distribution in | |||||
| * the LICENSE.txt file. | |||||
| */ | |||||
| package org.apache.myrmidon; | |||||
| import java.io.IOException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Collection; | |||||
| import java.util.Iterator; | |||||
| import jdepend.framework.JDepend; | |||||
| import jdepend.framework.JavaPackage; | |||||
| import junit.framework.TestCase; | |||||
| /** | |||||
| * An abstract Unit test that can be used to test Dependency metrics | |||||
| * fall in acceptable limits. | |||||
| * | |||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
| * @version $Revision$ $Date$ | |||||
| */ | |||||
| public class DependencyMetricsTest | |||||
| extends TestCase | |||||
| { | |||||
| private JDepend m_jDepend; | |||||
| public DependencyMetricsTest( final String name ) | |||||
| { | |||||
| super( name ); | |||||
| } | |||||
| /** | |||||
| * Sets up the test fixture. | |||||
| * | |||||
| * Called before every test case method. | |||||
| */ | |||||
| protected void setUp() | |||||
| { | |||||
| m_jDepend = new JDepend(); | |||||
| try | |||||
| { | |||||
| m_jDepend.addDirectory( "src/java" ); | |||||
| //m_jDepend.addDirectory( "src/main" ); | |||||
| } | |||||
| catch( final IOException ioe ) | |||||
| { | |||||
| fail( ioe.getMessage() ); | |||||
| } | |||||
| m_jDepend.analyze(); | |||||
| } | |||||
| /** | |||||
| * Tears down the test fixture. | |||||
| * | |||||
| * Called after every test case method. | |||||
| */ | |||||
| protected void tearDown() | |||||
| { | |||||
| m_jDepend = null; | |||||
| } | |||||
| /** | |||||
| * Utility method to retrieve JDpenden instance that contains statistics. | |||||
| */ | |||||
| protected final JDepend getJDepend() | |||||
| { | |||||
| return m_jDepend; | |||||
| } | |||||
| /** | |||||
| * Make sure that the launcher classes in org.apache.myrmidon.launcher.* | |||||
| * are completely decoupled from the rest of the system. | |||||
| */ | |||||
| public void testLauncherDecoupled() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final String name = "org.apache.myrmidon.launcher"; | |||||
| final JavaPackage javaPackage = jDepend.getPackage( name ); | |||||
| final Collection afferentSet = javaPackage.getAfferents(); | |||||
| final Iterator afferents = afferentSet.iterator(); | |||||
| while( afferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage afferent = (JavaPackage)afferents.next(); | |||||
| final String afferentName = afferent.getName(); | |||||
| if( !afferentName.startsWith( name ) ) | |||||
| { | |||||
| fail( "The launcher package " + name + " depends on external classes " + | |||||
| "contained in " + afferentName + ". No classes besides " + | |||||
| "those in the launcher hierarchy should be referenced" ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure that the implementations of the myrmidon kernel components | |||||
| * (ie org.apache.myrmidon.component.X.*) are not referenced by anyone | |||||
| * except by other objects in the same package or child packages. | |||||
| */ | |||||
| public void testNoComponentImplSharing() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| final String name = javaPackage.getName(); | |||||
| final String componentPackage = "org.apache.myrmidon.component."; | |||||
| if( !name.startsWith( componentPackage ) ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| final int start = componentPackage.length() + 1; | |||||
| final int end = name.indexOf( '.', start ); | |||||
| final String component = name.substring( end ); | |||||
| final Collection afferentSet = javaPackage.getAfferents(); | |||||
| final Iterator afferents = afferentSet.iterator(); | |||||
| while( afferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage efferent = (JavaPackage)afferents.next(); | |||||
| final String efferentName = efferent.getName(); | |||||
| if( !efferentName.startsWith( component ) ) | |||||
| { | |||||
| fail( "The package " + name + " is referred to by classes " + | |||||
| "contained in " + efferentName + ". No classes besides " + | |||||
| "those part of the particular implementation of kernel " + | |||||
| "component should reference the implementations" ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure that aut does not depend on any other ant classes | |||||
| * and thus can be cleanly decoupled. | |||||
| */ | |||||
| public void testAutDecoupled() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| final String name = javaPackage.getName(); | |||||
| if( !name.startsWith( "org.apache.aut" ) ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| final Collection efferentSet = javaPackage.getEfferents(); | |||||
| final Iterator efferents = efferentSet.iterator(); | |||||
| while( efferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage efferent = (JavaPackage)efferents.next(); | |||||
| final String efferentName = efferent.getName(); | |||||
| if( efferentName.startsWith( "org.apache.myrmidon" ) || | |||||
| efferentName.startsWith( "org.apache.antlib" ) || | |||||
| efferentName.startsWith( "org.apache.tools.ant" ) ) | |||||
| { | |||||
| fail( "The package " + name + " depends on classes " + | |||||
| "contained in " + efferentName ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure there are no circular dependencies between packages because | |||||
| * circular dependencies are evil!!! | |||||
| */ | |||||
| public void testNoCircularity() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| if( javaPackage.containsCycle() ) | |||||
| { | |||||
| final ArrayList cycle = new ArrayList(); | |||||
| javaPackage.collectCycle( cycle ); | |||||
| final ArrayList names = getPackageNames( cycle ); | |||||
| fail( "The package " + javaPackage.getName() + " contains a cycle " + | |||||
| "with a path " + names ); | |||||
| } | |||||
| } | |||||
| } | |||||
| private ArrayList getPackageNames( final ArrayList cycle ) | |||||
| { | |||||
| final ArrayList names = new ArrayList(); | |||||
| final int size = cycle.size(); | |||||
| for( int i = 0; i < size; i++ ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)cycle.get( i ); | |||||
| names.add( javaPackage.getName() ); | |||||
| } | |||||
| return names; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,215 @@ | |||||
| /* | |||||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||||
| * | |||||
| * This software is published under the terms of the Apache Software License | |||||
| * version 1.1, a copy of which has been included with this distribution in | |||||
| * the LICENSE.txt file. | |||||
| */ | |||||
| package org.apache.myrmidon; | |||||
| import java.io.IOException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Collection; | |||||
| import java.util.Iterator; | |||||
| import jdepend.framework.JDepend; | |||||
| import jdepend.framework.JavaPackage; | |||||
| import junit.framework.TestCase; | |||||
| /** | |||||
| * An abstract Unit test that can be used to test Dependency metrics | |||||
| * fall in acceptable limits. | |||||
| * | |||||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||||
| * @version $Revision$ $Date$ | |||||
| */ | |||||
| public class DependencyMetricsTest | |||||
| extends TestCase | |||||
| { | |||||
| private JDepend m_jDepend; | |||||
| public DependencyMetricsTest( final String name ) | |||||
| { | |||||
| super( name ); | |||||
| } | |||||
| /** | |||||
| * Sets up the test fixture. | |||||
| * | |||||
| * Called before every test case method. | |||||
| */ | |||||
| protected void setUp() | |||||
| { | |||||
| m_jDepend = new JDepend(); | |||||
| try | |||||
| { | |||||
| m_jDepend.addDirectory( "src/java" ); | |||||
| //m_jDepend.addDirectory( "src/main" ); | |||||
| } | |||||
| catch( final IOException ioe ) | |||||
| { | |||||
| fail( ioe.getMessage() ); | |||||
| } | |||||
| m_jDepend.analyze(); | |||||
| } | |||||
| /** | |||||
| * Tears down the test fixture. | |||||
| * | |||||
| * Called after every test case method. | |||||
| */ | |||||
| protected void tearDown() | |||||
| { | |||||
| m_jDepend = null; | |||||
| } | |||||
| /** | |||||
| * Utility method to retrieve JDpenden instance that contains statistics. | |||||
| */ | |||||
| protected final JDepend getJDepend() | |||||
| { | |||||
| return m_jDepend; | |||||
| } | |||||
| /** | |||||
| * Make sure that the launcher classes in org.apache.myrmidon.launcher.* | |||||
| * are completely decoupled from the rest of the system. | |||||
| */ | |||||
| public void testLauncherDecoupled() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final String name = "org.apache.myrmidon.launcher"; | |||||
| final JavaPackage javaPackage = jDepend.getPackage( name ); | |||||
| final Collection afferentSet = javaPackage.getAfferents(); | |||||
| final Iterator afferents = afferentSet.iterator(); | |||||
| while( afferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage afferent = (JavaPackage)afferents.next(); | |||||
| final String afferentName = afferent.getName(); | |||||
| if( !afferentName.startsWith( name ) ) | |||||
| { | |||||
| fail( "The launcher package " + name + " depends on external classes " + | |||||
| "contained in " + afferentName + ". No classes besides " + | |||||
| "those in the launcher hierarchy should be referenced" ); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure that the implementations of the myrmidon kernel components | |||||
| * (ie org.apache.myrmidon.component.X.*) are not referenced by anyone | |||||
| * except by other objects in the same package or child packages. | |||||
| */ | |||||
| public void testNoComponentImplSharing() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| final String name = javaPackage.getName(); | |||||
| final String componentPackage = "org.apache.myrmidon.component."; | |||||
| if( !name.startsWith( componentPackage ) ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| final int start = componentPackage.length() + 1; | |||||
| final int end = name.indexOf( '.', start ); | |||||
| final String component = name.substring( end ); | |||||
| final Collection afferentSet = javaPackage.getAfferents(); | |||||
| final Iterator afferents = afferentSet.iterator(); | |||||
| while( afferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage efferent = (JavaPackage)afferents.next(); | |||||
| final String efferentName = efferent.getName(); | |||||
| if( !efferentName.startsWith( component ) ) | |||||
| { | |||||
| fail( "The package " + name + " is referred to by classes " + | |||||
| "contained in " + efferentName + ". No classes besides " + | |||||
| "those part of the particular implementation of kernel " + | |||||
| "component should reference the implementations" ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure that aut does not depend on any other ant classes | |||||
| * and thus can be cleanly decoupled. | |||||
| */ | |||||
| public void testAutDecoupled() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| final String name = javaPackage.getName(); | |||||
| if( !name.startsWith( "org.apache.aut" ) ) | |||||
| { | |||||
| continue; | |||||
| } | |||||
| final Collection efferentSet = javaPackage.getEfferents(); | |||||
| final Iterator efferents = efferentSet.iterator(); | |||||
| while( efferents.hasNext() ) | |||||
| { | |||||
| final JavaPackage efferent = (JavaPackage)efferents.next(); | |||||
| final String efferentName = efferent.getName(); | |||||
| if( efferentName.startsWith( "org.apache.myrmidon" ) || | |||||
| efferentName.startsWith( "org.apache.antlib" ) || | |||||
| efferentName.startsWith( "org.apache.tools.ant" ) ) | |||||
| { | |||||
| fail( "The package " + name + " depends on classes " + | |||||
| "contained in " + efferentName ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Make sure there are no circular dependencies between packages because | |||||
| * circular dependencies are evil!!! | |||||
| */ | |||||
| public void testNoCircularity() | |||||
| { | |||||
| final JDepend jDepend = getJDepend(); | |||||
| final Collection packageSet = jDepend.getPackages(); | |||||
| final Iterator packages = packageSet.iterator(); | |||||
| while( packages.hasNext() ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)packages.next(); | |||||
| if( javaPackage.containsCycle() ) | |||||
| { | |||||
| final ArrayList cycle = new ArrayList(); | |||||
| javaPackage.collectCycle( cycle ); | |||||
| final ArrayList names = getPackageNames( cycle ); | |||||
| fail( "The package " + javaPackage.getName() + " contains a cycle " + | |||||
| "with a path " + names ); | |||||
| } | |||||
| } | |||||
| } | |||||
| private ArrayList getPackageNames( final ArrayList cycle ) | |||||
| { | |||||
| final ArrayList names = new ArrayList(); | |||||
| final int size = cycle.size(); | |||||
| for( int i = 0; i < size; i++ ) | |||||
| { | |||||
| final JavaPackage javaPackage = (JavaPackage)cycle.get( i ); | |||||
| names.add( javaPackage.getName() ); | |||||
| } | |||||
| return names; | |||||
| } | |||||
| } | |||||