/* * generated by Xtext 2.10.0 */ package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.BuildUtilities import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests.CMakeUtil.CMakeGenerateException import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CMakeListsGenerator import be.uantwerpen.ansymo.semanticadaptation.testframework.FmuMainTestGenerator import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider import com.google.inject.Inject import java.io.File import java.io.FileFilter import java.io.FileWriter import java.nio.file.Files import java.nio.file.Paths import java.util.regex.Pattern import org.apache.commons.io.FileUtils import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.xtext.generator.InMemoryFileSystemAccess import org.eclipse.xtext.testing.InjectWith import org.eclipse.xtext.testing.XtextRunner import org.eclipse.xtext.testing.util.ParseHelper import org.eclipse.xtext.testing.validation.ValidationTestHelper import org.junit.Assert import org.junit.BeforeClass import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith @RunWith(XtextRunner) @InjectWith(SemanticAdaptationInjectorProvider) class CgCppBasicTest extends AbstractSemanticAdaptationTest { // @Inject CppGenerator underTest @Inject extension ParseHelper @Inject extension ValidationTestHelper val static hcfRoot = Paths.get("target", "hcfDummy", "hcf").toFile() @BeforeClass def static setupHcf() { if (!CMakeUtil.windows) { FileUtils.write(new File(hcfRoot.parentFile, "CMakeLists.txt"), CMakeListsGenerator.generateCMakeListsHcfDummy()); val cmake = new CMakeUtil(true) try { Assert.assertTrue("Expected cmake to parse", cmake.generate(hcfRoot.parentFile)); Assert.assertTrue("Expected no make errors", cmake.make(hcfRoot.parentFile)); } catch (CMakeGenerateException e) { e.printStackTrace } } } @Test def window_sa_canonical_new() { __parseAndGenerateWithNoErrors('window_sa_canonical_new.BASE.sa', 'test_input/single_folder_spec/window/', 'powerwindow'); } @Test def empty_ctrl_rules() { __parseAndGenerateWithNoErrors('plantmr.sa', 'test_input/single_folder_spec/emptyctrlrules/', 'PlantMR'); } @Test def getSetState_sa() { __parseAndGenerateWithNoErrors('GetSetState.sa', 'test_input/single_folder_spec/getsetstate/', "getSetState"); } @Test def lazy_canonical() { __parseAndGenerateWithNoErrors('lazy_canonical.sa', 'test_input/single_folder_spec/lazy/', "lazy"); } @Ignore @Test def loop() { __parseAndGenerateWithNoErrors('loop_canonical.sa', 'test_input/single_folder_spec/loop/', "LoopSA"); } @Test def rate() { __parseAndGenerateWithNoErrors('rate.sa', 'test_input/single_folder_spec/rate/', "rate"); } @Test def rate_canonical() { __parseAndGenerateWithNoErrors('rate_canonical.sa', 'test_input/single_folder_spec/rate/', "rate_canonical"); } @Test def power() { __parseAndGenerateWithNoErrors('power.BASE.sa', 'test_input/single_folder_spec/power/', 'power'); } @Test def rollback_test() { __parseAndGenerateWithNoErrors('rollback_test.sa', 'test_input/single_folder_spec/rollback_test/', 'rollback_test'); } @Test def controller_test() { __parseAndGenerateWithNoErrors('controller.sa', 'test_input/single_folder_spec/controller/', 'controller'); } def __parseNoErrorsWithValidation(String directory, String filename) { val model = __parse(filename); __assertNoParseErrors(model, filename); val correctFileDirectory = new File(directory + File.separator + "correct"); val fsa = new InMemoryFileSystemAccess() val cppGen = new CppGenerator(); cppGen.doGenerate(model.eResource, fsa); for (files : fsa.allFiles.entrySet) { val filename2 = files.key.substring(14); val file = new File(correctFileDirectory, filename2); val correctFileContent = Files.readAllLines(file.toPath); var path = new File("generated"); if (path.exists) path.delete else path.mkdir; path = new File(path, files.key.substring(14)) val FileWriter writer = new FileWriter(path); writer.write(files.value.toString); writer.close; val testFileContent = Files.readAllLines(path.toPath); if (correctFileContent.size != testFileContent.size) { System.out.println("Error: Lines are of different length in file: " + filename2); } else { for (var i = 0; i < testFileContent.size; i++) { val testLine = testFileContent.get(i); val correctLine = correctFileContent.get(i); if (testLine.compareTo(correctLine) != 0) { if (!testLine.contains("guid")) { System.out.println("ERROR: The following lines are not equal: \n" + testLine + "\n" + correctLine); } } } } } } def __parseAndGenerateWithNoErrors(String filename, String directory, String projectName) { val dirTestOutput = directory.replace('test_input/','target/test-classes/') val saRootDir = Paths.get(dirTestOutput).toFile(); val saGenRootTempDir = Paths.get(dirTestOutput, projectName).toFile(); val absFileName = Paths.get(dirTestOutput, filename).toFile(); val srcGenPath = new File(saGenRootTempDir, "sources") val resourcesPath = new File(saGenRootTempDir, "resources"); println("saGenRootTempDir="+saGenRootTempDir.absolutePath) println("absFileName="+absFileName.absolutePath) val model = __parse(absFileName.absolutePath) __assertNoParseErrors(model, absFileName.absolutePath) val fsa = new InMemoryFileSystemAccess(); val cppGen = new CppGenerator(); cppGen.doGenerate(model.eResource, fsa, saRootDir.absolutePath); if (saGenRootTempDir.exists) { BuildUtilities.deleteFolder(saGenRootTempDir); } saGenRootTempDir.mkdirs(); srcGenPath.mkdirs(); resourcesPath.mkdirs(); for (files : fsa.allFiles.entrySet) { val fName = files.key.substring(14); var File fp; if (fName.equals("modelDescription.xml") || fName.equals("CMakeLists.txt") || fName.equals("msys-toolchain.cmake")) { fp = new File(saGenRootTempDir, fName); } else { fp = new File(srcGenPath, fName); } BuildUtilities.writeToFile(fp, files.value.toString); } val mainCpp = FmuMainTestGenerator.generateMainCppFile(resourcesPath.absolutePath.replace("\\", "\\\\")); BuildUtilities.writeToFile(new File(srcGenPath, "main.cpp"), mainCpp); for (rf : cppGen.resourcePaths) { val sinkFile = new File(resourcesPath, rf.name); System.out.println("Copied file to: " + sinkFile); BuildUtilities.copyFile(rf, sinkFile); } // BuildUtilities.writeToFile(new File(saRootDir, "CMakeLists.txt"), // CMakeListsGenerator.generateCMakeLists(projectName)); // // val cMakeToolChain = CMakeListsGenerator.generateToolChainCmake(); // BuildUtilities.writeToFile(new File(saRootDir, "msys-toolchain.cmake"), cMakeToolChain); if (!CMakeUtil.windows) { val cmake = new CMakeUtil(true) FileUtils.copyDirectory(hcfRoot, new File(saGenRootTempDir, "hcf"), new FileFilter() { override accept(File pathname) { return !pathname.name.equals("CMakeCache.txt") } }) Assert.assertTrue("Expected cmake to parse", cmake.generate(saGenRootTempDir)); Assert.assertTrue("Expected no make errors", cmake.make(saGenRootTempDir)); Assert.assertTrue("Failed to pack the FMU", cmake.make(saGenRootTempDir, "pack")); } } def __parseNoErrorsPrint(String filename) { val root = __parse(filename) print_ast(root) __assertNoParseErrors(root, filename) } def __parse(String filename) { return readFile(filename).parse } def __parse( String filename, ResourceSet resourceSetToUse ) { return readFile(filename).parse(resourceSetToUse) } def __assertNoParseErrors(EObject root, String filename) { try { root.assertNoErrors } catch (AssertionError e) { val p = Pattern.compile(".*, offset (?[0-9]+), length (?[0-9]+)") val code = readFile(filename) for (String line : e.message.split("\n")) { val m = p.matcher(line) m.matches() val count = __occurrencesInString(code.subSequence(0, Integer.valueOf(m.group("offset"))).toString(), "\n") print(filename + " at line " + (count + 1) + ": ") println(line) } throw e } } def __occurrencesInString(String str, String findstr) { var lastIndex = 0 var count = 0 while (lastIndex != -1) { lastIndex = str.indexOf(findstr, lastIndex) if (lastIndex != -1) { count++ lastIndex += findstr.length() } } return count } }