001 /** 002 * www.jcoverage.com 003 * Copyright (C)2003 jcoverage ltd. 004 * 005 * This file is part of jcoverage. 006 * 007 * jcoverage is free software; you can redistribute it and/or modify 008 * it under the terms of the GNU General Public License as published 009 * by the Free Software Foundation; either version 2 of the License, 010 * or (at your option) any later version. 011 * 012 * jcoverage is distributed in the hope that it will be useful, but 013 * WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with jcoverage; if not, write to the Free Software 019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 020 * USA 021 * 022 */ 023 package com.jcoverage.tool.coveragecheck; 024 025 import com.jcoverage.coverage.Instrumentation; 026 import com.jcoverage.coverage.InstrumentationPersistence; 027 import com.jcoverage.coverage.Version; 028 029 import gnu.getopt.Getopt; 030 import gnu.getopt.LongOpt; 031 032 import java.io.File; 033 import java.io.FileInputStream; 034 import java.io.IOException; 035 import java.math.BigDecimal; 036 import java.util.Iterator; 037 import java.util.HashMap; 038 import java.util.Map; 039 import java.util.StringTokenizer; 040 041 import org.apache.log4j.Logger; 042 043 import org.apache.oro.text.regex.MalformedPatternException; 044 import org.apache.oro.text.regex.Pattern; 045 import org.apache.oro.text.regex.Perl5Compiler; 046 import org.apache.oro.text.regex.Perl5Matcher; 047 048 049 public class Main extends InstrumentationPersistence { 050 static final Logger logger=Logger.getLogger(Main.class); 051 052 final Perl5Matcher pm=new Perl5Matcher(); 053 final Perl5Compiler pc=new Perl5Compiler(); 054 055 Map minimumCoverageRates=new HashMap(); 056 CoverageRate minimumCoverageRate; 057 058 File instrumentationDirectory=new File(System.getProperty("user.dir")); 059 060 void setInstrumentationDirectory(File instrumentationDirectory) { 061 this.instrumentationDirectory=instrumentationDirectory; 062 } 063 064 double inRangeAndDivideByOneHundred(String coverageRateAsPercentage) { 065 return inRangeAndDivideByOneHundred(Integer.valueOf(coverageRateAsPercentage).intValue()); 066 } 067 068 double inRangeAndDivideByOneHundred(int coverageRateAsPercentage) { 069 if((coverageRateAsPercentage>=0)&&(coverageRateAsPercentage<=100)) { 070 return ((double)coverageRateAsPercentage)/100d; 071 } 072 throw new IllegalArgumentException("Invalid value, valid range is [0 .. 100]"); 073 } 074 075 void setMinimumCoverageRate(String minimumCoverageRate) throws MalformedPatternException { 076 StringTokenizer tokenizer=new StringTokenizer(minimumCoverageRate,":"); 077 minimumCoverageRates.put(pc.compile(tokenizer.nextToken()),new CoverageRate(inRangeAndDivideByOneHundred(tokenizer.nextToken()),inRangeAndDivideByOneHundred(tokenizer.nextToken()))); 078 } 079 080 CoverageRate findMinimumCoverageRate(String key) { 081 Iterator i=minimumCoverageRates.entrySet().iterator(); 082 while(i.hasNext()) { 083 Map.Entry entry=(Map.Entry)i.next(); 084 085 if(pm.matches(key,(Pattern)entry.getKey())) { 086 return (CoverageRate)entry.getValue(); 087 } 088 } 089 return minimumCoverageRate; 090 } 091 092 093 Main(String[] args) throws IOException,MalformedPatternException { 094 System.out.println("jcoverage "+Version.VERSION_STRING+" copyright (c)2003 jcoverage ltd. http://jcoverage.com/"); 095 System.out.println("jcoverage is licensed under the GNU General Public License"); 096 System.out.println("jcoverage comes with ABSOLUTELY NO WARRANTY"); 097 System.out.println("jcoverage check"); 098 099 LongOpt[] longOpts=new LongOpt[4]; 100 longOpts[0]=new LongOpt("branch",LongOpt.REQUIRED_ARGUMENT,null,'b'); 101 longOpts[1]=new LongOpt("line",LongOpt.REQUIRED_ARGUMENT,null,'l'); 102 longOpts[2]=new LongOpt("directory",LongOpt.REQUIRED_ARGUMENT,null,'d'); 103 longOpts[3]=new LongOpt("regex",LongOpt.REQUIRED_ARGUMENT,null,'r'); 104 105 106 Getopt g=new Getopt(getClass().getName(),args,":b:l:d:r:",longOpts); 107 int c; 108 109 double branchCoverageRate=0.8; 110 double lineCoverageRate=0.7; 111 112 while((c=g.getopt())!=-1) { 113 switch(c) { 114 case 'b': 115 branchCoverageRate=inRangeAndDivideByOneHundred(g.getOptarg()); 116 break; 117 118 case 'l': 119 lineCoverageRate=inRangeAndDivideByOneHundred(g.getOptarg()); 120 break; 121 122 case 'd': 123 setInstrumentationDirectory(new File(g.getOptarg())); 124 break; 125 126 case 'r': 127 setMinimumCoverageRate(g.getOptarg()); 128 break; 129 } 130 } 131 132 minimumCoverageRate=new CoverageRate(lineCoverageRate,branchCoverageRate); 133 134 if(logger.isInfoEnabled()) { 135 logger.info("instrumentation directory: "+instrumentationDirectory); 136 } 137 138 merge(loadInstrumentation(new FileInputStream(new File(instrumentationDirectory,Instrumentation.FILE_NAME)))); 139 140 if(logger.isInfoEnabled()) { 141 logger.info("instrumentation has "+keySet().size()+" entries"); 142 } 143 144 Iterator i=keySet().iterator(); 145 while(i.hasNext()) { 146 String key=(String)i.next(); 147 148 CoverageRate coverageRate=findMinimumCoverageRate(key); 149 Instrumentation instrumentation=getInstrumentation(key); 150 151 if(logger.isInfoEnabled()) { 152 StringBuffer sb=new StringBuffer(); 153 sb.append(key); 154 sb.append(", line: "); 155 sb.append(percentage(instrumentation.getLineCoverageRate())); 156 sb.append("% ("); 157 sb.append(percentage(coverageRate.getLineCoverageRate())); 158 sb.append("%), branch: "); 159 sb.append(percentage(instrumentation.getBranchCoverageRate())); 160 sb.append("% ("); 161 sb.append(percentage(coverageRate.getBranchCoverageRate())); 162 sb.append("%)"); 163 logger.info(sb.toString()); 164 } 165 166 167 if(instrumentation.getLineCoverageRate()<coverageRate.getLineCoverageRate()) { 168 StringBuffer sb=new StringBuffer(); 169 sb.append(key); 170 sb.append(" line coverage rate of: "); 171 sb.append(percentage(instrumentation.getLineCoverageRate())); 172 sb.append("% (required: "); 173 sb.append(percentage(coverageRate.getLineCoverageRate())); 174 sb.append("%)"); 175 System.out.println(sb.toString()); 176 } 177 178 if(instrumentation.getBranchCoverageRate()<coverageRate.getBranchCoverageRate()) { 179 StringBuffer sb=new StringBuffer(); 180 sb.append(key); 181 sb.append(" branch coverage rate of: "); 182 sb.append(percentage(instrumentation.getBranchCoverageRate())); 183 sb.append("% (required: "); 184 sb.append(percentage(coverageRate.getBranchCoverageRate())); 185 sb.append("%)"); 186 System.out.println(sb.toString()); 187 } 188 } 189 } 190 191 String percentage(double coverateRate) { 192 BigDecimal decimal=new BigDecimal(coverateRate*100); 193 return decimal.setScale(1,BigDecimal.ROUND_DOWN).toString(); 194 } 195 196 public static void main(String[] args) throws IOException,MalformedPatternException { 197 new Main(args); 198 } 199 }