/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.engine.integration;
import com.google.dart.engine.context.AnalysisContext;
import com.google.dart.engine.context.AnalysisException;
import com.google.dart.engine.element.CompilationUnitElement;
import com.google.dart.engine.element.LibraryElement;
import com.google.dart.engine.error.AnalysisError;
import com.google.dart.engine.error.ErrorCode;
import com.google.dart.engine.internal.context.PerformanceStatistics;
import com.google.dart.engine.source.Source;
import com.google.dart.engine.utilities.io.PrintStringWriter;
import junit.framework.Assert;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
public abstract class DirectoryBasedSuiteBuilder {
public class AnalysisTest extends TestCase {
private File sourceFile;
public AnalysisTest(File sourceFile) {
super(sourceFile.getName());
this.sourceFile = sourceFile;
}
public File getSourceFile() {
return sourceFile;
}
public void testFile() throws Exception {
testSingleFile(sourceFile);
}
protected String getTestName() {
return sourceFile.getName();
}
@Override
protected void runTest() throws Throwable {
try {
setName("testFile");
super.runTest();
} finally {
setName(getTestName());
}
}
}
/**
* The number of tests that failed because there were errors generated when there were not
* expected to be any errors.
*/
protected int errorCount = 0;
/**
* The number of tests that failed because there were no errors generated when errors were
* expected.
*/
protected int noErrorCount = 0;
public TestSuite buildSuite(File directory, String suiteName) {
TestSuite suite = new TestSuite(suiteName);
if (directory.exists()) {
addTestsForFilesIn(suite, directory);
}
return suite;
}
/**
* Add the errors reported for the given compilation unit to the given list of errors.
*
* @param errorList the list to which the errors are to be added
* @param element the compilation unit whose errors are to be added
* @throws AnalysisException if the errors could not be determined
*/
protected void addErrors(ArrayList<AnalysisError> errorList, CompilationUnitElement element)
throws AnalysisException {
Source source = element.getSource();
LibraryElement library = element.getLibrary();
AnalysisContext context = library.getContext();
context.resolveCompilationUnit(source, library);
AnalysisError[] errors = context.computeErrors(source);
if (errors == null) {
Assert.fail("The compilation unit \"" + element.getSource().getFullName()
+ "\" was not resolved");
}
for (AnalysisError error : errors) {
errorList.add(error);
}
}
protected void addTestForFile(TestSuite suite, File file) {
suite.addTest(new AnalysisTest(file));
}
/**
* Assert that the errors in the error list match the expected behavior of the test.
*
* @param errorExpected {@code true} if the test indicates that errors should be produced
* @param expectedToFail {@code true} if the outcome is expected to be inverted from normal
* @param errorList the list of errors that were produced for the files that were analyzed
*/
protected void assertErrors(boolean errorExpected, boolean expectedToFail,
ArrayList<AnalysisError> errorList) {
Collections.sort(errorList, AnalysisError.ERROR_CODE_COMPARATOR);
if (errorExpected) {
if (expectedToFail) {
if (errorList.size() > 0) {
Assert.fail("Expected to fail with no errors, but passed with errors");
}
} else {
if (errorList.size() <= 0) {
noErrorCount++;
Assert.fail("Expected errors, found none");
}
}
} else {
if (expectedToFail) {
if (errorList.size() <= 0) {
Assert.fail("Expected to fail with errors, but passed with no errors");
}
} else {
if (errorList.size() > 0) {
errorCount++;
@SuppressWarnings("resource")
PrintStringWriter writer = new PrintStringWriter();
writer.print("Expected 0 errors, found ");
writer.print(errorList.size());
writer.print(":");
for (AnalysisError error : errorList) {
ErrorCode code = error.getErrorCode();
int offset = error.getOffset();
writer.println();
writer.printf(
" %s (%d..%d) \"%s\"",
code.getClass().getSimpleName() + "." + code,
offset,
offset + error.getLength(),
error.getMessage());
}
Assert.fail(writer.toString());
}
}
}
}
protected void printStatistics() {
System.out.print(" scan: ");
printTime(PerformanceStatistics.scan.getResult());
System.out.println();
System.out.print(" parse: ");
printTime(PerformanceStatistics.parse.getResult());
System.out.println();
System.out.print(" resolve: ");
printTime(PerformanceStatistics.resolve.getResult());
System.out.println();
System.out.print(" errors: ");
printTime(PerformanceStatistics.errors.getResult());
System.out.println();
System.out.print(" hints: ");
printTime(PerformanceStatistics.hints.getResult());
System.out.println();
}
protected void printTime(long time) {
if (time == 0) {
System.out.print("0 ms");
} else {
System.out.print(time);
System.out.print(" ms");
if (time > 60000) {
long seconds = time / 1000;
long minutes = seconds / 60;
seconds -= minutes * 60;
System.out.print(" (");
System.out.print(minutes);
System.out.print(":");
if (seconds < 10) {
System.out.print("0");
}
System.out.print(seconds);
System.out.print(")");
}
}
}
protected abstract void testSingleFile(File sourceFile) throws Exception;
private void addTestsForFilesIn(TestSuite suite, File directory) {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
TestSuite childSuite = new TestSuite("Tests in " + file.getName());
addTestsForFilesIn(childSuite, file);
if (childSuite.countTestCases() > 0) {
suite.addTest(childSuite);
}
} else {
String fileName = file.getName();
if (fileName.endsWith(".dart") && !fileName.endsWith("_patch.dart")) {
addTestForFile(suite, file);
}
}
}
}
}