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 junit.framework.TestCase;
041    import java.util.*;
042    import java.io.*;
043    import edu.rice.cs.plt.reflect.JavaVersion;
044    import edu.rice.cs.plt.iter.*;
045    import edu.rice.cs.plt.io.IOUtil;
046    
047    /** This is a high-level test to make sure that taking an Elementary Level file from
048      * source file to augmented file has the correct behavior, does not throw errors when
049      * it should not, throws errors when it should, and results in the correct augmented code.
050      * Files that should be successfully tested are placed in the testFiles/forElementaryLevelTest folder 
051      * as .dj0 files, and the expected augmented files asre also placed in the testFiles/forElementaryLevelTest
052      * folder with the same name, but a .expected extension.  Files that are expected to generate errors are
053      * placed in the testFiles/forElementaryLevelTest/shouldBreak folder, as .dj0 files.
054      * Other subdirectories are used for other tests.
055      */
056    public class ElementaryLevelTest extends TestCase {
057      File directory;
058      
059      public void setUp() {
060        directory = new File("testFiles" + File.separatorChar + "forElementaryLevelTest");
061      }
062      
063    //  public void assertEquals(String s, Data answer, Data testValue) {
064    //    if (! answer.equals(testValue)) 
065    //      System.err.println("Unit test '" + s + "' failed. Expected '" + 
066    //                         answer.getName() + "'.  Found '" + testValue.getName() + "'.");
067    //  }
068      
069      /** Tests some files that should be handled without errors, and ensures the resulting augmented
070        * file is correct.*/
071      public void testSuccessful() {
072        File[] testFiles = directory.listFiles(new FileFilter() {
073          public boolean accept(File pathName) { return pathName.getAbsolutePath().endsWith(".dj0"); }
074        });
075    //    System.err.println("testFiles for testSuccessful = " + Arrays.toString(testFiles));
076        LanguageLevelConverter llc = new LanguageLevelConverter();
077        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
078        result = llc.convert(testFiles, new Options(JavaVersion.JAVA_5,
079                                                    IterUtil.make(new File("lib/buildlib/junit.jar"))));
080    //    System.err.println("Visitor exception #1 = " + result.getSecond().getFirst());
081    //    fail("Dumping System.err");
082        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
083        assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
084        
085        /** Now make sure that the resulting java files are correct.*/
086        for (int i = 0; i < testFiles.length; i++) {
087          File currFile = testFiles[i];
088          String fileName = currFile.getAbsolutePath();
089          fileName = fileName.substring(0, fileName.length() -4);
090          File resultingFile = new File(fileName + ".java");
091          File correctFile = new File(fileName + ".expected");
092          
093    //      System.err.println("Testing file: " + fileName);
094          
095          if (correctFile.exists()) {
096            try {
097              assertEquals("File " + currFile.getName() + " should have been parsed and augmented correctly.",
098                           lf(IOUtil.toString(correctFile)),
099                           lf(IOUtil.toString(resultingFile)));
100            }
101            catch (IOException ioe) {
102              fail(ioe.getMessage());
103              // let JUnit throw the exception
104            }
105          }
106        }
107      }
108      
109      /*Test some files that should break*/
110      public void testShouldBeErrors() {
111        directory = new File(directory, "shouldBreak");
112        File[] testFiles = directory.listFiles(new FileFilter() {
113          public boolean accept(File pathName) {
114            return pathName.getAbsolutePath().endsWith(".dj0");
115          }});
116        
117    //    System.err.println("testFiles for testShouldBeErrors = " + Arrays.toString(testFiles));
118        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
119        for (int i = 0; i < testFiles.length; i++) {
120          LanguageLevelConverter llc = new LanguageLevelConverter();
121          result = llc.convert(new File[]{ testFiles[i] }, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
122    //      System.err.println("Test result = " + result);
123          assertTrue("should be parse exceptions or visitor exceptions in file " + testFiles[i].getName(),
124                     ! result.getFirst().isEmpty() || ! result.getSecond().isEmpty());
125        }
126      }
127      
128      // TODO: !!! Reinstate this test
129      /** Tests that when some files have already been compiled, the .java files are not generated for those files,
130        * and files that reference those files are augmented correctly.
131        */
132      public void xtestSomeFilesCompiled() {
133        directory = new File(directory, "someCompiled");
134        File[] testFiles = directory.listFiles(new FileFilter() {
135          public boolean accept(File pathName) {
136            return pathName.getName().equals("UseOtherClassAsField.dj0") || pathName.getName().equals("SubClass.dj0");
137          }});
138        
139        LanguageLevelConverter llc = new LanguageLevelConverter();
140        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
141        result = llc.convert(testFiles, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
142        
143        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
144        assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
145        
146        /**Now make sure that the resulting java files are correct.*/
147        for (int i = 0; i < testFiles.length; i++) {
148          File currFile = testFiles[i];
149          String fileName = currFile.getAbsolutePath();
150          fileName = fileName.substring(0, fileName.length() -4);
151          File resultingFile = new File(fileName + ".java");
152          File correctFile = new File(fileName + ".expected");
153          
154          try {
155            assertEquals("File " + currFile.getName() + " should have been handled correctly",
156                         lf(IOUtil.toString(correctFile)),
157                         lf(IOUtil.toString(resultingFile)));
158          }
159          catch (IOException ioe) {
160            fail(ioe.getMessage());
161            // let JUnit throw the exception
162          }
163        }
164        
165        /**And make sure that .java files did not get generated for the classes referenced from our test class.*/
166        File superClass = new File(directory.getAbsolutePath() + "SuperClass.java");
167        File classAsField = new File(directory.getAbsolutePath() + "ClassAsField.java");
168        assertFalse("superClass.java should not exist", superClass.exists());
169        assertFalse("ClassAsField.java should not exist", classAsField.exists());
170      }
171      
172      /* Make sure that successful compilation is not dependent on visiting the file with no dependencies first.*/
173      public void testOrderMatters() {
174        directory = new File(directory, "orderMatters");
175        File[] files = new File[] { 
176          new File(directory, "Empty.dj0"), 
177          new File(directory, "List.dj0"), 
178          new File(directory, "NonEmpty.dj0") 
179        };
180        LanguageLevelConverter llc = new LanguageLevelConverter();
181        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
182    //    System.err.println("files for testOrderMatters = " + Arrays.toString(files));
183        result = llc.convert(files, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
184        
185        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
186        assertEquals("should be 1 visitor exception", 1, result.getSecond().size());
187        assertEquals("the error message should be correct", "Could not resolve symbol f", 
188                     result.getSecond().getFirst().getFirst());
189        
190    //    System.err.println("testOrderMatters finished");
191      }
192      
193      /** An empty file should not get converted to a .java file. */
194      public void testEmptyFileNoAction() {
195        directory = new File(directory, "emptyFile");
196        File[] files = new File[]{ new File(directory, "EmptyFile.dj0")};
197        LanguageLevelConverter llc = new LanguageLevelConverter();
198        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
199        result = llc.convert(files, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
200        
201        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
202        assertEquals("should be no visitor exceptions", 0, result.getSecond().size());
203        assertFalse("Should be no .java file", (new File(directory, "EmptyFile.java")).exists());
204      }
205      
206      /** Makes sure that autoboxing is done appropriately*/
207      public void testRequiresAutoboxing() {
208        directory = new File(directory, "requiresAutoboxing");
209        File[] testFiles = directory.listFiles(new FileFilter() {
210          public boolean accept(File pathName) {
211            return pathName.getAbsolutePath().endsWith(".dj0");
212          }});
213        
214        LanguageLevelConverter llc = new LanguageLevelConverter();
215        Pair<LinkedList<JExprParseException>, LinkedList<Pair<String, JExpressionIF>>> result;
216        result = llc.convert(testFiles, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
217        
218        assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
219        assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
220        
221    //    for (int i = 0; i <testFiles.length; i++) {
222    //      LanguageLevelConverter llc5 = new LanguageLevelConverter();
223    //      result = llc5.convert(new File[]{testFiles[i]}, new Options(JavaVersion.JAVA_5, EmptyIterable.<File>make()));
224    //      
225    //      assertEquals("should be no parse exceptions", new LinkedList<JExprParseException>(), result.getFirst());
226    //      assertEquals("should be no visitor exceptions", new LinkedList<Pair<String, JExpressionIF>>(), result.getSecond());
227    //    }
228    
229        
230        /* Now make sure that the resulting java files are correct.*/
231        for (int i = 0; i < testFiles.length; i++) {
232          File currFile = testFiles[i];
233          String fileName = currFile.getAbsolutePath();
234          fileName = fileName.substring(0, fileName.length() -4);
235          File resultingFile = new File(fileName + ".java");
236          File correctFile = new File(fileName + ".expected");
237          
238          try {
239            assertEquals("File " + currFile.getName() + " should have been parsed and augmented correctly.",
240                         lf(IOUtil.toString(correctFile)),
241                         lf(IOUtil.toString(resultingFile)));
242          }
243          catch (IOException ioe) {
244            fail(ioe.getMessage());
245            // let JUnit throw the exception
246          }
247        }
248      }
249    
250      /** Convert whatever line feeds (\n, \r, \r\n) are in the string to just \n, ignoring trailing whitespace. */
251      public static String lf(String s) {
252          return s.trim().replaceAll(edu.rice.cs.plt.text.TextUtil.NEWLINE_PATTERN,"\n");
253      }
254    }