CgCppBasicTest.xtend 8.1 KB

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