001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.ruby;
043:
044: import java.io.BufferedReader;
045: import java.io.BufferedWriter;
046: import java.io.File;
047: import java.io.FileReader;
048: import java.io.FileWriter;
049: import java.io.IOException;
050: import java.io.InputStream;
051: import java.io.InputStreamReader;
052: import java.io.OutputStream;
053: import java.io.OutputStreamWriter;
054: import java.io.Writer;
055: import java.nio.CharBuffer;
056: import java.util.ArrayList;
057: import java.util.Collection;
058: import java.util.Collections;
059: import java.util.List;
060: import java.util.prefs.Preferences;
061: import javax.swing.Action;
062: import javax.swing.text.Document;
063: import org.jruby.ast.Node;
064: import org.netbeans.modules.gsf.api.ParseListener;
065: import org.netbeans.modules.gsf.api.ParserFile;
066: import org.netbeans.modules.gsf.api.ParserResult;
067: import org.netbeans.modules.gsf.api.TranslatedSource;
068: import org.netbeans.api.ruby.platform.RubyInstallation;
069: import org.netbeans.api.ruby.platform.TestUtil;
070: import org.netbeans.editor.BaseDocument;
071: import org.netbeans.junit.NbTestCase;
072: import org.netbeans.modules.gsf.DefaultLanguage;
073: import org.netbeans.modules.gsf.LanguageRegistry;
074: import org.netbeans.modules.ruby.lexer.RubyTokenId;
075: import org.netbeans.modules.ruby.options.CodeStyle;
076: import org.netbeans.modules.ruby.options.FmtOptions;
077: import org.netbeans.modules.gsf.spi.DefaultParseListener;
078: import org.netbeans.modules.gsf.spi.DefaultParserFile;
079: import org.openide.ErrorManager;
080: import org.openide.filesystems.FileObject;
081: import org.openide.filesystems.FileSystem;
082: import org.openide.filesystems.FileUtil;
083: import org.openide.loaders.DataObject;
084: import org.openide.loaders.DataObjectNotFoundException;
085: import org.openide.util.NbPreferences;
086:
087: /**
088: * @author Tor Norbye
089: */
090: public abstract class RubyTestBase extends
091: org.netbeans.api.ruby.platform.RubyTestBase {
092:
093: public RubyTestBase(String testName) {
094: super (testName);
095: }
096:
097: protected @Override
098: void setUp() throws Exception {
099: super .setUp();
100: System.setProperty("netbeans.user", getWorkDirPath());
101: }
102:
103: protected ParserResult parse(FileObject fileObject) {
104: RubyParser parser = new RubyParser();
105: int caretOffset = -1;
106:
107: ParserFile file = new DefaultParserFile(fileObject, null, false);
108: String sequence = "";
109: ParseListener listener = new DefaultParseListener();
110: // BaseDocument baseDoc = null;
111: try {
112: // DataObject dobj = DataObject.find(fileObject);
113: // EditorCookie cookie = dobj.getCookie(EditorCookie.class);
114: // Document doc = cookie.openDocument();
115: // sequence = doc.getText(0, doc.getLength());
116: sequence = readFile(fileObject);
117: // baseDoc = getDocument(sequence);
118: } catch (Exception ex) {
119: fail(ex.toString());
120: }
121: TranslatedSource translatedSource = null; // TODO
122: RubyParser.Context context = new RubyParser.Context(file,
123: listener, sequence, caretOffset, translatedSource);
124: ParserResult result = parser.parseBuffer(context,
125: RubyParser.Sanitize.NEVER);
126: return result;
127: }
128:
129: protected void initializeRegistry() {
130: LanguageRegistry registry = LanguageRegistry.getInstance();
131: List<Action> actions = Collections.emptyList();
132: if (!LanguageRegistry.getInstance().isSupported(
133: RubyInstallation.RUBY_MIME_TYPE)) {
134: List<String> extensions = Collections.singletonList("rb");
135: org.netbeans.modules.gsf.Language dl = new DefaultLanguage(
136: "Ruby", "org/netbeans/modules/ruby/jrubydoc.png",
137: "text/x-ruby", extensions, actions,
138: new RubyLanguage(), new RubyParser(),
139: new CodeCompleter(), new RenameHandler(),
140: new DeclarationFinder(), new Formatter(),
141: new BracketCompleter(), new RubyIndexer(),
142: new StructureAnalyzer(), null, false);
143: List<org.netbeans.modules.gsf.Language> languages = new ArrayList<org.netbeans.modules.gsf.Language>();
144: languages.add(dl);
145: registry.addLanguages(languages);
146: }
147: }
148:
149: protected Node getRootNode(String relFilePath) {
150: FileObject fileObject = getTestFile(relFilePath);
151: ParserResult result = parse(fileObject);
152: assertNotNull(result);
153: RubyParseResult rpr = (RubyParseResult) result;
154: Node root = rpr.getRootNode();
155:
156: return root;
157: }
158:
159: // Locate as many Ruby files from the JRuby distribution as possible: libs, gems, etc.
160: protected List<FileObject> findJRubyRubyFiles() {
161: List<FileObject> l = new ArrayList<FileObject>();
162: addRubyFiles(l, TestUtil.getXTestJRubyHomeFO());
163:
164: return l;
165: }
166:
167: private void addRubyFiles(List<FileObject> list, FileObject parent) {
168: for (FileObject child : parent.getChildren()) {
169: if (child.isFolder()) {
170: addRubyFiles(list, child);
171: } else if (child.getMIMEType().equals(
172: RubyMimeResolver.RUBY_MIME_TYPE)) {
173: list.add(child);
174: }
175: }
176: }
177:
178: protected String readFile(final FileObject fo) {
179: return read(fo);
180: }
181:
182: public static String read(final FileObject fo) {
183: try {
184: final StringBuilder sb = new StringBuilder(5000);
185: fo.getFileSystem().runAtomicAction(
186: new FileSystem.AtomicAction() {
187:
188: public void run() throws IOException {
189:
190: if (fo == null) {
191: return;
192: }
193:
194: InputStream is = fo.getInputStream();
195: BufferedReader reader = new BufferedReader(
196: new InputStreamReader(is));
197:
198: while (true) {
199: String line = reader.readLine();
200:
201: if (line == null) {
202: break;
203: }
204:
205: sb.append(line);
206: sb.append('\n');
207: }
208: }
209: });
210:
211: if (sb.length() > 0) {
212: return sb.toString();
213: } else {
214: return null;
215: }
216: } catch (IOException ioe) {
217: ErrorManager.getDefault().notify(ioe);
218:
219: return null;
220: }
221: }
222:
223: public static BaseDocument createDocument(String s) {
224: try {
225: BaseDocument doc = new BaseDocument(null, false);
226: doc.putProperty(org.netbeans.api.lexer.Language.class,
227: RubyTokenId.language());
228: doc
229: .putProperty("mimeType",
230: RubyInstallation.RUBY_MIME_TYPE);
231:
232: doc.insertString(0, s, null);
233:
234: return doc;
235: } catch (Exception ex) {
236: fail(ex.toString());
237: return null;
238: }
239: }
240:
241: public static BaseDocument getDocumentFor(FileObject fo) {
242: return createDocument(read(fo));
243: }
244:
245: protected BaseDocument getDocument(String s) {
246: return createDocument(s);
247: }
248:
249: protected BaseDocument getDocument(FileObject fo) {
250: try {
251: // DataObject dobj = DataObject.find(fo);
252: // assertNotNull(dobj);
253: //
254: // EditorCookie ec = (EditorCookie)dobj.getCookie(EditorCookie.class);
255: // assertNotNull(ec);
256: //
257: // return (BaseDocument)ec.openDocument();
258: BaseDocument doc = getDocument(readFile(fo));
259: try {
260: DataObject dobj = DataObject.find(fo);
261: doc.putProperty(Document.StreamDescriptionProperty,
262: dobj);
263: } catch (DataObjectNotFoundException dnfe) {
264: fail(dnfe.toString());
265: }
266:
267: return doc;
268: } catch (Exception ex) {
269: fail(ex.toString());
270: return null;
271: }
272: }
273:
274: protected TestCompilationInfo getInfo(String file) throws Exception {
275: FileObject fileObject = getTestFile(file);
276: return getInfo(fileObject);
277: }
278:
279: protected TestCompilationInfo getInfo(FileObject fileObject)
280: throws Exception {
281: String text = readFile(fileObject);
282: if (text == null) {
283: text = "";
284: }
285: BaseDocument doc = getDocument(text);
286:
287: TestCompilationInfo info = new TestCompilationInfo(this ,
288: fileObject, doc, text);
289:
290: return info;
291: }
292:
293: public static String readFile(File f) throws Exception {
294: FileReader r = new FileReader(f);
295: int fileLen = (int) f.length();
296: CharBuffer cb = CharBuffer.allocate(fileLen);
297: r.read(cb);
298: cb.rewind();
299: return cb.toString();
300: }
301:
302: protected File getDataSourceDir() {
303: // Check whether token dump file exists
304: // Try to remove "/build/" from the dump file name if it exists.
305: // Otherwise give a warning.
306: File inputFile = getDataDir();
307: String inputFilePath = inputFile.getAbsolutePath();
308: boolean replaced = false;
309: if (inputFilePath.indexOf(pathJoin("build", "test")) != -1) {
310: inputFilePath = inputFilePath.replace(pathJoin("build",
311: "test"), pathJoin("test"));
312: replaced = true;
313: }
314: if (!replaced
315: && inputFilePath
316: .indexOf(pathJoin("test", "work", "sys")) != -1) {
317: inputFilePath = inputFilePath.replace(pathJoin("test",
318: "work", "sys"), pathJoin("test", "unit"));
319: replaced = true;
320: }
321: if (!replaced) {
322: System.err
323: .println("Warning: Attempt to use dump file "
324: + "from sources instead of the generated test files failed.\n"
325: + "Patterns '/build/test/' or '/test/work/sys/' not found in "
326: + inputFilePath);
327: }
328: inputFile = new File(inputFilePath);
329: assertTrue(inputFile.exists());
330:
331: return inputFile;
332: }
333:
334: private static String pathJoin(String... chunks) {
335: StringBuilder result = new StringBuilder(File.separator);
336: for (String chunk : chunks) {
337: result.append(chunk).append(File.separatorChar);
338: }
339: return result.toString();
340: }
341:
342: protected File getDataFile(String relFilePath) {
343: File inputFile = new File(getDataSourceDir(), relFilePath);
344: return inputFile;
345: }
346:
347: protected void assertDescriptionMatches(String relFilePath,
348: String description, boolean includeTestName, String ext)
349: throws Exception {
350: File rubyFile = getDataFile(relFilePath);
351: if (!rubyFile.exists()) {
352: NbTestCase.fail("File " + rubyFile + " not found.");
353: }
354:
355: File goldenFile = getDataFile(relFilePath
356: + (includeTestName ? ("." + getName()) : "") + ext);
357: if (!goldenFile.exists()) {
358: if (!goldenFile.createNewFile()) {
359: NbTestCase.fail("Cannot create file " + goldenFile);
360: }
361: FileWriter fw = new FileWriter(goldenFile);
362: try {
363: fw.write(description);
364: } finally {
365: fw.close();
366: }
367: NbTestCase.fail("Created generated golden file "
368: + goldenFile + "\nPlease re-run the test.");
369: }
370:
371: String expected = readFile(goldenFile);
372:
373: // Because the unit test differ is so bad...
374: if (false) { // disabled
375: if (!expected.equals(description)) {
376: BufferedWriter fw = new BufferedWriter(new FileWriter(
377: "/tmp/expected.txt"));
378: fw.write(expected);
379: fw.close();
380: fw = new BufferedWriter(new FileWriter(
381: "/tmp/actual.txt"));
382: fw.write(description);
383: fw.close();
384: }
385: }
386:
387: assertEquals(expected.trim(), description.trim());
388: }
389:
390: protected void assertDescriptionMatches(FileObject fileObject,
391: String description, boolean includeTestName, String ext)
392: throws Exception {
393: File goldenFile = getDataFile("testfiles/"
394: + fileObject.getName()
395: + (includeTestName ? ("." + getName()) : "") + ext);
396: if (!goldenFile.exists()) {
397: if (!goldenFile.createNewFile()) {
398: NbTestCase.fail("Cannot create file " + goldenFile);
399: }
400: FileWriter fw = new FileWriter(goldenFile);
401: try {
402: fw.write(description);
403: } finally {
404: fw.close();
405: }
406: NbTestCase.fail("Created generated golden file "
407: + goldenFile + "\nPlease re-run the test.");
408: }
409:
410: String expected = readFile(goldenFile);
411:
412: // Because the unit test differ is so bad...
413: if (false) { // disabled
414: if (!expected.equals(description)) {
415: BufferedWriter fw = new BufferedWriter(new FileWriter(
416: "/tmp/expected.txt"));
417: fw.write(expected);
418: fw.close();
419: fw = new BufferedWriter(new FileWriter(
420: "/tmp/actual.txt"));
421: fw.write(description);
422: fw.close();
423: }
424: }
425:
426: assertEquals("Not matching goldenfile: "
427: + FileUtil.getFileDisplayName(fileObject), expected
428: .trim(), description.trim());
429: }
430:
431: protected void assertFileContentsMatches(String relFilePath,
432: String description, boolean includeTestName, String ext)
433: throws Exception {
434: File rubyFile = getDataFile(relFilePath);
435: if (!rubyFile.exists()) {
436: NbTestCase.fail("File " + rubyFile + " not found.");
437: }
438:
439: File goldenFile = getDataFile(relFilePath
440: + (includeTestName ? ("." + getName()) : "") + ext);
441: if (!goldenFile.exists()) {
442: if (!goldenFile.createNewFile()) {
443: NbTestCase.fail("Cannot create file " + goldenFile);
444: }
445: FileWriter fw = new FileWriter(goldenFile);
446: try {
447: fw.write(description);
448: } finally {
449: fw.close();
450: }
451: NbTestCase.fail("Created generated golden file "
452: + goldenFile + "\nPlease re-run the test.");
453: }
454:
455: String expected = readFile(goldenFile);
456: assertEquals(expected.trim(), description.trim());
457: }
458:
459: public void assertEquals(Collection<String> s1,
460: Collection<String> s2) {
461: List<String> l1 = new ArrayList<String>();
462: l1.addAll(s1);
463: Collections.sort(l1);
464: List<String> l2 = new ArrayList<String>();
465: l2.addAll(s2);
466: Collections.sort(l2);
467:
468: assertEquals(l1.toString(), l2.toString());
469: }
470:
471: protected Formatter getFormatter(IndentPrefs preferences) {
472: if (preferences == null) {
473: preferences = new IndentPrefs(2, 2);
474: }
475:
476: Preferences prefs = NbPreferences
477: .forModule(FormatterTest.class);
478: prefs.put(FmtOptions.indentSize, Integer.toString(preferences
479: .getIndentation()));
480: prefs.put(FmtOptions.continuationIndentSize, Integer
481: .toString(preferences.getHangingIndentation()));
482: CodeStyle codeStyle = CodeStyle.getTestStyle(prefs);
483:
484: Formatter formatter = new Formatter(codeStyle, 80);
485:
486: return formatter;
487: }
488:
489: protected void createFilesFromDesc(FileObject folder,
490: String descFile) throws Exception {
491: File taskFile = new File(getDataDir(), descFile);
492: assertTrue(taskFile.exists());
493: BufferedReader br = new BufferedReader(new FileReader(taskFile));
494: while (true) {
495: String line = br.readLine();
496: if (line == null || line.trim().length() == 0) {
497: break;
498: }
499:
500: if (line.endsWith("\r")) {
501: line = line.substring(0, line.length() - 1);
502: }
503:
504: String path = line;
505: if (path.endsWith("/")) {
506: path = path.substring(0, path.length() - 1);
507: FileObject f = FileUtil.createFolder(folder, path);
508: assertNotNull(f);
509: } else {
510: FileObject f = FileUtil.createData(folder, path);
511: assertNotNull(f);
512: }
513: }
514: }
515:
516: public static void createFiles(File baseDir, String... paths)
517: throws IOException {
518: assertNotNull(baseDir);
519: for (String path : paths) {
520: FileObject baseDirFO = FileUtil.toFileObject(baseDir);
521: assertNotNull(baseDirFO);
522: assertNotNull(FileUtil.createData(baseDirFO, path));
523: }
524: }
525:
526: public static void createFile(FileObject dir, String relative,
527: String contents) throws IOException {
528: FileObject datafile = FileUtil.createData(dir, relative);
529: OutputStream os = datafile.getOutputStream();
530: Writer writer = new BufferedWriter(new OutputStreamWriter(os));
531: writer.write(contents);
532: writer.close();
533: }
534: }
|