1
2
3
4
5
6
7
8 package org.eclipse.papyrus.designer.languages.cpp.codegen.tests;
9
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13
14 import java.io.InputStream;
15 import java.util.List;
16 import java.util.Scanner;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IFolder;
20 import org.eclipse.core.resources.IProject;
21 import org.eclipse.core.resources.ResourcesPlugin;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.NullProgressMonitor;
25 import org.eclipse.emf.common.util.URI;
26 import org.eclipse.emf.ecore.EObject;
27 import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
28 import org.eclipse.papyrus.infra.core.sashwindows.di.service.IPageManager;
29 import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
30 import org.eclipse.papyrus.infra.services.openelement.service.OpenElementService;
31 import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
32 import org.eclipse.papyrus.junit.utils.EditorUtils;
33 import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
34 import org.eclipse.papyrus.uml.tools.model.UmlModel;
35 import org.eclipse.papyrus.uml.tools.model.UmlUtils;
36 import org.eclipse.ui.IWorkbenchPage;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.handlers.IHandlerService;
39 import org.junit.AfterClass;
40 import org.junit.BeforeClass;
41 import org.junit.ClassRule;
42 import org.junit.Test;
43
44 @SuppressWarnings("nls")
45 public class CppCodegenTest {
46
47 static {
48
49
50 System.setProperty("papyrus.run-headless", Boolean.TRUE.toString());
51 }
52
53 private static final String GENERATE_COMMAND_ID = "org.eclipse.papyrus.designer.languages.cpp.codegen.command";
54
55 private static final String EDITOR_ID = "org.eclipse.papyrus.infra.core.papyrusEditor";
56
57 private static final String ModelProjectName = "project";
58
59 private static final String ModelName = "CppCodegenTest.uml";
60
61 private static final String GenProjectName = "org.eclipse.papyrus.cppgen.CppCodegenTest";
62
63 private static final String GenFolderName = "CppCodegenTest";
64
65 private static final String ModelPath = "/" + ModelProjectName + '/' + ModelName;
66
67 private static final String ExpectedGenFolderName = "ExpectedModel";
68
69 private static final String ExpectedGenFolderPath = "/" + ModelProjectName + '/' + ExpectedGenFolderName;
70
71 private static final String Class1_fragment = "_x6ArECrKEeOncLSXAkfRBA";
72
73 private static final String Class2_fragment = "_0E-t0CrKEeOncLSXAkfRBA";
74
75 private static final String Class3_fragment = "_29UM4CrKEeOncLSXAkfRBA";
76
77 private static final String Class4_fragment = "_-j3HgCrKEeOncLSXAkfRBA";
78
79 private static final String Class5_fragment = "_hTMV0CumEeOcwILjsIdkdw";
80
81 private static final String Class6_fragment = "_OJ7A0CxUEeOcwILjsIdkdw";
82
83 private static final String Class7_fragment = "_ZqD3YCz9EeOcwILjsIdkdw";
84
85 private static final String Class8_fragment = "_qS9iYDEmEeOSfbt-FmCdoQ";
86
87 private static final String Class9_fragment = "_jcK5MDG0EeOOEc5pE2t6oQ";
88
89 private static final String Package1_fragment = "_nZ5DgDEmEeOSfbt-FmCdoQ";
90
91 private static final String Model_fragment = "_1_ToYCoNEeOncLSXAkfRBA";
92
93 private static final IProgressMonitor npm = new NullProgressMonitor();
94
95 private static IProject modelProject;
96
97 private static IProject genProject;
98
99 private static IHandlerService handlerService;
100
101 private static URI modelUri;
102
103 private static URI genCodeUri;
104
105 private static IWorkbenchPage page;
106
107 private static PapyrusMultiDiagramEditor editor;
108
109 private static OpenElementService elementActivator;
110
111 private static UmlModel model;
112
113 @ClassRule
114 public static HouseKeeper.Static houseKeeper = new HouseKeeper.Static();
115
116 @BeforeClass
117 public static void loadProject() throws Exception {
118
119 handlerService = (IHandlerService)PlatformUI.getWorkbench().getService(IHandlerService.class);
120
121
122
123 modelProject = houseKeeper.createProject(ModelProjectName);
124
125
126 IFile diFile = houseKeeper.createFile(modelProject, "CppCodegenTest.di", "resources/CppCodegenTest.di");
127 houseKeeper.createFile(modelProject, "CppCodegenTest.notation", "resources/CppCodegenTest.notation");
128 houseKeeper.createFile(modelProject, "CppCodegenTest.uml", "resources/CppCodegenTest.uml");
129
130 String[] targetFiles = new String[]{
131 "Class1.h", "Class1.cpp",
132 "Class2.h", "Class2.cpp",
133 "Class3.h", "Class3.cpp",
134 "Class4.h", "Class4.cpp",
135 "Class5.h", "Class5.cpp",
136 "Class6.h", "Class6.cpp",
137 "Class7.h", "Class7.cpp",
138 "Pkg_CppCodegenTest.h",
139 "Package1/Class8.h", "Package1/Class8.cpp",
140 "Package1/Class9.h", "Package1/Class9.cpp",
141 "Package1/Pkg_Package1.h"
142 };
143
144 for (String targetFile: targetFiles){
145 houseKeeper.createFile(modelProject, targetFile, ExpectedGenFolderName + "/" + targetFile);
146 }
147
148
149 modelUri = URI.createPlatformResourceURI(ModelPath, true);
150 assertNotNull(modelUri);
151
152
153
154 page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
155
156 editor = (PapyrusMultiDiagramEditor) EditorUtils.openEditor(diFile);
157 assertNotNull(editor);
158
159 model = UmlUtils.getUmlModel();
160 assertNotNull(model);
161
162
163 elementActivator = editor.getServicesRegistry().getService(OpenElementService.class);
164 assertNotNull(elementActivator);
165
166
167 genCodeUri = URI.createPlatformPluginURI(ExpectedGenFolderPath, true);
168 assertNotNull(genCodeUri);
169 }
170
171 @AfterClass
172 public static void cleanup() throws Exception {
173 if(modelProject == null) {
174 return;
175 }
176
177
178
179 if(page != null) {
180 page.closeAllEditors(false);
181 }
182
183
184 modelProject.delete(true, true, npm);
185 modelProject = null;
186 }
187
188 @Test
189 public void testGenerateClass1() throws Exception {
190 assertGenerate(Class1_fragment);
191 assertGeneratedMatchesExpected("Class1.h");
192 assertGeneratedMatchesExpected("Class1.cpp");
193 }
194
195 @Test
196 public void testGenerateClass2() throws Exception {
197 assertGenerate(Class2_fragment);
198 assertGeneratedMatchesExpected("Class2.h");
199 assertGeneratedMatchesExpected("Class2.cpp");
200 }
201
202 @Test
203 public void testGenerateClass3() throws Exception {
204 assertGenerate(Class3_fragment);
205 assertGeneratedMatchesExpected("Class3.h");
206 assertGeneratedMatchesExpected("Class3.cpp");
207 }
208
209 @Test
210 public void testGenerateClass4() throws Exception {
211 assertGenerate(Class4_fragment);
212 assertGeneratedMatchesExpected("Class4.h");
213 assertGeneratedMatchesExpected("Class4.cpp");
214 }
215
216 @Test
217 public void testGenerateClass5() throws Exception {
218 assertGenerate(Class5_fragment);
219 assertGeneratedMatchesExpected("Class5.h");
220 assertGeneratedMatchesExpected("Class5.cpp");
221 }
222
223 @Test
224 public void testGenerateClass6() throws Exception {
225 assertGenerate(Class6_fragment);
226 assertGeneratedMatchesExpected("Class6.h");
227 assertGeneratedMatchesExpected("Class6.cpp");
228 }
229
230 @Test
231 public void testGenerateClass7() throws Exception {
232 assertGenerate(Class7_fragment);
233 assertGeneratedMatchesExpected("Class7.h");
234 assertGeneratedMatchesExpected("Class7.cpp");
235 }
236
237 @Test
238 public void testGenerateClass8() throws Exception {
239 assertGenerate(Class8_fragment);
240 assertGeneratedMatchesExpected("Class8.h", "Package1");
241 assertGeneratedMatchesExpected("Class8.cpp", "Package1");
242 }
243
244 @Test
245 public void testGenerateClass9() throws Exception {
246 assertGenerate(Class9_fragment);
247 assertGeneratedMatchesExpected("Class9.h", "Package1");
248 assertGeneratedMatchesExpected("Class9.cpp", "Package1");
249 }
250
251 @Test
252 public void testGeneratePackage1NamespaceHeader() throws Exception {
253 assertGenerate(Package1_fragment);
254 assertGeneratedMatchesExpected("Pkg_Package1.h", "Package1");
255 }
256
257
258 @Test
259 public void testGenerateModelNamespaceHeader() throws Exception {
260 assertGenerate(Model_fragment);
261 assertGeneratedMatchesExpected("Pkg_CppCodegenTest.h");
262 }
263
264 private void assertGenerate(String fragment) throws Exception {
265 selectSemanticElement(fragment);
266 handlerService.executeCommand(GENERATE_COMMAND_ID, null);
267 }
268
269 private void selectSemanticElement(String uriFragment) throws Exception {
270 URI elementUri = modelUri.appendFragment(uriFragment);
271 EObject semantic = model.getResource().getResourceSet().getEObject(elementUri, true);
272
273
274
275
276
277 IMultiDiagramEditor editor = elementActivator.openSemanticElement(semantic);
278 assertNotNull(editor);
279
280
281
282 if(editor.getActiveEditor() == null) {
283 ServicesRegistry registry = (ServicesRegistry)editor.getAdapter(ServicesRegistry.class);
284 assertNotNull(registry);
285
286 IPageManager pageManager = registry.getService(IPageManager.class);
287 assertNotNull(pageManager);
288
289 List<Object> pages = pageManager.allPages();
290 assertNotNull(pages);
291 assertTrue(pages.size() > 0);
292
293 editor = elementActivator.openSemanticElement(semantic, pages.toArray());
294 assertNotNull(editor);
295 }
296
297
298 assertNotNull(editor.getActiveEditor());
299 }
300
301 private static String getFileContents(IFile file) throws CoreException {
302 InputStream inStream = file.getContents();
303 assertNotNull("Contents of file \"" + file.getName() + "\" are empty.", inStream);
304 String content = null;
305 Scanner s = new Scanner(inStream);
306
307 s.useDelimiter("\\Z");
308
309 content = s.hasNext() ? s.next() : "";
310 s.close();
311
312 return content;
313 }
314
315 private IProject getGeneratedProject() {
316 if(genProject != null) {
317 return genProject;
318 }
319
320 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(GenProjectName);
321 if(project == null || !project.exists()) {
322 throw new AssertionError("Generated project not found");
323 }
324
325 return genProject = project;
326 }
327
328
329
330
331
332
333
334
335
336
337 private void assertGeneratedMatchesExpected(String fileName, String... depthSegments) throws Exception {
338 IFolder generatedFolder = getGeneratedProject().getFolder(GenFolderName);
339 assertTrue("Default generated folder \"" + GenFolderName + "\" was not generated", generatedFolder.exists());
340
341
342 IFolder generatedPackageFolder = null;
343 for(int i = 0; i < depthSegments.length; i++) {
344 if(i == 0) {
345 generatedPackageFolder = generatedFolder.getFolder(depthSegments[i]);
346 } else {
347 generatedPackageFolder = generatedPackageFolder.getFolder(depthSegments[i]);
348 }
349 assertTrue("Package folder \"" + depthSegments[i] + "\" was not generated.", generatedPackageFolder.exists());
350 }
351
352
353 IFile generatedFile = null;
354 if(generatedPackageFolder != null) {
355 generatedFile = generatedPackageFolder.getFile(fileName);
356 } else {
357 generatedFile = generatedFolder.getFile(fileName);
358 }
359 assertTrue("File " + fileName + " was not generated.", generatedFile.exists());
360 String fileContent = getFileContents(generatedFile);
361
362
363
364 IFolder expectedFolder = null;
365 for(int i = 0; i < depthSegments.length; i++) {
366 if(i == 0) {
367 expectedFolder = modelProject.getFolder(depthSegments[i]);
368 } else {
369 expectedFolder = expectedFolder.getFolder(depthSegments[i]);
370 }
371 assertTrue("Package folder \"" + depthSegments[i] + "\" was not generated.", expectedFolder.exists());
372 }
373
374
375 IFile expectedFile = null;
376 if(expectedFolder != null) {
377 expectedFile = expectedFolder.getFile(fileName);
378 } else {
379 expectedFile = modelProject.getFile(fileName);
380 }
381 assertTrue("File " + fileName + " was not generated.", expectedFile.exists());
382 String expectedFileContent = getFileContents(expectedFile);
383
384 assertContentMatches(fileName, fileContent, expectedFileContent);
385 }
386
387 private static void assertContentMatches(String filename, String generated, String expected) {
388 Scanner expectedScanner = new Scanner(expected);
389 char[] strippedGen = generated.replaceAll("\\s+", "").trim().toCharArray();
390 int genCharsTraversed = 0;
391 boolean outofchars = false;
392
393
394
395
396
397
398
399
400
401 try {
402 int lineNumber = 1;
403 int lineCharBegin = 0;
404 for(; !outofchars && expectedScanner.hasNextLine(); ++lineNumber) {
405 lineCharBegin = genCharsTraversed;
406 String eLine = expectedScanner.nextLine();
407 String strippedELine = eLine.replaceAll("\\s+", "").trim();
408 char[] strippedExpected = strippedELine.toCharArray();
409 for(int i = 0; i < strippedExpected.length; i++) {
410 if(strippedExpected[i] != strippedGen[genCharsTraversed]) {
411 fail(filename + ':' + lineNumber + "expected '" + eLine.trim() + "'but found '" + rebuildStringForLineError(generated.trim(), eLine.trim(), i, genCharsTraversed, lineCharBegin) + "'");
412 }
413 genCharsTraversed++;
414 if(genCharsTraversed == strippedGen.length) {
415 outofchars = true;
416 }
417 }
418 }
419 if(expectedScanner.hasNextLine()) {
420 fail(filename + ':' + lineNumber + " expected '" + expectedScanner.nextLine() + "' but found end-of-file");
421 } else if(!outofchars) {
422 fail(filename + ':' + lineNumber + " expected end-of-file but found '" + rebuildStringForEndOfFileError(generated.trim(), genCharsTraversed) + '\'');
423 }
424 } finally {
425 if(expectedScanner != null) {
426 expectedScanner.close();
427 }
428 }
429 }
430
431 private static String rebuildStringForLineError(String generatedString, String expectedLine, int beginInExpectedLine, int genCharsTraversed, int firstCharInExpLine) {
432 String brokenLine = "";
433
434 int lengthFromFirstDiff = expectedLine.replaceAll("\\s+", "").length() - beginInExpectedLine;
435 char[] generatedChars = generatedString.replaceAll("\\s+", " ").toCharArray();
436 int nonwhitechars = 0;
437 for(int i = 0; i < generatedChars.length; i++) {
438 if(generatedChars[i] != ' ') {
439 nonwhitechars++;
440 }
441 if(nonwhitechars >= firstCharInExpLine && nonwhitechars < genCharsTraversed + lengthFromFirstDiff) {
442
443 brokenLine += generatedChars[i];
444 } else if(nonwhitechars == genCharsTraversed + lengthFromFirstDiff) {
445
446 if(generatedChars[i + 1] != '\0') {
447 brokenLine += "...";
448 }
449 break;
450 }
451 }
452
453 return brokenLine;
454 }
455
456 private static String rebuildStringForEndOfFileError(String generatedString, int genCharsTraversed) {
457 String brokenLine = "";
458
459 char[] generatedChars = generatedString.replaceAll("\\s+", " ").toCharArray();
460 int nonwhitechars = 0;
461 for(int i = 0; i < generatedChars.length; i++) {
462 if(generatedChars[i] != ' ') {
463 nonwhitechars++;
464 }
465 if(nonwhitechars > genCharsTraversed && generatedChars[i] != '\0') {
466
467 brokenLine += generatedChars[i];
468 } else if(nonwhitechars == genCharsTraversed + 15 || generatedChars[i] == '\0') {
469
470 if(generatedChars[i + 1] != '\0') {
471 brokenLine += "...";
472 }
473 break;
474 }
475 }
476 return brokenLine;
477 }
478 }