001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@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.drjava.model;
038:
039: import junit.framework.*;
040:
041: import java.io.*;
042:
043: import javax.swing.text.BadLocationException;
044: import javax.swing.text.Position;
045:
046: import edu.rice.cs.drjava.model.compiler.*;
047:
048: /** Tests to ensure that compilation fails when expected, and that the errors
049: * are reported correctly.
050: *
051: * Every test in this class is run for *each* of the compilers that is available.
052: *
053: * @version $Id: GlobalModelCompileErrorsTest.java 4255 2007-08-28 19:17:37Z mgricken $
054: */
055: public final class GlobalModelCompileErrorsTest extends
056: GlobalModelTestCase {
057:
058: private static final String FOO_MISSING_CLOSE_TEXT = "class DrJavaTestFoo {";
059: private static final String BAR_MISSING_SEMI_TEXT = "class DrJavaTestBar { int x }";
060: private static final String FOO_PACKAGE_AFTER_IMPORT = "import java.util.*;\npackage a;\n"
061: + FOO_TEXT;
062: private static final String FOO_PACKAGE_INSIDE_CLASS = "class DrJavaTestFoo { package a; }";
063: private static final String FOO_PACKAGE_AS_FIELD = "class DrJavaTestFoo { int package; }";
064: private static final String FOO_PACKAGE_AS_FIELD_2 = "class DrJavaTestFoo { int package = 5; }";
065: private static final String BAR_MISSING_SEMI_TEXT_MULTIPLE_LINES = "class DrJavaTestFoo {\n int a = 5;\n int x\n }";
066:
067: // /** Overrides setUp in order to save the Untitled file that resides in the model currently, so that saveBeforeCompile will not cause a failure*/
068: // public void setUp() throws IOException{
069: // super.setUp();
070: // _model.getOpenDefinitionsDocuments().get(0).saveFile(new FileSelector(new File(_tempDir, "blank document")));
071: // }
072:
073: // /** Overrides {@link TestCase#runBare} to interatively run this test case for each compiler, without resetting
074: // * the interactions JVM. This method is called once per test method, and it magically invokes the method.
075: // */
076: // public void runBare() throws Throwable {
077: // CompilerInterface[] compilers = CompilerRegistry.ONLY.getAvailableCompilers();
078: // for (int i = 0; i < compilers.length; i++) {
079: // //System.out.println("Run " + i + ": " + compilers[i]);
080: // setUp();
081: // _model.getCompilerModel().setActiveCompiler(compilers[i]);
082: // try { runTest(); }
083: // finally { tearDown(); }
084: // }
085: // }
086:
087: /** Gets the name of the compiler.
088: * @return the string representation of the active compiler
089: */
090: private String _name() {
091: return "compiler="
092: + _model.getCompilerModel().getActiveCompiler()
093: .getName() + ": ";
094: }
095:
096: /** Tests calling compileAll with different source roots works if the files have errors in them. (Each file
097: * has 1 error.)
098: * Note that this testcase will fail if several compilers can be found through the .drjava file.
099: * As the test is then run one time per compiler it can find.
100: */
101: public void testCompileAllFailsDifferentSourceRoots()
102: throws BadLocationException, IOException,
103: InterruptedException {
104:
105: File aDir = new File(_tempDir, "a");
106: File bDir = new File(_tempDir, "b");
107: aDir.mkdir();
108: bDir.mkdir();
109:
110: OpenDefinitionsDocument doc = setupDocument(FOO_MISSING_CLOSE_TEXT);
111: final File file = new File(aDir, "DrJavaTestFoo.java");
112: doc.saveFile(new FileSelector(file));
113:
114: OpenDefinitionsDocument doc2 = setupDocument(BAR_MISSING_SEMI_TEXT);
115: final File file2 = new File(bDir, "DrJavaTestBar.java");
116: doc2.saveFile(new FileSelector(file2));
117:
118: CompileShouldFailListener listener = new CompileShouldFailListener();
119:
120: _model.addListener(listener);
121:
122: CompilerModel cm = _model.getCompilerModel();
123: cm.compileAll();
124: listener.waitCompileDone();
125:
126: assertCompileErrorsPresent(_name(), true);
127: assertEquals("Should have 2 compiler errors", 2, _model
128: .getCompilerModel().getNumErrors());
129: listener.checkCompileOccurred();
130:
131: // Make sure .class does not exist for both files
132: File compiled = classForJava(file, "DrJavaTestFoo");
133: assertEquals(_name()
134: + "Class file exists after failing compile (1)", false,
135: compiled.exists());
136: File compiled2 = classForJava(file2, "DrJavaTestBar");
137: assertEquals(_name()
138: + "Class file exists after failing compile (2)", false,
139: compiled2.exists());
140: _model.removeListener(listener);
141: }
142:
143: /** Creates a source file with "package" as a field name and ensures that compile starts but fails due to
144: * the invalid field name.
145: */
146: public void testCompilePackageAsField()
147: throws BadLocationException, IOException,
148: InterruptedException {
149: OpenDefinitionsDocument doc = setupDocument(FOO_PACKAGE_AS_FIELD);
150: final File file = tempFile();
151: doc.saveFile(new FileSelector(file));
152:
153: CompileShouldFailListener listener = new CompileShouldFailListener();
154: _model.addListener(listener);
155:
156: doc.startCompile();
157: listener.waitCompileDone();
158: listener.checkCompileOccurred();
159:
160: // There better be an error since "package" can not be an identifier!
161: assertCompileErrorsPresent(_name(), true);
162:
163: File compiled = classForJava(file, "DrJavaTestFoo");
164: assertEquals(_name()
165: + "Class file exists after failing compile", false,
166: compiled.exists());
167: _model.removeListener(listener);
168: }
169:
170: /** Creates a source file with "package" as a field name and ensures that compile starts but fails due to the
171: * invalid field name. This is different from {@link #testCompilePackageAsField} as it initializes the field.
172: */
173: public void testCompilePackageAsField2()
174: throws BadLocationException, IOException,
175: InterruptedException {
176: OpenDefinitionsDocument doc = setupDocument(FOO_PACKAGE_AS_FIELD_2);
177: final File file = tempFile();
178: doc.saveFile(new FileSelector(file));
179:
180: CompileShouldFailListener listener = new CompileShouldFailListener();
181: _model.addListener(listener);
182:
183: doc.startCompile();
184: listener.waitCompileDone();
185: listener.checkCompileOccurred();
186:
187: // There better be an error since "package" can not be an identifier!
188: assertCompileErrorsPresent(_name(), true);
189:
190: File compiled = classForJava(file, "DrJavaTestFoo");
191: assertEquals(_name()
192: + "Class file exists after failing compile", false,
193: compiled.exists());
194: _model.removeListener(listener);
195: }
196:
197: /** Tests compiling an invalid file and checks to make sure the class file was not created. */
198: public void testCompileMissingCloseSquiggly()
199: throws BadLocationException, IOException,
200: InterruptedException {
201: OpenDefinitionsDocument doc = setupDocument(FOO_MISSING_CLOSE_TEXT);
202: final File file = tempFile();
203: doc.saveFile(new FileSelector(file));
204:
205: CompileShouldFailListener listener = new CompileShouldFailListener();
206: _model.addListener(listener);
207:
208: doc.startCompile();
209: listener.waitCompileDone();
210: assertCompileErrorsPresent(_name(), true);
211: listener.checkCompileOccurred();
212:
213: File compiled = classForJava(file, "DrJavaTestFoo");
214: assertTrue(_name() + "Class file exists after compile?!",
215: !compiled.exists());
216: _model.removeListener(listener);
217: }
218:
219: /** Puts an otherwise valid package statement inside a class declaration. This better not work! */
220: public void testCompileWithPackageStatementInsideClass()
221: throws BadLocationException, IOException,
222: InterruptedException {
223:
224: // Create temp file
225: File baseTempDir = tempDirectory();
226: File subdir = new File(baseTempDir, "a");
227: File fooFile = new File(subdir, "DrJavaTestFoo.java");
228: File compiled = classForJava(fooFile, "DrJavaTestFoo");
229:
230: // Now make subdirectory a
231: subdir.mkdir();
232:
233: // Save the footext to DrJavaTestFoo.java in the subdirectory
234: OpenDefinitionsDocument doc = setupDocument(FOO_PACKAGE_INSIDE_CLASS);
235: doc.saveFileAs(new FileSelector(fooFile));
236:
237: // do compile -- should fail since package decl is not valid!
238: CompileShouldFailListener listener = new CompileShouldFailListener();
239: _model.addListener(listener);
240:
241: doc.startCompile();
242: listener.waitCompileDone();
243:
244: listener.checkCompileOccurred();
245: assertCompileErrorsPresent(_name(), true);
246: assertTrue(_name() + "Class file exists after failed compile",
247: !compiled.exists());
248:
249: // check that model.resetCompilerErrors works
250: _model.getCompilerModel().resetCompilerErrors();
251: CompilerErrorModel cem = _model.getCompilerModel()
252: .getCompilerErrorModel();
253: assertEquals("CompilerErrorModel has errors after reset", 0,
254: cem.getNumErrors());
255: _model.removeListener(listener);
256: }
257:
258: /** Tests the compiler errors have the correct line numbers.
259: * TODO: rewrite this test for the new error model interface
260: */
261: public void testCompileFailsCorrectLineNumbers()
262: throws BadLocationException, IOException,
263: InterruptedException {
264: File aDir = new File(_tempDir, "a");
265: File bDir = new File(_tempDir, "b");
266: aDir.mkdir();
267: bDir.mkdir();
268: OpenDefinitionsDocument doc = setupDocument(FOO_PACKAGE_AFTER_IMPORT);
269: final File file = new File(aDir, "DrJavaTestFoo.java");
270: doc.saveFile(new FileSelector(file));
271: OpenDefinitionsDocument doc2 = setupDocument(BAR_MISSING_SEMI_TEXT_MULTIPLE_LINES);
272: final File file2 = new File(bDir, "DrJavaTestBar.java");
273: doc2.saveFile(new FileSelector(file2));
274:
275: // do compile -- should fail since package decl is not valid!
276: CompileShouldFailListener listener = new CompileShouldFailListener();
277: _model.addListener(listener);
278:
279: CompilerModel cm = _model.getCompilerModel();
280: cm.compileAll();
281: listener.waitCompileDone();
282:
283: assertCompileErrorsPresent(_name(), true);
284: assertEquals("Should have 2 compiler errors", 2, _model
285: .getCompilerModel().getNumErrors());
286: listener.checkCompileOccurred();
287: _model.removeListener(listener);
288:
289: CompilerErrorModel cme = cm.getCompilerErrorModel();
290: assertEquals("Should have had two errors", 2, cme
291: .getNumErrors());
292:
293: CompilerError ce1 = cme.getError(0);
294: CompilerError ce2 = cme.getError(1);
295: assertEquals("first doc should have an error", file
296: .getCanonicalFile(), ce1.file().getCanonicalFile());
297: assertEquals("second doc should have an error", file2
298: .getCanonicalFile(), ce2.file().getCanonicalFile());
299:
300: Position p1 = cme.getPosition(ce1);
301: Position p2 = cme.getPosition(ce2);
302: assertTrue(
303: "location of first error should be between 20 and 29 inclusive (line 2), but was "
304: + p1.getOffset(), p1.getOffset() <= 20
305: && p1.getOffset() <= 29);
306: assertTrue(
307: "location of error should be after 34 (line 3 or 4)",
308: p2.getOffset() >= 34);
309: }
310: }
|