CgCppBasicTest.xtend 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * generated by Xtext 2.10.0
  3. */
  4. package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
  5. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.BuildUtilities
  6. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator
  7. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests.CMakeUtil.CMakeGenerateException
  8. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
  9. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CMakeListsGenerator
  10. import be.uantwerpen.ansymo.semanticadaptation.testframework.FmuMainTestGenerator
  11. import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
  12. import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
  13. import com.google.inject.Inject
  14. import java.io.File
  15. import java.io.FileFilter
  16. import java.io.FileWriter
  17. import java.nio.file.Files
  18. import java.nio.file.Paths
  19. import java.util.regex.Pattern
  20. import org.apache.commons.io.FileUtils
  21. import org.eclipse.emf.ecore.EObject
  22. import org.eclipse.emf.ecore.resource.ResourceSet
  23. import org.eclipse.xtext.generator.InMemoryFileSystemAccess
  24. import org.eclipse.xtext.testing.InjectWith
  25. import org.eclipse.xtext.testing.XtextRunner
  26. import org.eclipse.xtext.testing.util.ParseHelper
  27. import org.eclipse.xtext.testing.validation.ValidationTestHelper
  28. import org.junit.Assert
  29. import org.junit.BeforeClass
  30. import org.junit.Ignore
  31. import org.junit.Test
  32. import org.junit.runner.RunWith
  33. @RunWith(XtextRunner)
  34. @InjectWith(SemanticAdaptationInjectorProvider)
  35. class CgCppBasicTest extends AbstractSemanticAdaptationTest {
  36. // @Inject CppGenerator underTest
  37. @Inject extension ParseHelper<SemanticAdaptation>
  38. @Inject extension ValidationTestHelper
  39. val static hcfRoot = Paths.get("target", "hcfDummy", "hcf").toFile()
  40. @BeforeClass
  41. def static setupHcf() {
  42. if (!CMakeUtil.windows) {
  43. FileUtils.write(new File(hcfRoot.parentFile, "CMakeLists.txt"),
  44. CMakeListsGenerator.generateCMakeListsHcfDummy());
  45. val cmake = new CMakeUtil(true)
  46. try {
  47. Assert.assertTrue("Expected cmake to parse", cmake.generate(hcfRoot.parentFile));
  48. Assert.assertTrue("Expected no make errors", cmake.make(hcfRoot.parentFile));
  49. } catch (CMakeGenerateException e) {
  50. e.printStackTrace
  51. }
  52. }
  53. }
  54. @Test def window_sa_canonical_new() {
  55. __parseAndGenerateWithNoErrors('window_sa_canonical_new.BASE.sa', 'test_input/single_folder_spec/window/', 'powerwindow');
  56. }
  57. @Test def empty_ctrl_rules() {
  58. __parseAndGenerateWithNoErrors('plantmr.sa', 'test_input/single_folder_spec/emptyctrlrules/', 'PlantMR');
  59. }
  60. @Test def getSetState_sa() {
  61. __parseAndGenerateWithNoErrors('GetSetState.sa', 'test_input/single_folder_spec/getsetstate/', "getSetState");
  62. }
  63. @Test def lazy_canonical() {
  64. __parseAndGenerateWithNoErrors('lazy_canonical.sa', 'test_input/single_folder_spec/lazy/', "lazy");
  65. }
  66. @Ignore @Test def loop() {
  67. __parseAndGenerateWithNoErrors('loop_canonical.sa', 'test_input/single_folder_spec/loop/', "LoopSA");
  68. }
  69. @Test def rate() {
  70. __parseAndGenerateWithNoErrors('rate.sa', 'test_input/single_folder_spec/rate/', "rate");
  71. }
  72. @Test def rate_canonical() {
  73. __parseAndGenerateWithNoErrors('rate_canonical.sa', 'test_input/single_folder_spec/rate/', "rate_canonical");
  74. }
  75. @Test def power() {
  76. __parseAndGenerateWithNoErrors('power.BASE.sa', 'test_input/single_folder_spec/power/', 'power');
  77. }
  78. @Test def rollback_test() {
  79. __parseAndGenerateWithNoErrors('rollback_test.sa', 'test_input/single_folder_spec/rollback_test/', 'rollback_test');
  80. }
  81. @Test def controller_test() {
  82. __parseAndGenerateWithNoErrors('controller.sa', 'test_input/single_folder_spec/controller/', 'controller');
  83. }
  84. def __parseNoErrorsWithValidation(String directory, String filename) {
  85. val model = __parse(filename);
  86. __assertNoParseErrors(model, filename);
  87. val correctFileDirectory = new File(directory + File.separator + "correct");
  88. val fsa = new InMemoryFileSystemAccess()
  89. val cppGen = new CppGenerator();
  90. cppGen.doGenerate(model.eResource, fsa);
  91. for (files : fsa.allFiles.entrySet) {
  92. val filename2 = files.key.substring(14);
  93. val file = new File(correctFileDirectory, filename2);
  94. val correctFileContent = Files.readAllLines(file.toPath);
  95. var path = new File("generated");
  96. if (path.exists)
  97. path.delete
  98. else
  99. path.mkdir;
  100. path = new File(path, files.key.substring(14))
  101. val FileWriter writer = new FileWriter(path);
  102. writer.write(files.value.toString);
  103. writer.close;
  104. val testFileContent = Files.readAllLines(path.toPath);
  105. if (correctFileContent.size != testFileContent.size) {
  106. System.out.println("Error: Lines are of different length in file: " + filename2);
  107. } else {
  108. for (var i = 0; i < testFileContent.size; i++) {
  109. val testLine = testFileContent.get(i);
  110. val correctLine = correctFileContent.get(i);
  111. if (testLine.compareTo(correctLine) != 0) {
  112. if (!testLine.contains("guid")) {
  113. System.out.println("ERROR: The following lines are not equal: \n" + testLine + "\n" +
  114. correctLine);
  115. }
  116. }
  117. }
  118. }
  119. }
  120. }
  121. def __parseAndGenerateWithNoErrors(String filename, String directory, String projectName) {
  122. val dirTestOutput = directory.replace('test_input/','target/test-classes/')
  123. val saRootDir = Paths.get(dirTestOutput).toFile();
  124. val saGenRootTempDir = Paths.get(dirTestOutput, projectName).toFile();
  125. val absFileName = Paths.get(dirTestOutput, filename).toFile();
  126. val srcGenPath = new File(saGenRootTempDir, "sources")
  127. val resourcesPath = new File(saGenRootTempDir, "resources");
  128. println("saGenRootTempDir="+saGenRootTempDir.absolutePath)
  129. println("absFileName="+absFileName.absolutePath)
  130. val model = __parse(absFileName.absolutePath)
  131. __assertNoParseErrors(model, absFileName.absolutePath)
  132. val fsa = new InMemoryFileSystemAccess();
  133. val cppGen = new CppGenerator();
  134. cppGen.doGenerate(model.eResource, fsa, saRootDir.absolutePath);
  135. if (saGenRootTempDir.exists) {
  136. BuildUtilities.deleteFolder(saGenRootTempDir);
  137. }
  138. saGenRootTempDir.mkdirs();
  139. srcGenPath.mkdirs();
  140. resourcesPath.mkdirs();
  141. for (files : fsa.allFiles.entrySet) {
  142. val fName = files.key.substring(14);
  143. var File fp;
  144. if (fName.equals("modelDescription.xml") || fName.equals("CMakeLists.txt") || fName.equals("msys-toolchain.cmake")) {
  145. fp = new File(saGenRootTempDir, fName);
  146. } else {
  147. fp = new File(srcGenPath, fName);
  148. }
  149. BuildUtilities.writeToFile(fp, files.value.toString);
  150. }
  151. val mainCpp = FmuMainTestGenerator.generateMainCppFile(resourcesPath.absolutePath.replace("\\", "\\\\"));
  152. BuildUtilities.writeToFile(new File(srcGenPath, "main.cpp"), mainCpp);
  153. for (rf : cppGen.resourcePaths) {
  154. val sinkFile = new File(resourcesPath, rf.name);
  155. System.out.println("Copied file to: " + sinkFile);
  156. BuildUtilities.copyFile(rf, sinkFile);
  157. }
  158. // BuildUtilities.writeToFile(new File(saRootDir, "CMakeLists.txt"),
  159. // CMakeListsGenerator.generateCMakeLists(projectName));
  160. //
  161. // val cMakeToolChain = CMakeListsGenerator.generateToolChainCmake();
  162. // BuildUtilities.writeToFile(new File(saRootDir, "msys-toolchain.cmake"), cMakeToolChain);
  163. if (!CMakeUtil.windows) {
  164. val cmake = new CMakeUtil(true)
  165. FileUtils.copyDirectory(hcfRoot, new File(saGenRootTempDir, "hcf"), new FileFilter() {
  166. override accept(File pathname) {
  167. return !pathname.name.equals("CMakeCache.txt")
  168. }
  169. })
  170. Assert.assertTrue("Expected cmake to parse", cmake.generate(saGenRootTempDir));
  171. Assert.assertTrue("Expected no make errors", cmake.make(saGenRootTempDir));
  172. Assert.assertTrue("Failed to pack the FMU", cmake.make(saGenRootTempDir, "pack"));
  173. }
  174. }
  175. def __parseNoErrorsPrint(String filename) {
  176. val root = __parse(filename)
  177. print_ast(root)
  178. __assertNoParseErrors(root, filename)
  179. }
  180. def __parse(String filename) {
  181. return readFile(filename).parse
  182. }
  183. def __parse(
  184. String filename,
  185. ResourceSet resourceSetToUse
  186. ) {
  187. return readFile(filename).parse(resourceSetToUse)
  188. }
  189. def __assertNoParseErrors(EObject root, String filename) {
  190. try {
  191. root.assertNoErrors
  192. } catch (AssertionError e) {
  193. val p = Pattern.compile(".*, offset (?<offset>[0-9]+), length (?<length>[0-9]+)")
  194. val code = readFile(filename)
  195. for (String line : e.message.split("\n")) {
  196. val m = p.matcher(line)
  197. m.matches()
  198. val count = __occurrencesInString(code.subSequence(0, Integer.valueOf(m.group("offset"))).toString(),
  199. "\n")
  200. print(filename + " at line " + (count + 1) + ": ")
  201. println(line)
  202. }
  203. throw e
  204. }
  205. }
  206. def __occurrencesInString(String str, String findstr) {
  207. var lastIndex = 0
  208. var count = 0
  209. while (lastIndex != -1) {
  210. lastIndex = str.indexOf(findstr, lastIndex)
  211. if (lastIndex != -1) {
  212. count++
  213. lastIndex += findstr.length()
  214. }
  215. }
  216. return count
  217. }
  218. }