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    }