6 Test dummy; // FIXME ugly hack
8 GlobalSettings globalSettings { };
14 void OnDisplay(Surface surface,
15 int x, int y, int width,
18 DataDisplayFlags flags)
20 ColorKey keys[] = {{Color {digest[0] , digest[1] , digest[2] }, 0.0f},
21 {Color {digest[3] , digest[4] , digest[5] }, 0.2f},
22 {Color {digest[6] , digest[7] , digest[8] }, 0.4f},
23 {Color {digest[9] , digest[10], digest[11]}, 0.6f},
24 {Color {digest[12], digest[13], digest[14]}, 0.8f},
25 {Color {digest[15], digest[0] , digest[1] }, 1.0f}};
27 surface.Gradient(keys, 6, 0, horizontal, x+1, y+1, x+34, y+14);
28 surface.Rectangle(x+1,y+1,x+34,y+14);
31 void OnSerialize(IOChannel channel)
33 channel.WriteData(digest,16);
35 void OnUnserialize(IOChannel channel)
37 channel.ReadData(digest,16);
42 TempFile hashTemp { };
44 Array<OutputFile> files = AccessMacros::allOutputFiles(value);
47 File f = of.outputFile;
53 uint count = f.Read(buffer,1,sizeof(buffer));
54 hashTemp.Write(buffer, 1, count);
63 size = hashTemp.GetSize();
64 MD5Update(&ctx, hashTemp.buffer, size);
65 MD5Final(digest, &ctx);
71 // TOFIX: When this is commented out, no warning at conversion but conversion not acting as such!!
76 CompilerConfig defaultCompiler;
78 void CreateMakefile(String epjPath, String makePath)
82 char* configName = null;//"release";
84 if(false) //noGlobalSettings)
86 defaultCompiler = MakeDefaultCompiler("Default", true);
91 char * compiler = getenv("COMPILER");
92 if(!compiler) compiler = "Default";
94 // TODO: Command line option to choose between the two
95 // or a command line option to not use global settings
96 //defaultCompiler = MakeDefaultCompiler();
97 defaultCompiler = ideSettings.GetCompilerConfig(compiler);
98 // possible TODO: use the workspace to select the active compiler
99 // TODO: option to specify compiler name when using global settings
101 defaultCompiler.eccCommand = "ecc -nolinenumbers";
103 if(FileExists(epjPath).isFile)
105 char extension[MAX_EXTENSION] = "";
106 GetExtension(epjPath, extension);
108 if(!strcmp(extension, ProjectExtension))
110 project = LoadProject(epjPath, "Debug");
113 ProjectConfig defaultConfig = null;
117 for(config : project.configurations)
119 if(!strcmpi(configName, config.name))
121 project.config = config;
127 printf("Error: Project configuration (%s) was not found.\n", configName);
131 ProjectConfig releaseConfig;
132 for(config : project.configurations)
134 if(!strcmpi(config.name, "Release"))
136 project.config = config;
137 releaseConfig = config;
141 if(!releaseConfig && project.configurations.count)
143 project.config = project.configurations.firstIterator.data;
145 releaseConfig = project.configs.first;
146 releaseConfig.objDir.dir = "release";
147 releaseConfig.targetDir.dir = "release";
148 releaseConfig.optimize = forSpeed;
149 releaseConfig.debug = false;
150 releaseConfig.name = "Release";
156 printf("Error: There are no Project configurations.\n", configName);
158 // we don't need to create a config to compile a config-less project, do we?
160 char targetName[MAX_FILENAME];
161 GetLastDirectory(epjPath, targetName);
162 StripExtension(targetName);
163 defaultConfig = ProjectConfig
166 targetType = executable;
167 targetName = targetName;
168 defaultNameSpace = "";
169 objDir.dir = "release";
170 targetDir.dir = "release";
174 makingModified = true;
175 compilingModified = true;
176 linkingModified = true;
178 project.config = defaultConfig;
184 project.GenerateCrossPlatformMk();
185 project.GenerateCompilerCf(defaultCompiler);
186 project.GenerateMakefile(makePath, false, null, project.config);
189 delete defaultConfig;
201 String filePath "filePath";
202 TestRun reference "reference";
203 bool active "active";
211 dbtable "OutputFiles" OutputFile
214 File outputFile "outputFile";
215 String filePath "filePath";
218 OutputFileType type "type";
219 DateTime created "created";
223 dbtable "Runs" TestRun
226 File makeOutput "makeOutput";
227 bool makeReturnValue "makeReturnValue";
229 TimeStamp time "time";
231 MD5Digest digest "digest";
232 dbindex test, time testAndTime;
239 TestRun ::lastTestRun(Test t)
242 Row tRow { tbl = dbindex("Runs", testAndTime) };
243 if(tRow.Find(dbfield("Runs",test),middle,nil,t)) {
249 Array<TestRun> ::allTestRuns(Test t)
251 Array<TestRun> runs { };
252 Row tRow { tbl = dbindex("Runs",testAndTime) };
253 for(tRow.Find(dbfield("Runs",test),middle,nil,t); !tRow.nil; tRow.Find(dbfield("Runs", test), next, nil, t)) //Next())
254 runs.Add(tRow.sysID);
258 Array<OutputFile> ::allOutputFiles(TestRun t)
260 Array<OutputFile> files { };
261 RowOutputFiles tRow { tbl = dbindex("OutputFiles",run) };
262 for(tRow.Find(dbfield("OutputFiles",run),middle,nil,t); !tRow.nil; tRow.Find(dbfield("OutputFiles", run), next, nil, t)) //tRow.Next())
266 files.Add(tRow.sysID);
273 class TestSuiteGlobalSettings : GlobalAppSettings
275 settingsName = "testSuite";
278 ~TestSuiteGlobalSettings()
283 void OnAskReloadSettings()
289 if(GlobalAppSettings::Load())
293 GetGlobalValue("Tools","diff", singleString, &diffTool);
294 GetGlobalValue("Tests","list", singleString, &testDB_file);
300 if(GlobalAppSettings::Save())
302 PutGlobalValue("Tools","diff", singleString, diffTool);
303 PutGlobalValue("Tests","list", singleString, testDB_file);
309 class DiffThread : Thread
311 char origDir[MAX_LOCATION];
312 char newDir[MAX_LOCATION];
317 FileListing flOrig { origDir, 0 };
318 FileListing flNew { newDir, 0 };
319 diff = DualPipeOpenf({ true }, "%s \"%s\" \"%s\"", theGlobalSettings.diffTool, origDir, newDir);
326 DeleteFile(flOrig.path);
331 DeleteFile(flNew.path);
337 void DiffDir(Array<OutputFile> outputOrig, Array<OutputFile> outputNew)
339 //char origDir[MAX_LOCATION];
340 //char newDir[MAX_LOCATION];
341 char tmpname[MAX_LOCATION];
343 CreateTemporaryDir(origDir, "TestSuiteOrigDir");
344 CreateTemporaryDir(newDir,"TestSuiteNewDir");
346 for(d : [ outputOrig, outputNew ])
350 char tmpname[MAX_LOCATION];
351 char dummybuffer[MAX_LOCATION];
352 File outputFile = of.outputFile;
356 GetLastDirectory(of.filePath, dummybuffer);
357 strcpy(tmpname, (d == outputOrig) ? origDir : newDir);
358 PathCat(tmpname, dummybuffer);
359 tmp = FileOpen(tmpname, write);
362 CopyFile(outputFile, tmp);
376 int GenerateMakefile(Test t)
378 DualPipe epj2makePipe;
379 char testFolder[MAX_LOCATION];
380 char makefileOut[MAX_LOCATION];
381 char epjName[MAX_LOCATION];
382 char * filePath = t.filePath;
385 StripLastDirectory(filePath, testFolder);
386 PathCat(testFolder, "release");
390 StripLastDirectory(filePath, testFolder);
391 GetLastDirectory(filePath, epjName);
392 strcpy(makefileOut, testFolder);
393 PathCat(makefileOut, "project-testingSuite.Makefile");
395 // epj2makePipe = DualPipeOpenf({ output = true },"epj2make -l /usr/ecere/lib -o %s %s > /dev/null", makefileOut, t.filePath);
396 //epj2makePipe = DualPipeOpenf({ output = true },"epj2make -cpp cpp -l /usr/ecere/lib -o %s %s", makefileOut, filePath);
397 //epj2makePipe.Wait();
398 CreateMakefile(filePath, makefileOut);
401 //return epj2makePipe.GetExitCode();
405 char* Copy2Temp(File f, String tmpPath)
408 char tmpFilename[MAX_LOCATION];
409 tmp = CreateTemporaryFile(tmpFilename, tmpPath);
415 int BuildTest(TestRun run)
418 int makeSuccess = -1;
419 char makefileOut[MAX_LOCATION];
420 char * filePath = run.test.filePath;
421 char oldDir[MAX_LOCATION];
422 StripLastDirectory(filePath, makefileOut);
424 GetWorkingDir(oldDir, sizeof(oldDir));
425 ChangeWorkingDir(makefileOut);
426 PathCat(makefileOut, "project-testingSuite.Makefile");
428 //Execute("make -f %s clean", makefileOut);
430 makePipe = DualPipeOpenf({ output = true },"%s -f %s clean", defaultCompiler.makeCommand, makefileOut);
434 char makeBuffer[1024];
437 while(!makePipe.Eof())
439 count = makePipe.Read(makeBuffer,1,sizeof(makeBuffer));
440 f.Write(makeBuffer, 1, count);
446 makePipe = DualPipeOpenf({ output = true },"%s -f %s", defaultCompiler.makeCommand, makefileOut);
450 char makeBuffer[1024];
453 while(!makePipe.Eof())
455 count = makePipe.Read(makeBuffer,1,sizeof(makeBuffer));
456 f.Write(makeBuffer, 1, count);
460 ChangeWorkingDir(oldDir);
461 makeSuccess = makePipe.GetExitCode();
462 run.makeReturnValue = makeSuccess;
467 void AddOutputFiles(TestRun run)
469 char testFolder[MAX_LOCATION];
471 char * filePath = run.test.filePath;
472 StripLastDirectory(filePath, testFolder);
474 // TODO: Get from config
475 PathCat(testFolder, "obj/release.win32");
477 fl = { testFolder, extensions = "c, ec, sym, imp" }; // ["c", "ec", "sym", "imp"] perhaps?
481 RowOutputFiles of { };
482 char extension[MAX_LOCATION];
483 DateTime rightNow { };
484 f = FileOpen(fl.path, read);
489 of.filePath = fl.path;
492 GetExtension(fl.path, extension);
493 if(!strcmp(extension,"c"))
497 else if(!strcmp(extension,"ec"))
501 else if(!strcmp(extension,"sym"))
505 else if(!strcmp(extension,"imp"))
509 rightNow.GetLocalTime();
510 of.created = (TimeStamp)rightNow;
517 void CopyFile(File input, File output)
520 input.Seek(0, start);
523 uint count = input.Read(buffer, 1, sizeof(buffer));
526 int yo = output.Write(buffer, 1, count);
531 class RelativeTimeStamp : TimeStamp
533 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
541 rightNow = (TimeStamp)dt;
542 count = (int64)(rightNow - (TimeStamp)this);
595 PrintBuf(tempString, 1024, "<1 minute ago");
599 PrintBuf(tempString, 1024, count, " ", units, (count > 1)? "s" : "", " ago");
608 void OnDisplay(Surface surface,
609 int x, int y, int width,
610 TrumpDialog trumpDialog,
612 DataDisplayFlags flags)
617 b = theTestSuiteWindow.makeSuccess.bitmap;
621 b = theTestSuiteWindow.makeFailure.bitmap;
623 surface.Blit(b, x, y, 0, 0, b.width, b.height);
627 class TestSuiteWindow : Window
629 text = "Ecere Compiler Tests";
630 background = activeBorder;
631 borderStyle = sizable;
636 anchor = { horz = -3, vert = 80 };
638 BitmapResource makeSuccess { ":check.png" , window = this };
639 BitmapResource makeFailure { ":x.png", window = this };
643 testListBox.AddField(fieldName);
644 testListBox.AddField(fieldActive);
646 runsListBox.AddField(fieldBuildStatus);
647 runsListBox.AddField(fieldAuraColor);
648 runsListBox.AddField(fieldRun);
649 runsListBox.AddField(fieldSaved);
650 // LoadTests(); FIXME this causes a segfault (but not OnCreate)
651 Print("starting up...\n");
654 PaneSplitter windowPanes
656 this, leftPane = testListBox, rightPane = runSection, split = 200;
660 this, anchor = { top = 0, bottom = 30, left = 0, right = 0 };
662 PaneSplitter runPanes
664 runSection, leftPane = dataBox, rightPane = runsListBox, split = 100, orientation = horizontal;
675 runsListBox.Update(null);
680 void NewTest(RowTests tRow, char* testName, char* testFilePath)
683 tRow.id = tRow.sysID;
686 tRow.filePath = testFilePath;
689 DataRow AddTest(RowTests tRow)
693 row = testListBox.AddRow();
695 s = tRow.name; row.SetData(fieldName, s); delete s;
696 row.SetData(fieldActive, tRow.active);
700 void DeleteTest(ListBox testListBox, DataRow row)
702 // do we also delete all runs and files associated with this test?
706 delete tRow; // won't be needed in the (distant?) future :-)
707 testListBox.DeleteRow(row);
715 theTestSuiteWindow.AddTest(tRow);
720 DataField fieldName { width = 140, header = "Name" , dataType = class(char*), editable = true };
721 DataField fieldActive { width = 40, header = "Active", dataType = class(bool) };
726 anchor = { top = 2, bottom = 30, left = 2, right = 2 },
729 bool NotifyChanged(ListBox testListBox, DataRow row)
733 tRow.name = row.GetData(fieldName);
734 tRow.active = row.GetData(fieldActive);
739 bool NotifyKeyDown(ListBox testListBox, DataRow row, Key key, unichar ch)
743 DeleteTest(testListBox, row);
744 // bRemove.NotifyClicked(this, bRemove,0,0,0);
746 else if(key == space)
748 //bool newActiveStatus = !(*(bool*)row.GetData(fieldActive)); // FIXME is needed?
749 row.SetData(fieldActive, !row.GetData(fieldActive));
750 testListBox.NotifyChanged(this, testListBox, row);
756 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
761 { // print to data box
770 dataBox.Printf("Name: %s\n", tname);
771 dataBox.Printf("Location: %s\n", tpath);
772 dataBox.Printf("Active: %d\n", tactive);
773 delete tname; delete tpath;
778 AccessMacros amacs{ };
780 runs = amacs.allTestRuns(t);
785 BuildStatus buildStatus;
786 TimeStamp time = tr.time;
787 MD5Digest aura = tr.digest;
788 buildStatus = tr.makeReturnValue ? failure : success;
789 row = runsListBox.AddRow();
791 row.SetData(fieldBuildStatus, buildStatus);
792 row.SetData(fieldAuraColor, aura);
793 row.SetData(fieldRun, time);
794 row.SetData(fieldSaved, tr.save);
802 DataField fieldBuildStatus { width = 40, dataType = class(BuildStatus), header = "Make" };
803 DataField fieldAuraColor { width = 40, dataType = class(MD5Digest), header = "Aura" };
804 DataField fieldRun { width = 120, dataType = class(RelativeTimeStamp), header = "Run" };
805 DataField fieldSaved { width = 80, dataType = class(bool), header = "Save", editable = true };
811 anchor = { top = 0, bottom = 0, left = 0, right = 0 },
814 bool NotifyChanged(ListBox listBox, DataRow row)
816 TestRun tr = (TestRun)row.tag;
817 tr.save = row.GetData(fieldSaved);
827 anchor = { top = 0, bottom = 0, left = 0, right = 0 },
828 hasHorzScroll = true,
838 anchor = { bottom = 2, left = 2 };
840 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
842 FileFilter projectFilters[] =
844 { "eC project and source files (.ec, .epj)", "ec, epj" }
846 FileDialog f { filters = projectFilters, sizeFilters = sizeof(projectFilters), type = multiOpen };
852 for(i=0; i<f.numSelections; ++i)
854 char testName[MAX_LOCATION];
856 GetLastDirectory(f.multiFilePaths[i], testName);
857 NewTest(tRow, testName, f.multiFilePaths[i]);
859 if(i+1 == f.numSelections)
861 testListBox.SelectRow(row);
875 anchor = { bottom = 2, right = 2 };
877 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
880 for(row=testListBox.firstRow; row; row=row.next)
882 Test t = (Test)row.tag;
891 DateTime rightNow { };
895 runs.id = runs.sysID;
896 rightNow.GetLocalTime();
897 runs.time = (TimeStamp)rightNow;
900 bt.GenerateMakefile(t);
902 bt.AddOutputFiles(run);
911 Array<OutputFile> outputsLatest = AccessMacros::allOutputFiles(run);
912 Array<OutputFile> outputsReference = AccessMacros::allOutputFiles(t.reference);
913 dt.DiffDir(outputsReference, outputsLatest);
916 testListBox.NotifySelect(this, testListBox, testListBox.currentRow, mods);
924 text = "Accept Run (x)",
926 anchor={ bottom = 2, right = 52 };
928 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
931 MessageBox confirmation
934 text = "Accept Test",
935 contents = "Accept the selected test?"
937 if(confirmation.Modal() == yes)
940 row = runsListBox.currentRow;
943 tr = (TestRun)row.tag;
945 tr.test.reference = tr;
953 globalSettings.Load();
956 delete theGlobalSettings.diffTool;
957 theGlobalSettings.diffTool = CopyString("meld");
958 // theGlobalSettings.diffTool = CopyString("C:/Program Files/Araxis/Araxis Merge v6.5/compare.exe /wait");
963 TestSuiteWindow theTestSuiteWindow { };
964 TestSuiteGlobalSettings theGlobalSettings { };
966 class TestSuiteApp : GuiApplication
968 DataSource ds { driver = /*"SQLite" */"EDB" };
973 db = database_open(ds, "TestSuite");
977 Array<OutputFile> files;
981 RowOutputFiles rFiles { };
984 Test t = (Test)tests.id;
985 runs = AccessMacros::allTestRuns(t);
990 if(t.reference == run)
994 files = AccessMacros::allOutputFiles(run);
1014 settingsContainer.Load();
1015 delete settingsContainer;