001 /*
002 Copyright (C) 2000 Chr. Clemens Lee <clemens@kclee.com>.
003
004 This file is part of JavaNCSS
005 (http://www.kclee.com/clemens/java/javancss/).
006
007 JavaNCSS is free software; you can redistribute it and/or modify it
008 under the terms of the GNU General Public License as published by the
009 Free Software Foundation; either version 2, or (at your option) any
010 later version.
011
012 JavaNCSS is distributed in the hope that it will be useful, but WITHOUT
013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
015 for more details.
016
017 You should have received a copy of the GNU General Public License
018 along with JavaNCSS; see the file COPYING. If not, write to
019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
020 Boston, MA 02111-1307, USA. */
021
022 package javancss.test;
023
024 import java.io.ByteArrayOutputStream;
025 import java.io.IOException;
026 import java.io.PrintStream;
027 import java.io.StringReader;
028 import java.util.ArrayList;
029 import java.util.Iterator;
030 import java.util.List;
031
032 import ccl.util.FileUtil;
033 import ccl.util.Test;
034 import ccl.util.Util;
035
036 import javancss.FunctionMetric;
037 import javancss.Javancss;
038 import javancss.ObjectMetric;
039 import javancss.PackageMetric;
040
041 /**
042 * Test class for the JavaNCSS application.
043 *
044 * $Id: JavancssTest.java 171 2009-05-31 20:12:01Z hboutemy $
045 * 3. 9. 1996
046 */
047 public class JavancssTest extends AbstractTest
048 {
049 private Javancss measureTestFile( int testFileId )
050 {
051 return new Javancss( getTestFile( testFileId ) );
052 }
053
054 private Javancss _checkNcss( int testNumber, int expectedNcss )
055 {
056 Javancss pJavancss = measureTestFile( testNumber );
057 int ncss = pJavancss.getNcss();
058 bugIf( ncss != expectedNcss, "Parsing file Test" + testNumber + ".java failed. Ncss is "
059 + ncss + " and not " + expectedNcss + "." );
060 return pJavancss;
061 }
062
063 private void _checkNcss( int testNumber )
064 {
065 Javancss pJavancss = measureTestFile( testNumber );
066 int ncss = pJavancss.getNcss();
067 bugIf( ncss == 0, "Parsing file Test" + testNumber + ".java failed. Ncss is 0" );
068 }
069
070 private Javancss _checkNcssAndLoc( int testNumber, int expectedNcss, int expectedLoc )
071 {
072 Javancss pJavancss = _checkNcss( testNumber, expectedNcss );
073 int loc = pJavancss.getLOC();
074 bugIf( loc != expectedLoc, "Parsing file Test" + testNumber + ".java failed. LOC is "
075 + loc + " and not " + expectedLoc + "." );
076 return pJavancss;
077 }
078
079 private Javancss _checkNcssAndLoc( int testNumber, int expectedNcssAndLoc )
080 {
081 return _checkNcssAndLoc( testNumber, expectedNcssAndLoc, expectedNcssAndLoc );
082 }
083
084 private Javancss _checkNcssAndLoc( int testNumber )
085 {
086 Javancss pJavancss = measureTestFile( testNumber );
087 int ncss = pJavancss.getNcss();
088 int loc = pJavancss.getLOC();
089 bugIf( ncss != loc, "Parsing file Test" + testNumber + ".java failed. Ncss is "
090 + ncss + ", LOC is " + loc + ": should be equal." );
091 return pJavancss;
092 }
093
094 /**
095 * There has been a bug introduced for version 16.34 which
096 * counts Javadoc comments (**) for fields as well as for
097 * methods, while I am only in the later ones.
098 * File Test20 has 6 methods and 6 + 1 ** comments.
099 * This test should make sure that 3 attribute comments
100 * won't be counted.
101 */
102 public void testJavadocs()
103 {
104 _enterSubTest( "javadocs" );
105
106 _checkJvdcs( 20, 7 );
107 _checkJvdcs( 68, 2 );
108 _checkJvdcs( 121, 2 );
109 _checkJvdcs( 122, 1 );
110
111 //Added by REYNAUD Sebastien (LOGICA) for JAVANCSS-20
112 _checkJvdcs( 139 , 3 );
113 _checkJvdcs( 140 , 2 );
114 _checkJvdcs( 141 , 1 );
115 //
116
117 _exitSubTest();
118 }
119
120 /**
121 * Check that Javadoc line counts are correct.
122 * There is one bug where there are only two files with
123 * a package jacob in the test directory (Test1.java and
124 * Test28.java), and while both have no javadocs at all,
125 * the count is still 11. The eleven seem to come from
126 * files Test20.java and Test21.java.
127 * This test shall trace this bug down and shall later asure
128 * that it got fixed.
129 */
130 public void testJavadocLines()
131 {
132 _enterSubTest( "javadoc lines" );
133
134 _checkJavadocLines( 28, "jacob", 0 );
135
136 //
137 // same test with more files
138 //
139 _checkJavadocLines( new int[] { 20, 21, 28 }, "jacob", 0 );
140
141 _checkJavadocLines( 68, ".", 6 );
142 _checkJavadocLines( 69, ".", 4 );
143 _checkJavadocLines( new int[] { 68, 69 }, ".", 10 );
144 _checkJavadocLines( 65, "idebughc.testsuite", 14 );
145
146 _exitSubTest();
147 }
148
149 private void _checkJavadocLines( int testFile, String sPackage, int javadocLines )
150 {
151 Javancss pJavancss = measureTestFile( testFile );
152
153 _checkJavadocLines( pJavancss, sPackage, javadocLines );
154 }
155
156 private void _checkJavadocLines( int[] aTestFile, String sPackage, int javadocLines )
157 {
158 List files = new ArrayList();
159 for( int i = 0; i < aTestFile.length; i++ )
160 {
161 int next = aTestFile[ i ];
162 files.add( getTestFile( next ) );
163 }
164
165 Javancss pJavancss = new Javancss( files );
166 _checkJavadocLines( pJavancss, sPackage, javadocLines );
167 }
168
169 private void _checkJavadocLines( Javancss pJavancss, String sPackage, int javadocLines )
170 {
171 List vPackageMetrics = pJavancss.getPackageMetrics();
172 Assert( vPackageMetrics.size() >= 1 );
173 PackageMetric pmPackage = null;
174 Iterator ePackageMetrics = vPackageMetrics.iterator();
175 while( ePackageMetrics.hasNext() )
176 {
177 PackageMetric pmNext = (PackageMetric)ePackageMetrics.next();
178 if ( pmNext.name.equals( sPackage ) )
179 {
180 pmPackage = pmNext;
181 }
182 }
183 Assert( pmPackage != null );
184 Assert( pmPackage.javadocsLn == javadocLines
185 , "pmJacob.javadocsLn: " + pmPackage + ": " + pmPackage.javadocsLn );
186 }
187
188 private void _checkParse( int testFile )
189 {
190 Javancss pJavancss = measureTestFile( testFile );
191 bugIf( pJavancss.getNcss() <= 0, "Parsing file Test" + testFile + ".java failed!" );
192 }
193
194 public JavancssTest() {
195 super();
196 }
197
198 public JavancssTest(Test pTest_) {
199 super(pTest_);
200 }
201
202 protected void _doIt()
203 throws Exception
204 {
205 Util.debug( this, "_doIt().testDir: " + getTestDir() );
206
207 testNcss();
208
209 testNcssAndMore();
210
211 testJavadocLines();
212
213 testJavadocs();
214
215 testCCN();
216
217 testEncoding();
218
219 testVersion();
220
221 testRecursive();
222
223 XmlFormatterTest xmlTest = new XmlFormatterTest( this );
224 xmlTest.setTestDir( getTestDir() );
225 xmlTest.run();
226 setTests( xmlTest );
227 }
228
229 public void testNcss()
230 {
231 _enterSubTest( "ncss" );
232
233 Javancss pJavancss = null;
234
235 _checkNcss( 2, 8 );
236 _checkNcss( 3, 69 );
237 _checkNcss( 4, 11 );
238 _checkNcss( 5, 16 );
239 _checkNcss( 7, 30 );
240 _checkNcss( 8, 30 );
241
242 _checkNcssAndLoc( 13 );
243 _checkNcssAndLoc( 14 );
244 _checkNcssAndLoc( 15 );
245
246 _checkNcss( 16, 4 );
247 _checkNcssAndLoc( 17 );
248 _checkNcssAndLoc( 18 );
249
250 _checkNcss( 20, 46 );
251 _checkNcss( 21, 67 );
252 _checkNcss( 22, 283 );
253 _checkNcss( 26, 47 );
254 _checkNcss( 27, 4 );
255 _checkNcss( 28, 465 );
256 _checkNcss( 29, 1 );
257
258 // Nr. 42
259 // missing lf in last line/<EOF> not in single line
260 try
261 {
262 _checkNcss( 35, 1 );
263 }
264 catch ( Exception eEOF )
265 {
266 bugIf( true, "}<EOF>" );
267 }
268 try
269 {
270 _checkNcss( 36, 1 );
271 }
272 catch ( Error eEOF )
273 {
274 bugIf( true, "//<EOF>" );
275 }
276 try
277 {
278 _checkNcss( 37, 1 );
279 }
280 catch ( Error eCTRLZ )
281 {
282 bugIf( true, "//ctrl-Z" );
283 }
284 try
285 {
286 _checkNcss( 38, 1 );
287 }
288 catch ( Error eCTRLZ )
289 {
290 bugIf( true, "0x0actrl-Z" );
291 }
292 // Nr. 46
293 // semicolons not allowed by JLS, but not counted anyway.
294 try
295 {
296 _checkNcss( 39, 5 );
297 }
298 catch ( Error eEmptyStatements )
299 {
300 bugIf( true, "Empty statments." );
301 }
302 // Nr. 47
303 // ;; in java.sql.Connection
304 try
305 {
306 _checkNcss( 32, 26 );
307 }
308 catch ( Error eJavaSQLConnection )
309 {
310 bugIf( true, "java.sql.Connection double semicolon" );
311 }
312
313 // javancss parsed a file which it shouldn't
314 pJavancss = measureTestFile( 42 );
315 bugIf( pJavancss.getLastErrorMessage() == null, "Test42 should be parsed *and* result in an exception." );
316
317 // file containing just ;
318 _checkNcss( 43, 0 );
319
320 // Test if javancss continues after running across a parse error
321 // Test42,java has an error, so use two other file and this and
322 // take a look if it finishes with right result.
323 pJavancss = measureTestFile( 1 );
324 int ncss57 = pJavancss.getNcss();
325 pJavancss = measureTestFile( 2 );
326 ncss57 += pJavancss.getNcss();
327 List vFiles = new ArrayList();
328 vFiles.add( getTestFile( 1 ) );
329 vFiles.add( getTestFile( 42 ) );
330 vFiles.add( getTestFile( 2 ) );
331 pJavancss = new Javancss( vFiles );
332 bugIf( pJavancss.getNcss() != ncss57, "ncss57: " + ncss57 + " pJavancss.getNcss(): " + pJavancss.getNcss() );
333
334 // Bug reported by .. .
335 // Test48.java should be parsed.
336 _checkParse( 48 );
337
338 _checkNcss( 49, 3 );
339
340 _checkParse( 50 );
341
342 _checkNcss( 51, 8 );
343 _checkNcss( 52, 12 );
344 _checkNcss( 53, 4 );
345 _checkNcss( 54, 9 );
346 _checkNcss( 55, 5 );
347 _checkNcss( 56 );
348 _checkNcss( 57 );
349 _checkNcss( 58, 37 );
350 _checkNcss( 59, 122 );
351 _checkNcss( 60, 35 );
352 _checkNcss( 61, 203 );
353 _checkNcss( 62, 616 );
354 _checkNcss( 63, 330 );
355 _checkNcss( 64, 70 );
356 _checkNcss( 65, 301 );
357 _checkNcss( 66, 3 );
358 _checkNcss( 67, 31 );
359
360 // more comment counting
361 _checkNcss( 68, 3 );
362
363 // zero methods one class javadoc comment, there should be no exception
364 // because of divide by zero
365 _checkNcss( 69, 1 );
366
367 /*
368 * This method tries to reproduce a bug reported by
369 * Chris Williamson. He reported problems with code
370 * like this: F150MemoryMap f150Map = (F150MemoryMap) F150.super.memMap;
371 */
372 _checkNcss( 70, 4 );
373
374 // test for strictfp interface and static inner interface
375 _checkNcss( 73, 1 );
376 _checkNcss( 74, 2 );
377
378 //
379 // new Java 1.5 features
380 //
381
382 // @Deprecated annotation
383 _checkNcss( 75, 584 );
384 // Class<?>
385 _checkNcss( 76, 404 );
386 // Class<?,?>
387 _checkNcss( 77, 48 );
388 // WeakHashMap<ImageInputStream, Object>
389 _checkNcss( 78, 35 );
390 // Map<String, Map<String, Object>>
391 _checkNcss( 79, 1345 );
392 // @Deprecated protected KeyStroke closeMenuKey;
393 _checkNcss( 80, 96 );
394 // etc.
395 _checkNcss( 81, 92 );
396 _checkNcss( 82, 26 );
397 _checkNcss( 83, 2 );
398 _checkNcss( 84, 55 );
399 _checkNcss( 85, 242 );
400 _checkNcss( 86, 22 );
401 _checkNcss( 87, 8 );
402 _checkNcss( 88, 11 );
403 _checkNcss( 89, 65 );
404 _checkNcss( 90, 494 );
405 _checkNcss( 91, 30 );
406 _checkNcss( 92, 6 );
407 _checkNcss( 93, 38 );
408 _checkNcss( 94, 3 );
409 _checkNcss( 95, 10 );
410 _checkNcss( 96, 3 );
411 _checkNcss( 97, 3 );
412 _checkNcss( 98, 37 );
413 _checkNcss( 99, 243 );
414 _checkNcss( 100, 5 );
415 _checkNcss( 101, 256 );
416 _checkNcss( 102, 10 );
417 _checkNcss( 103, 3 );
418 _checkNcss( 104, 3 );
419 _checkNcss( 105, 5 );
420 _checkNcss( 106, 10 );
421 _checkNcss( 107, 9 );
422 _checkNcss( 108, 2 );
423 _checkNcss( 109, 2 );
424 _checkNcss( 110, 1 );
425 _checkNcss( 111, 4 );
426 _checkNcss( 112, 3 );
427 _checkNcss( 113, 13 );
428 _checkNcss( 114, 3 );
429 _checkNcss( 115, 11663 );
430 _checkNcss( 116, 12 );
431 _checkNcss( 117, 15 );
432 _checkNcss( 119, 2 );
433 _checkNcss( 120, 3 );
434 _checkNcss( 121, 5 );
435 _checkNcss( 123, 4 );
436 _checkNcss( 124, 7 );
437 _checkNcss( 125, 2 );
438 _checkNcss( 126, 13 );
439 _checkNcss( 127, 3 );
440 _checkNcss( 128, 3 );
441 _checkNcss( 129, 6 );
442 _checkNcss( 130, 5 );
443 _checkNcss( 131, 6 );
444 _checkNcss( 132, 12 );
445 _checkNcss( 134, 4 );
446 _checkNcss( 136, 2 );
447 _checkNcss( 138, 3 );
448 _checkParse( 142 ); // JAVANCSS-12
449 _checkParse( 143 ); // JAVANCSS-9
450 _checkParse( 144 ); // JAVANCSS-13
451 _checkParse( 145 ); // JAVANCSS-14
452 _checkParse( 146 ); // JAVANCSS-17
453
454 _exitSubTest();
455 }
456
457 public void testNcssAndMore() throws IOException
458 {
459 _enterSubTest( "ncss and more..." );
460
461 Javancss pJavancss = null;
462
463 final int ncss1 = 318;
464 _checkNcss( 1 , ncss1 );
465
466 final int ncss6 = 565;
467 _checkNcssAndLoc( 6, ncss6, 1254 );
468
469 // Nr. 10
470 pJavancss = measureTestFile( 9 );
471 bugIf( ncss1 != pJavancss.getLOC(), "LOC: " + pJavancss.getLOC() );
472
473 _checkNcssAndLoc( 10, ncss6 );
474 _checkNcssAndLoc( 11 );
475
476 pJavancss = _checkNcssAndLoc( 12 );
477 List/*<FunctionMetric>*/ vFunctions = pJavancss.getFunctionMetrics();
478 String sFirstFunction = ( (FunctionMetric) vFunctions.get( 0 ) ).name;
479 bugIf( sFirstFunction == null );
480 /* System.out.println( sFirstFunction ); */
481 bugIf( !sFirstFunction.equals( "Test12.readFile(URL)" ), sFirstFunction );
482
483 // Nr. 22
484 pJavancss = measureTestFile( 19 );
485 vFunctions = pJavancss.getFunctionMetrics();
486 sFirstFunction = ( (FunctionMetric) vFunctions.get( 0 ) ).name;
487 bugIf( !sFirstFunction.equals( "test.Test19.foo(String[],Controller)" ), sFirstFunction );
488 sFirstFunction = ( (FunctionMetric) vFunctions.get( 3 ) ).name;
489 bugIf( !sFirstFunction.equals( "test.Test19.main(String[])" ) );
490
491 pJavancss = _checkNcss( 23, 10 );
492 vFunctions = pJavancss.getFunctionMetrics();
493 bugIf( vFunctions.size() != 7 );
494 bugIf( new Javancss( getTestFile( 24 ) ).getFunctionMetrics().size() != vFunctions.size() );
495
496 // Nr. 30
497 pJavancss = _checkNcss( 25, 12 );
498 bugIf( pJavancss.getFunctionMetrics().size() != 9 );
499
500 // Nr. 35
501 String sTogether;
502 String sTest11 = "";
503 String sTest12 = "";
504 try
505 {
506 sTest11 = FileUtil.readFile( getTestFile( 11 ).getAbsolutePath() );
507 sTest12 = FileUtil.readFile( getTestFile( 12 ).getAbsolutePath() );
508 }
509 catch ( IOException e )
510 {
511 bugIf( true );
512 }
513 sTogether = sTest11 + sTest12;
514 pJavancss = new Javancss( new StringReader( sTogether ) );
515 vFunctions = pJavancss.getFunctionMetrics();
516 Util.debug( "JavancssTest._doIt().vFunctions: " + vFunctions );
517 sFirstFunction = ( (FunctionMetric) vFunctions.get( 0 ) ).name;
518 bugIf( !sFirstFunction.equals( "ccl.util.Test11.atoi(String)" ) );
519 String sSomeFunction = ( (FunctionMetric) vFunctions.get( 32 ) ).name;
520 bugIf( !sSomeFunction.equals( "Test12.readFile(URL)" ), "Function: " + sSomeFunction );
521 List vPackages = pJavancss.getPackageMetrics();
522 bugIf( vPackages.size() != 2 );
523 int ncss38 = pJavancss.getNcss();
524
525 String[] asArg = new String[3];
526 asArg[0] = getTestFile( 11 ).getAbsolutePath();
527 asArg[1] = asArg[0];
528 asArg[2] = getTestFile( 12 ).getAbsolutePath();
529 pJavancss = measureWithArgs( asArg );
530 vPackages = pJavancss.getPackageMetrics();
531 bugIf( vPackages.size() != 2 );
532 bugIf( ncss38 == pJavancss.getNcss() );
533
534 pJavancss = measureTestFile( 56 );
535 String sOutput56 = pJavancss.printPackageNcss();
536 sOutput56 += "\n";
537 sOutput56 += pJavancss.printObjectNcss();
538 sOutput56 += "\n";
539 sOutput56 += pJavancss.printFunctionNcss();
540 sOutput56 = Util.replace( sOutput56, "\r\n", "\n" );
541 String sCompare56 = FileUtil.readFile( getTestFile( "Output56.txt" ).getAbsolutePath() );
542 Assert( sOutput56.equals( sCompare56 ), "File test/Output56.txt and javancss output differs:\n" + sOutput56 );
543
544 // check that javadocs are counted correctly
545 // after patches for additional comment counting
546 pJavancss = measureTestFile( 32 );
547 String sOutput32 = pJavancss.printPackageNcss();
548 sOutput32 += "\n";
549 sOutput32 += pJavancss.printObjectNcss();
550 sOutput32 += "\n";
551 sOutput32 += pJavancss.printFunctionNcss();
552 sOutput32 = Util.replace( sOutput32, "\r\n", "\n" );
553 String sCompare32 = FileUtil.readFile( getTestFile( "Output32.txt" ).getAbsolutePath() );
554 Assert( sOutput32.equals( sCompare32 ), "File test/Output32.txt and javancss output differs:\n" + sOutput32 );
555
556 _exitSubTest();
557 }
558
559 private void _checkJvdcs( int testFileNumber, int expectedJvdcsResult )
560 {
561 Javancss pJavancss = measureTestFile( testFileNumber );
562 List/*<ObjectMetric>*/ vObjectMetrics = pJavancss.getObjectMetrics();
563 ObjectMetric classMetric = (ObjectMetric) vObjectMetrics.get( 0 );
564 int jvdcs = classMetric.javadocs;
565 /* int jvdc = pJavancss.getJvdc(); */
566 bugIf( jvdcs != expectedJvdcsResult, "Parsing file Test" + testFileNumber + ".java failed. Jvdc is " + jvdcs
567 + " and not " + expectedJvdcsResult + "." );
568 }
569
570 /**
571 * Tests the cyclomatic complexity number measurement.
572 */
573 public void testCCN()
574 {
575 _enterSubTest( "ccn" );
576
577 // CCN for return and throw
578 Javancss pJavancss = measureTestFile( 40 );
579 List/*<FunctionMetric>*/ vFunctions = pJavancss.getFunctionMetrics();
580 bugIf( vFunctions.size() != 1 );
581 assertCCN( vFunctions, 0, 3 );
582
583 pJavancss = measureTestFile( 41 );
584 vFunctions = pJavancss.getFunctionMetrics();
585 assertCCN( vFunctions, 0, 3 );
586 assertCCN( vFunctions, 1, 1 );
587 assertCCN( vFunctions, 2, 3 );
588 assertCCN( vFunctions, 3, 3 );
589 assertCCN( vFunctions, 4, 1 );
590
591 pJavancss = measureTestFile( 72 );
592 vFunctions = pJavancss.getFunctionMetrics();
593 assertCCN( vFunctions, 0, 4 );
594 assertCCN( vFunctions, 1, 5 );
595 assertCCN( vFunctions, 2, 4 );
596 assertCCN( vFunctions, 3, 4 );
597 assertCCN( vFunctions, 4, 2 );
598
599 _exitSubTest();
600 }
601
602 private void assertCCN( List vFunctions, int methodIndex, int expectedCCN )
603 {
604 int ccn = ( (FunctionMetric) vFunctions.get( methodIndex ) ).ccn;
605 Assert( ccn == expectedCCN, "Expected ccn was " + expectedCCN + " but the result is: " + ccn );
606 }
607
608 public static void main( String[] asArg_ )
609 {
610 new JavancssTest().main();
611 }
612
613 private Javancss measureWithArgs( String[] args ) throws IOException
614 {
615 // turn stdout off
616 PrintStream psStdout = System.out;
617
618 try
619 {
620 System.setOut( new PrintStream( new ByteArrayOutputStream() ) );
621 return new Javancss(args);
622 }
623 finally
624 {
625 // turn stdout back on
626 System.setOut( psStdout );
627 }
628 }
629
630 public void testEncoding() throws IOException
631 {
632 _enterSubTest( "encoding" );
633
634 String[] args = new String[] { "-encoding", "UTF-16", getTestFile( "TestEncoding.java" ).getAbsolutePath() };
635 Javancss pJavancss = measureWithArgs( args );
636
637 int expectedNcss = 11;
638 int ncss = pJavancss.getNcss();
639
640 bugIf( ncss != expectedNcss,
641 "Parsing file TestEncoding.java failed. Ncss is " + ncss + " and not " + expectedNcss + "." );
642
643 _exitSubTest();
644 }
645
646 public void testVersion() throws IOException
647 {
648 _enterSubTest( "version" );
649
650 String[] args = new String[] { "-version" };
651 measureWithArgs( args );
652
653 _exitSubTest();
654 }
655
656 public void testRecursive() throws IOException
657 {
658 _enterSubTest( "recursive" );
659
660 String[] args = new String[] { "-recursive", getTestFile( "../lib" ).getAbsolutePath() };
661 measureWithArgs( args );
662
663 _exitSubTest();
664 }
665 }