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 */
023package com.jcoverage.tool.coveragecheck;
024
025import com.jcoverage.coverage.Instrumentation;
026import com.jcoverage.coverage.InstrumentationPersistence;
027import com.jcoverage.coverage.Version;
028
029import gnu.getopt.Getopt;
030import gnu.getopt.LongOpt;
031
032import java.io.File;
033import java.io.FileInputStream;
034import java.io.IOException;
035import java.math.BigDecimal;
036import java.util.Iterator;
037import java.util.HashMap;
038import java.util.Map;
039import java.util.StringTokenizer;
040
041import org.apache.log4j.Logger;
042
043import org.apache.oro.text.regex.MalformedPatternException;
044import org.apache.oro.text.regex.Pattern;
045import org.apache.oro.text.regex.Perl5Compiler;
046import org.apache.oro.text.regex.Perl5Matcher;
047
048
049public 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}