/** * Copyright (c) 2008-2011 Sonatype, Inc. * All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions. * * This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General * Public License Version 3 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3 * for more details. * * You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see * http://www.gnu.org/licenses. * * Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of * Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation. * All other trademarks are the property of their respective owners. */ package org.sonatype.nexus.integrationtests.report; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.codehaus.plexus.util.StringUtils; import org.junit.Test; import com.thoughtworks.qdox.JavaDocBuilder; import com.thoughtworks.qdox.model.Annotation; import com.thoughtworks.qdox.model.JavaClass; import com.thoughtworks.qdox.model.JavaMethod; public class ReportWriter { private File sourceDir; public ReportWriter( File sourceDir ) { this.sourceDir = sourceDir; } public void writeReport() { // parse the java doc JavaDocBuilder builder = new JavaDocBuilder(); builder.addSourceTree( this.sourceDir ); // all parsed // now find all of the test classes List<JavaClass> testClasses = new ArrayList<JavaClass>(); JavaClass[] classes = builder.getClasses(); List<JavaClass> classesWithoutDescriptions = new ArrayList<JavaClass>(); for ( int ii = 0; ii < classes.length; ii++ ) { JavaClass javaClass = classes[ii]; if ( !javaClass.isAbstract() && classHasMethodWithTestAnnotation( javaClass ) ) { testClasses.add( javaClass ); // check if we have a javadoc comment if ( StringUtils.isEmpty( javaClass.getComment() ) ) { classesWithoutDescriptions.add( javaClass ); } } } List<ReportBean> beans = new ArrayList<ReportBean>(); for ( JavaClass javaClass : testClasses ) { ReportBean bean = new ReportBean(); bean.setJavaClass( javaClass ); bean.setTestId( this.getTestId( javaClass ) ); // add to the collection beans.add( bean ); } // sort the beans. Collections.sort( beans ); // now this would be nice to be configurable, but move the sample tests to the top of the list this.fudgeOrder( beans ); // now write the report // TODO: get from container new ConsoleWikiReport().writeReport( beans ); // print errors here.. this should be handled better, but there are no plans for this 'report' anyway. if ( !classesWithoutDescriptions.isEmpty() ) { System.err.println( "\n\n\n\nErrors:\n" ); for ( Iterator<JavaClass> iter = classesWithoutDescriptions.iterator(); iter.hasNext(); ) { JavaClass javaClass = (JavaClass) iter.next(); System.err.println( javaClass.getName() + " is missing a javadoc comment." ); } } } private void fudgeOrder( List<ReportBean> beans ) { ReportBean nexus166Sample = this.removeBeanFromList( beans, "NEXUS-166" ); ReportBean nexus262SampleProxy = this.removeBeanFromList( beans, "NEXUS-262" ); beans.add( 0, nexus262SampleProxy ); beans.add( 0, nexus166Sample ); } /** * Looks for any class that contains a Junit 4 annotation <code>@Test</code>. * @param javaClass * @return */ private static boolean classHasMethodWithTestAnnotation( JavaClass javaClass ) { JavaMethod[] methods = javaClass.getMethods(); for ( JavaMethod javaMethod : methods ) { List<Annotation> annotations = Arrays.asList( javaMethod.getAnnotations() ); for ( Iterator<Annotation> iter = annotations.iterator(); iter.hasNext(); ) { Annotation annotation = iter.next(); if ( annotation.getType().getValue().equals( Test.class.getName() ) ) { return true; } } } return false; } private String getTestId( JavaClass javaClass ) { String packageName = javaClass.getPackage(); String testId = packageName.substring( packageName.lastIndexOf( '.' ) + 1, packageName.length() ).toLowerCase(); if ( testId.startsWith( "nexus" ) ) { testId = testId.replace( "nexus", "NEXUS-" ); } else { throw new RuntimeException( "The class: " + javaClass.getName() + " is not using the correct format for package. It sould be something like: <org.sonatype.nexus.inegrationtests>.nexusXXX.NexusXXXDescription. it was: " + javaClass.getPackage() + "." + javaClass.getName() ); } return testId; } private ReportBean removeBeanFromList( List<ReportBean> beans, String testId ) { for ( ReportBean bean : beans ) { if ( testId.equals( bean.getTestId() ) ) { beans.remove( bean ); return bean; } } return null; } public static void main( String[] args ) { File currentDir = new File( "." ); File sourceDir = null; File parentFile = currentDir.getAbsoluteFile(); while ( parentFile != null ) { if ( parentFile.getName().equals( "nexus-test-harness-launcher" ) ) { sourceDir = new File( parentFile, "/src/test/java" ); // we are done with this loop break; } // change the parent parentFile = parentFile.getParentFile(); } // make sure we have something if ( sourceDir == null ) { System.err.println( "Could not figre out the source dir: nexus-test-harness-launcher/src/test/java" ); } // now we can write the report new ReportWriter( sourceDir ).writeReport(); } }