001: /**************************************************************************/
002: /* NICE Testsuite */
003: /* A testsuite for the Nice programming language */
004: /* (c) Alex Greif 2002 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package nice.tools.testsuite;
012:
013: import java.io.*;
014: import java.util.*;
015:
016: /**
017: * A testsuite file with its testcases.
018: *
019: * @author Alex Greif <a href="mailto:alex.greif@web.de">alex.greif@web.de</a>
020: * @version $Id: TestSuite.java,v 1.18 2007/11/25 20:03:14 bonniot Exp $
021: */
022: public class TestSuite {
023:
024: /**
025: * TODO
026: *
027: */
028: private static final String TESTCASE_TYPE_PASS = "pass";
029:
030: /**
031: * TODO
032: *
033: */
034: private static final String TESTCASE_TYPE_FAIL = "fail";
035:
036: /**
037: * TODO
038: *
039: */
040: private static final String KEYWORD_GLOBAL = "global";
041:
042: /**
043: * TODO
044: *
045: */
046: private static final String KEYWORD_COMMENT = "comment";
047:
048: /**
049: * The testsuite file on the disc
050: *
051: */
052: private File _file;
053: /**
054: * TODO
055: *
056: */
057: private List _testCases = new ArrayList();
058:
059: /**
060: * Nice source file that contains the gathered global sources.
061: * These sources are available for all testcases.
062: *
063: */
064: private GlobalSourceFile _globalSource = new GlobalSourceFile();
065:
066: /**
067: * Constructor. Reads the testcases and performs the tests in the testsuite.
068: *
069: * @param testSuiteFile TODO
070: * @exception TestSuiteException TODO
071: */
072: public TestSuite(File testSuiteFile) throws TestSuiteException {
073: _file = testSuiteFile;
074:
075: TestNice.getOutput().startTestSuite(this );
076: readTestCases();
077: performTests();
078: TestNice.getOutput().endTestSuite();
079: }
080:
081: /**
082: * Reads the testsuite file line by line and creates the appropriate testcases.
083: * Also handles globals and comments
084: *
085: * @exception TestSuiteException TODO
086: */
087: private void readTestCases() throws TestSuiteException {
088: BufferedReader reader = null;
089: try {
090: reader = new BufferedReader(new FileReader(_file));
091: String line;
092: TestCase testCase = null;
093: boolean isGlobalSource = false;
094: boolean testsuiteKeywordLine;
095: while ((line = reader.readLine()) != null) {
096: if (line.trim().length() == 0) // ignore empty lines
097: continue;
098:
099: testsuiteKeywordLine = line
100: .startsWith(TestNice.KEYWORD_SIGN);
101: if (testsuiteKeywordLine)
102: isGlobalSource = line.toLowerCase().indexOf(
103: KEYWORD_GLOBAL) != -1;
104:
105: if (isGlobalSource) {
106: getGlobalSource().consumeLine(line);
107: continue;
108: }
109:
110: if (testsuiteKeywordLine && consumeComment(line))
111: continue;
112:
113: if (testsuiteKeywordLine) {
114: testCase = createTestCase(line);
115: _testCases.add(testCase);
116: continue;
117: }
118:
119: testCase.consumeLine(line);
120: }
121: } catch (IOException e) {
122: throw new TestSuiteException(
123: "Exception while reading file: " + _file, e);
124: } finally {
125: if (reader != null)
126: try {
127: reader.close();
128: } catch (IOException e) {
129: throw new TestSuiteException(
130: "could not close file: " + _file);
131: }
132: }
133: }
134:
135: /**
136: * Decides whether the line is a comment or not, and if it is one
137: * then the comment is printed if desired.
138: *
139: */
140: boolean consumeComment(String line) {
141: int commentPos = line.toLowerCase().indexOf(KEYWORD_COMMENT);
142: if (commentPos == -1)
143: return false;
144: if (TestNice.getWriteComments()) {
145: String comment = line.substring(
146: commentPos + KEYWORD_COMMENT.length()).trim();
147: TestNice.getOutput().logAndFlush(KEYWORD_COMMENT, comment);
148: }
149:
150: return true;
151: }
152:
153: /**
154: * Creates and returns a specific TestCase object depending upon
155: * the keyword.
156: *
157: * @param line TODO
158: * @exception TestSuiteException TODO
159: */
160: private TestCase createTestCase(String line)
161: throws TestSuiteException {
162: String type = line.substring(TestNice.KEYWORD_SIGN.length())
163: .trim();
164:
165: boolean skip = false;
166: if (type.endsWith(" skip")) {
167: skip = true;
168: type = type.substring(0, type.length() - "skip".length())
169: .trim();
170: }
171:
172: boolean isKnownBug = false;
173: if (type.endsWith(" bug")) {
174: isKnownBug = true;
175: type = type.substring(0, type.length() - "bug".length())
176: .trim();
177: }
178:
179: boolean noLocation = false;
180: if (type.endsWith(" no-location")) {
181: noLocation = true;
182: type = type.substring(0,
183: type.length() - "no-location".length()).trim();
184: }
185:
186: TestCase res;
187: if (TESTCASE_TYPE_PASS.equalsIgnoreCase(type))
188: res = new PassTestCase(this );
189: else if (TESTCASE_TYPE_FAIL.equalsIgnoreCase(type))
190: res = new FailTestCase(this );
191: else
192: throw new TestSuiteException("Unknown testcase type: "
193: + type);
194:
195: res.skip = skip;
196: res.isKnownBug = isKnownBug;
197: res.noLocation = noLocation;
198: return res;
199: }
200:
201: /**
202: * Performs tests on all testcases in this testsuite.
203: * Writes the files of the testcase, and calls the specific
204: * TestCase class to perform the test.
205: *
206: * @exception TestSuiteException TODO
207: */
208: private void performTests() throws TestSuiteException {
209: for (Iterator iter = _testCases.iterator(); iter.hasNext();) {
210: TestNice.cleanupTempFolder();
211: TestCase testCase = (TestCase) iter.next();
212:
213: if (testCase.skip) {
214: TestNice.getOutput().startTestCase(testCase);
215: testCase.fail();
216: continue;
217: }
218:
219: testCase.writeFiles();
220: testCase.performTest();
221: }
222: }
223:
224: /**
225: * Returns the testsuite file.
226: *
227: */
228: public File getFile() {
229: return _file;
230: }
231:
232: /**
233: * Returns the global source file.
234: *
235: */
236: GlobalSourceFile getGlobalSource() {
237: return _globalSource;
238: }
239:
240: /**
241: * Returns whether we have a global source file.
242: *
243: */
244: boolean hasGlobalSource() {
245: return !_globalSource.isEmpty();
246: }
247:
248: }
249:
250: // Local Variables:
251: // tab-width: 2
252: // End:
|