/******************************************************************************* * Copyright (c) 2012, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package dtool.tests; import static dtool.tests.DToolTestResources.getTestResourceFile; import static dtool.tests.DToolTestResources.resourceFileToString; import static melnorme.utilbox.core.Assert.AssertNamespace.assertFail; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import static melnorme.utilbox.misc.CollectionUtil.filter; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import java.util.function.Predicate; import melnorme.utilbox.misc.SimpleLogger; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import dtool.sourcegen.AnnotatedSource; import dtool.sourcegen.AnnotatedSource.MetadataEntry; import dtool.sourcegen.TemplatedSourceProcessor; import dtool.sourcegen.TemplatedSourceProcessorCommonTest.TestsTemplatedSourceProcessor; import dtool.sourcegen.TemplatedSourceProcessorParser.TspExpansionElement; import dtool.util.NewUtils; @RunWith(Parameterized.class) public abstract class CommonTemplatedSourceBasedTest extends DeeFileBasedTest { public static SimpleLogger templatedTestsSourceLog = SimpleLogger.create("TemplatedSourceBasedTest"); public static SimpleLogger expandedTestCaseLog = SimpleLogger.create("TemplatedSourceBasedTest"); public static ArrayList<File> getDeeModuleList(String testFolder) { return getDeeModuleList(getTestResourceFile(testFolder), true); } public static void addCommonDefinitions(Class<?> klass, String testFolder, Map<String, TspExpansionElement> commonDefs) { ArrayList<File> commonDefsFileList = getDeeModuleList(testFolder); commonDefsFileList = filter(commonDefsFileList, new TemplatedTestFilesFilter(){{filterHeaders = false;}}); String klassSimpleName = klass.getSimpleName(); testsLogger.println(">>>>>>============ " + klassSimpleName + " COMMON DEFINITIONS FILES: ============" ); for (File headerFile : commonDefsFileList) { testsLogger.println(headerFile); TemplatedSourceProcessor tsp = new DeeTestsTemplateSourceProcessor() { @Override protected void addFullyProcessedSourceCase(ProcessingState caseState) { assertTrue(caseState.isHeaderCase); } }; tsp.processSource_unchecked("#", readStringFromFile_PreserveBOM(headerFile)); assertTrue(tsp.getGenCases().size() == 0); NewUtils.addNew(commonDefs, tsp.getGlobalExpansions()); } testsLogger.println("--------------" ); } /* ----------------------------------------------- */ public static Collection<Object[]> createTestFileParameters(String testFolder) { return createTestFileParameters(testFolder, new TemplatedTestFilesFilter()); } public static Collection<Object[]> createTestFileParameters(String testFolder, TemplatedTestFilesFilter filter) { List<File> fileList = getDeeModuleList(testFolder); fileList = filter != null ? filter(fileList, filter) : fileList; return createTestListFromFiles(true, fileList); } public static class TemplatedTestFilesFilter implements Predicate<File> { boolean filterHeaders = true; @Override public boolean test(File file) { if(file.getName().endsWith("_TODO")) return true; if(file.getName().endsWith(".txt")) return true; if(file.getParentFile().getName().equals("0_common")) return filterHeaders; if(file.getName().contains(".export") || file.getName().contains(".EXPORT")) return filterHeaders; if(file.getName().endsWith(".tsp")) return !filterHeaders; if(file.getName().endsWith(".d")) { try { assertTrue(!TemplatedSourceProcessor.isTSPSourceStart(new FileReader(file))); } catch(IOException e) { assertFail(); } // Allow if file had no TSP data. return true; } throw assertFail(); } } public CommonTemplatedSourceBasedTest(String testUIDescription, File file) { super(testUIDescription, file); } public AnnotatedSource[] getTestCasesFromFile(Map<String, TspExpansionElement> commonDefinitions) { DeeTestsTemplateSourceProcessor tsp = new DeeTestsTemplateSourceProcessor(); if(commonDefinitions != null) { tsp.addGlobalExpansions(commonDefinitions); } testsLogger.print(">>>====== " + getClass().getSimpleName() + " on: " + resourceFileToString(file)); AnnotatedSource[] sourceBasedTests = tsp.processSource_unchecked("#", readStringFromFile_PreserveBOM(file)); testsLogger.println(" ("+sourceBasedTests.length+") ======<<<"); return sourceBasedTests; } public static AnnotatedSource[] getSourceBasedTestCases(String fileSource) { return new DeeTestsTemplateSourceProcessor().processSource_unchecked("#", fileSource); } protected static class DeeTestsTemplateSourceProcessor extends TestsTemplatedSourceProcessor { @Override protected void putExpansion(ProcessingState sourceCase, String expansionId, TspExpansionElement expansion) { addExpansion(sourceCase, expansionId, expansion); if(DToolTests.TESTS_LITE_MODE) { String name = expansionId; if(name != null && name.endsWith("__LITE")) { name = name.replace("__LITE", ""); TspExpansionElement value = expansion; TspExpansionElement newElem = new TspExpansionElement(name, value.pairedExpansionId, value.arguments, value.anonymousExpansion, value.dontOuputSource); assertTrue(sourceCase.getExpansion(name) != null); addExpansion(sourceCase, name, newElem); } } } public void addExpansion(ProcessingState sourceCase, String expansionId, TspExpansionElement expansion) { sourceCase.putExpansion(expansionId, expansion); } } public void runAnnotatedTests(AnnotatedSource[] sourceBasedTests) { HashSet<String> printedTemplatedSources = new HashSet<String>(); boolean printTestCaseSource = true; int splitTemplateChildCount = -1; for (AnnotatedSource testCase : sourceBasedTests) { if(testCase.findMetadata("comment", "NO_STDOUT") != null) { printTestCaseSource = false; } boolean printCaseSeparator = testCase.findMetadata("comment", "PRINT_SEP") != null; if(!printedTemplatedSources.contains(testCase.originalTemplatedSource)) { printCaseEnd(splitTemplateChildCount); splitTemplateChildCount = 0; String testClassName = getClass().getSimpleName(); String fileName = file.getName(); templatedTestsSourceLog.println( ">> ----------- "+testClassName+" TEMPLATE ("+fileName+") : ----------- <<"); templatedTestsSourceLog.print(testCase.originalTemplatedSource); if(!testCase.originalTemplatedSource.endsWith("\n")) templatedTestsSourceLog.println(); templatedTestsSourceLog.println(" ----------- ^^^^ ----------- "); } printedTemplatedSources.add(testCase.originalTemplatedSource); checkOffsetInvariant(testCase); enterAnnotatedSourceCase(testCase, printTestCaseSource, printCaseSeparator); splitTemplateChildCount++; } printCaseEnd(splitTemplateChildCount); templatedTestsSourceLog.println(); } protected void printCaseEnd(int originalTemplateChildCount) { if(originalTemplateChildCount > 10 && originalTemplateChildCount != -1) { templatedTestsSourceLog.println("<< ^^^ Previous case count: " + originalTemplateChildCount); } } protected void enterAnnotatedSourceCase(AnnotatedSource testCase, boolean printTestCaseSource, boolean printCaseSeparator) { if(printTestCaseSource) { printTestCaseSource(testCase, printCaseSeparator); } runAnnotatedSourceTest(testCase); } public static void checkOffsetInvariant(AnnotatedSource testSource) { int mdOffset = 0; for (MetadataEntry mde : testSource.metadata) { if(mde.isTopLevelMetadata()) { assertTrue(mde.offset >= mdOffset); } mdOffset = mde.offset; } } protected static final Pattern STARTING_NEWLINES_TRIMMER = Pattern.compile("(^(\\n|\\r\\n)*)|((\\n|\\r\\n)*$)"); public void printTestCaseSource(AnnotatedSource testCase, boolean printCaseSeparator) { if(printCaseSeparator) { expandedTestCaseLog.println(">-----------"); } // String caseSource = AnnotatedSource.printSourceWithMetadata(testCase); String caseSource = testCase.source; expandedTestCaseLog.println(STARTING_NEWLINES_TRIMMER.matcher(caseSource).replaceAll("")); } protected abstract void runAnnotatedSourceTest(AnnotatedSource testCase); }