001    /*BEGIN_COPYRIGHT_BLOCK
002     *
003     * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
004     * All rights reserved.
005     * 
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *    * Redistributions of source code must retain the above copyright
009     *      notice, this list of conditions and the following disclaimer.
010     *    * Redistributions in binary form must reproduce the above copyright
011     *      notice, this list of conditions and the following disclaimer in the
012     *      documentation and/or other materials provided with the distribution.
013     *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014     *      names of its contributors may be used to endorse or promote products
015     *      derived from this software without specific prior written permission.
016     * 
017     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028     *
029     * This software is Open Source Initiative approved Open Source Software.
030     * Open Source Initative Approved is a trademark of the Open Source Initiative.
031     * 
032     * This file is part of DrJava.  Download the current version of this project
033     * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034     * 
035     * END_COPYRIGHT_BLOCK*/
036    
037    package edu.rice.cs.javalanglevels;
038    import edu.rice.cs.javalanglevels.parser.*;
039    import edu.rice.cs.javalanglevels.tree.*;
040    import edu.rice.cs.javalanglevels.util.Log;
041    import junit.framework.TestCase;
042    import java.util.*;
043    import java.io.*;
044    import edu.rice.cs.plt.reflect.JavaVersion;
045    import edu.rice.cs.plt.iter.IterUtil;
046    import edu.rice.cs.plt.io.IOUtil;
047    
048    import static edu.rice.cs.javalanglevels.ElementaryLevelTest.lf;
049    
050    /** This is a high-level test to make sure that taking an Advanced Level file from
051      * source file to augmented file has the correct behavior, does not throw errors when
052      * it should not, throws errors when it should, and results in the correct augmented code.
053      * Files that should be successfully tested are placed in the testFiles/forAdvancedLevelTest folder 
054      * as .dj2 files, and the expected augmented files asre also placed in the testFiles/forAdvancedLevelTest
055      * folder with the same name, but a .expected extension.  Files that are expected to generate errors are
056      * placed in the testFiles/forAdvancedLevelTest/shouldBreak folder, as .dj2 files.
057      * Other subdirectories are used for other tests.
058      */
059    import java.util.*;
060      
061    public class AdvancedLevelTest extends TestCase {
062        
063      public static final Log _log = new Log("LLConverter.txt", false);
064      
065      File dir1, dir2, dir3;
066      FileFilter dj2Filter, dj2JavaFilter;
067      
068      public void setUp() { 
069        dir1 = new File("testFiles/forAdvancedLevelTest"); 
070        dir2 = new File("testFiles/forAdvancedLevelTest/importedFiles"); 
071        dir3 = new File("testFiles/forAdvancedLevelTest/importedFiles2"); 
072        
073        dj2Filter = new FileFilter() {
074          public boolean accept(File pathName) {
075            String name = pathName.getAbsolutePath();
076            return (name.endsWith(".dj2"));
077          }
078        };
079        dj2JavaFilter = new FileFilter() {
080          public boolean accept(File pathName) {
081            String name = pathName.getAbsolutePath();
082            return (name.endsWith(".dj2") || name.endsWith(".java"));
083          }
084        };
085      }
086      
087      /** This ensures that setUp() is not failing. */
088      public void testNothing() {
089        LanguageLevelVisitor llv = 
090          new LanguageLevelVisitor(new File(""), 
091                                   "",
092                                   null,
093                                   new LinkedList<String>(), 
094                                   new LinkedList<String>(),
095                                   new HashSet<String>(), 
096                                   new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(),
097                                   new LinkedList<Command>());
098      }
099      
100      /** Try some example files and make sure they can be converted without errors and that the resulting conversions are 
101        * correct. */
102      public void testSuccessful() {
103    
104        _log.log("Running testSuccessful");
105        File[] files1 = dir1.listFiles(dj2Filter);
106        File[] files2 = dir2.listFiles(dj2Filter);
107        File[] files3 = dir3.listFiles(dj2Filter);
108    
109        LanguageLevelConverter llc = new LanguageLevelConverter();
110        // testFiles = files1 || files2 || files3; this computation is ugly in Java because Java has no functional lists
111        int len1 = files1.length;
112        int len2 = files2.length;
113        int len3 = files3.length;
114        File[] testFiles = new File[len1 + len2 + len3];
115        for (int i = 0; i < len1; i++) { testFiles[i] = files1[i]; }
116        for (int i = 0; i < len2; i++) { testFiles[len1 + i] = files2[i]; }
117        for (int i = 0; i < len3; i++) { testFiles[len1 + len2 + i] = files3[i]; }
118            
119        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
120        result = llc.convert(testFiles, new Options(JavaVersion.JAVA_5, IterUtil.<File>empty()));
121        
122    //    System.err.println("testFiles = " + Arrays.toString(testFiles));
123        
124        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
125        assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
126        
127        /**Now make sure that the resulting java files are correct.*/
128        for(int i = 0; i < testFiles.length; i++) {
129          File currFile = testFiles[i];
130          String fileName = currFile.getAbsolutePath();
131          fileName = fileName.substring(0, fileName.length() -4);
132          File resultingFile = new File(fileName + ".java");
133          File correctFile = new File(fileName + ".expected");
134          
135          if (correctFile.exists()) {
136            try {
137              assertEquals("File " + currFile.getName() + " should have been parsed and augmented correctly.",
138                           lf(IOUtil.toString(correctFile)),
139                           lf(IOUtil.toString(resultingFile)));
140            }
141            catch (IOException ioe) {
142              fail(ioe.getMessage());
143              // let JUnit throw the exception
144            }
145          }
146        }
147        
148        //test the subdirectory files as well.
149        File dir2 = new File(dir1.getAbsolutePath() + System.getProperty("file.separator") + "importedFiles");
150        testFiles = dir2.listFiles(new FileFilter() {
151          public boolean accept(File pathName) {
152            String name = pathName.getAbsolutePath();
153            return name.endsWith("IsItPackageAndImport.dj1") || name.endsWith("ToReference.dj1");
154          }});
155          
156          /**Now make sure that the resulting java files are correct.*/
157          for(int i = 0; i < testFiles.length; i++) {
158            File currFile = testFiles[i];
159            String fileName = currFile.getAbsolutePath();
160            fileName = fileName.substring(0, fileName.length() -4);
161            File resultingFile = new File(fileName + ".java");
162            File correctFile = new File(fileName + ".expected");
163            
164            if (correctFile.exists()) {
165              try {
166                assertEquals("File " + currFile.getName() + " should have been parsed and augmented correctly.",
167                             lf(IOUtil.toString(correctFile)),
168                             lf(IOUtil.toString(resultingFile)));
169              }
170              catch (IOException ioe) {
171                fail(ioe.getMessage());
172                // let JUnit throw the exception
173              }
174            }
175          }
176          
177    //      //And make sure that no java file was generated for ToReference2.dj1
178    //      //(This is testing that we correctly handled what could have been an ambiguous name reference, but wasn't)
179    //      File f = new File(dir2, "ToReference2.java");
180    //      assertFalse("ToReference2.java should not exist", f.exists());
181          
182          File f;
183          dir2 = new File(dir1.getAbsolutePath() + System.getProperty("file.separator") + "importedFiles2");
184          testFiles = dir2.listFiles(new FileFilter() {
185            public boolean accept(File pathName) {
186              return pathName.getAbsolutePath().endsWith("AlsoReferenced.dj1");
187            }});
188            
189            /**Now make sure that the resulting java files are correct.*/
190            for(int i = 0; i < testFiles.length; i++) {
191              File currFile = testFiles[i];
192              String fileName = currFile.getAbsolutePath();
193              fileName = fileName.substring(0, fileName.length() -4);
194              File resultingFile = new File(fileName + ".java");
195              File correctFile = new File(fileName + ".expected");
196              
197              if (correctFile.exists()) {
198                try {
199                  assertEquals("File " + currFile.getName() + " should have been parsed and augmented correctly.",
200                               lf(IOUtil.toString(correctFile)),
201                               lf(IOUtil.toString(resultingFile)));
202                }
203                catch (IOException ioe) {
204                  fail(ioe.getMessage());
205                  // let JUnit throw the exception
206                }
207              }
208            }
209            
210    //        //And make sure that no java file was generated for ToReference.dj1
211    //        f = new File(dir2, "ToReference.java");
212    //        assertFalse("ToReference.java should not exist", f.exists());
213    //        fail("Ensure that System.err is dumped");
214            
215      }
216      
217      /** This file used to have a NullPointer Exception in it because of a bug in the code.  Leave the test in so that the bug
218        * never gets reintroduced.
219        */
220      public void testNoNullPointer() { 
221        _log.log("Running testNoNullPointer");
222        dir1 = new File(dir1.getAbsolutePath() + "/shouldBreak");
223        File[] testFiles = dir1.listFiles(new FileFilter() {
224          public boolean accept(File pathName) {
225            return pathName.getAbsolutePath().endsWith("SwitchDoesntAssign.dj2");
226          }});
227        _log.log("testFiles = " + testFiles);
228        LanguageLevelConverter llc = new LanguageLevelConverter();
229        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
230        for (int i = 0; i<testFiles.length; i++) {
231          result = llc.convert(new File[]{testFiles[i]}, new Options(JavaVersion.JAVA_5, IterUtil.<File>empty()));
232          assertTrue("should be parse exceptions or visitor exceptions", !result.getFirst().isEmpty() || !result.getSecond().isEmpty());
233          }
234      }  
235        
236      /** Make sure that the order packaged files are compiled in does not matter.
237        * This is to make sure that a bug that was fixed stays fixed.
238        */
239      public void testPackagedOrderMatters() {
240        _log.log("Running testPackagedOrderMatters");
241        dir2 = new File(dir1.getAbsolutePath() + System.getProperty("file.separator") + "lists-dj2" + 
242                        System.getProperty("file.separator") + "src" + System.getProperty("file.separator") + "listFW");
243        File[] testFiles = 
244          new File[]{ new File(dir2, "NEList.dj2"), new File(dir2, "MTList.dj2"), new File(dir2, "IList.dj2")};
245        
246    //    System.err.println("testfiles = " + Arrays.toString(testFiles));
247    
248        LanguageLevelConverter llc = new LanguageLevelConverter();
249        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
250        result = llc.convert(testFiles, new Options(JavaVersion.JAVA_5, IterUtil.<File>empty()));
251    //    System.err.println("ParseExceptions: " + result.getFirst());
252    //    System.err.println("VisitorExceptions: " + result.getSecond());
253        
254        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
255        
256        assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
257        
258        //don't worry about checking the .java files for correctness...just make sure there weren't any exceptions
259      }
260    }