7 Test dummy; // FIXME ugly hack
9 GlobalSettings globalSettings { };
15 void OnDisplay(Surface surface,
16 int x, int y, int width,
19 DataDisplayFlags flags)
21 ColorKey keys[] = {{Color {digest[0] , digest[1] , digest[2] }, 0.0f},
22 {Color {digest[3] , digest[4] , digest[5] }, 0.2f},
23 {Color {digest[6] , digest[7] , digest[8] }, 0.4f},
24 {Color {digest[9] , digest[10], digest[11]}, 0.6f},
25 {Color {digest[12], digest[13], digest[14]}, 0.8f},
26 {Color {digest[15], digest[0] , digest[1] }, 1.0f}};
28 surface.Gradient(keys, 6, 0, horizontal, x+1, y+1, x+34, y+14);
29 surface.Rectangle(x+1,y+1,x+34,y+14);
32 void OnSerialize(IOChannel channel)
34 channel.WriteData(digest,16);
36 void OnUnserialize(IOChannel channel)
38 channel.ReadData(digest,16);
43 TempFile hashTemp { };
45 Array<OutputFile> files = AccessMacros::allOutputFiles(value);
48 File f = of.outputFile;
54 uint count = f.Read(buffer,1,sizeof(buffer));
55 hashTemp.Write(buffer, 1, count);
64 size = hashTemp.GetSize();
65 MD5Update(&ctx, hashTemp.buffer, size);
66 MD5Final(digest, &ctx);
72 // TOFIX: When this is commented out, no warning at conversion but conversion not acting as such!!
77 CompilerConfig defaultCompiler;
79 void CreateMakefile(String epjPath, String makePath)
83 char* configName = null;//"release";
85 defaultCompiler = MakeDefaultCompiler("Default", true);
86 defaultCompiler.eccCommand = "ecc -nolinenumbers";
88 if(FileExists(epjPath).isFile)
90 char extension[MAX_EXTENSION] = "";
91 GetExtension(epjPath, extension);
93 if(!strcmp(extension, ProjectExtension))
95 project = LoadProject(epjPath);
98 ProjectConfig defaultConfig = null;
102 for(config : project.configurations)
104 if(!strcmpi(configName, config.name))
106 project.config = config;
112 printf("Error: Project configuration (%s) was not found.\n", configName);
116 ProjectConfig releaseConfig;
117 for(config : project.configurations)
119 if(!strcmpi(config.name, "Release"))
121 project.config = config;
122 releaseConfig = config;
126 if(!releaseConfig && project.configurations.count)
128 project.config = project.configurations.firstIterator.data;
130 releaseConfig = project.configs.first;
131 releaseConfig.objDir.dir = "release";
132 releaseConfig.targetDir.dir = "release";
133 releaseConfig.optimize = forSpeed;
134 releaseConfig.debug = false;
135 releaseConfig.name = "Release";
141 printf("Error: There are no Project configurations.\n", configName);
143 // we don't need to create a config to compile a config-less project, do we?
145 char targetName[MAX_FILENAME];
146 GetLastDirectory(epjPath, targetName);
147 StripExtension(targetName);
148 defaultConfig = ProjectConfig
151 targetType = executable;
152 targetName = targetName;
153 defaultNameSpace = "";
154 objDir.dir = "release";
155 targetDir.dir = "release";
159 makingModified = true;
160 compilingModified = true;
161 linkingModified = true;
163 project.config = defaultConfig;
168 project.GenerateMakefile(makePath, false, "");
170 delete defaultConfig;
182 String filePath "filePath";
183 TestRun reference "reference";
184 bool active "active";
192 dbtable "OutputFiles" OutputFile
195 File outputFile "outputFile";
196 String filePath "filePath";
199 OutputFileType type "type";
200 DateTime created "created";
204 dbtable "Runs" TestRun
207 File makeOutput "makeOutput";
208 bool makeReturnValue "makeReturnValue";
210 TimeStamp time "time";
212 MD5Digest digest "digest";
213 dbindex test, time testAndTime;
220 TestRun ::lastTestRun(Test t)
223 Row tRow { tbl = dbindex("Runs", testAndTime) };
224 if(tRow.Find(dbfield("Runs",test),middle,nil,t)) {
230 Array<TestRun> ::allTestRuns(Test t)
232 Array<TestRun> runs { };
233 Row tRow { tbl = dbindex("Runs",testAndTime) };
234 for(tRow.Find(dbfield("Runs",test),middle,nil,t); !tRow.nil; tRow.Next())
235 runs.Add(tRow.sysID);
239 Array<OutputFile> ::allOutputFiles(TestRun t)
241 Array<OutputFile> files { };
242 RowOutputFiles tRow { tbl = dbindex("OutputFiles",run) };
243 for(tRow.Find(dbfield("OutputFiles",run),middle,nil,t); !tRow.nil; tRow.Next())
247 files.Add(tRow.sysID);
254 class TestSuiteApp : GuiApplication
256 DataSource ds { driver = /*"SQLite"*/"EDB" };
259 db = database_open(ds, "TestSuite");
263 Array<OutputFile> files;
267 RowOutputFiles rFiles { };
270 Test t = (Test)tests.id;
271 runs = AccessMacros::allTestRuns(t);
276 if(t.reference == run)
280 files = AccessMacros::allOutputFiles(run);
299 class TestSuiteGlobalSettings : GlobalAppSettings
301 settingsName = "testSuite";
304 ~TestSuiteGlobalSettings()
309 void OnAskReloadSettings()
315 if(GlobalAppSettings::Load())
319 GetGlobalValue("Tools","diff", singleString, &diffTool);
320 GetGlobalValue("Tests","list", singleString, $testDB_file);
326 if(GlobalAppSettings::Save())
328 PutGlobalValue("Tools","diff", singleString, diffTool);
329 PutGlobalValue("Tests","list", singleString, testDB_file);
335 class DiffThread : Thread
337 char origDir[MAX_LOCATION];
338 char newDir[MAX_LOCATION];
343 FileListing flOrig { origDir, 0 };
344 FileListing flNew { newDir, 0 };
345 diff = DualPipeOpenf({ true }, "%s \"%s\" \"%s\"", theGlobalSettings.diffTool, origDir, newDir);
352 DeleteFile(flOrig.path);
357 DeleteFile(flNew.path);
363 void DiffDir(Array<OutputFile> outputOrig, Array<OutputFile> outputNew)
365 //char origDir[MAX_LOCATION];
366 //char newDir[MAX_LOCATION];
367 char tmpname[MAX_LOCATION];
369 CreateTemporaryDir(origDir, "TestSuiteOrigDir");
370 CreateTemporaryDir(newDir,"TestSuiteNewDir");
372 for(d : [ outputOrig, outputNew ])
376 char tmpname[MAX_LOCATION];
377 char dummybuffer[MAX_LOCATION];
378 File outputFile = of.outputFile;
382 GetLastDirectory(of.filePath, dummybuffer);
383 strcpy(tmpname, (d == outputOrig) ? origDir : newDir);
384 PathCat(tmpname, dummybuffer);
385 tmp = FileOpen(tmpname, write);
388 CopyFile(outputFile, tmp);
402 int GenerateMakefile(Test t)
404 DualPipe epj2makePipe;
405 char testFolder[MAX_LOCATION];
406 char makefileOut[MAX_LOCATION];
407 char epjName[MAX_LOCATION];
408 char * filePath = t.filePath;
410 StripLastDirectory(filePath, testFolder);
411 PathCat(testFolder, "release");
414 StripLastDirectory(filePath, testFolder);
415 GetLastDirectory(filePath, epjName);
416 strcpy(makefileOut, testFolder);
417 PathCat(makefileOut, "makefile.test");
419 // epj2makePipe = DualPipeOpenf({ output = true },"epj2make -l /usr/ecere/lib -o %s %s > /dev/null", makefileOut, t.filePath);
420 //epj2makePipe = DualPipeOpenf({ output = true },"epj2make -cpp cpp -l /usr/ecere/lib -o %s %s", makefileOut, filePath);
421 //epj2makePipe.Wait();
422 CreateMakefile(filePath, makefileOut);
425 //return epj2makePipe.GetExitCode();
429 char* Copy2Temp(File f, String tmpPath)
432 char tmpFilename[MAX_LOCATION];
433 tmp = CreateTemporaryFile(tmpFilename, tmpPath);
439 int BuildTest(TestRun run)
443 char makefileOut[MAX_LOCATION];
444 char * filePath = run.test.filePath;
445 char oldDir[MAX_LOCATION];
446 StripLastDirectory(filePath, makefileOut);
448 GetWorkingDir(oldDir, sizeof(oldDir));
449 ChangeWorkingDir(makefileOut);
450 PathCat(makefileOut, "makefile.test");
452 //Execute("make -f %s clean", makefileOut);
454 makePipe = DualPipeOpenf({ output = true },"make -f %s clean", makefileOut);
457 char makeBuffer[1024];
460 while(!makePipe.Eof())
462 count = makePipe.Read(makeBuffer,1,sizeof(makeBuffer));
463 f.Write(makeBuffer, 1, count);
469 makePipe = DualPipeOpenf({ output = true },"make -f %s", makefileOut);
472 char makeBuffer[1024];
475 while(!makePipe.Eof())
477 count = makePipe.Read(makeBuffer,1,sizeof(makeBuffer));
478 f.Write(makeBuffer, 1, count);
483 ChangeWorkingDir(oldDir);
484 makeSuccess = makePipe.GetExitCode();
485 run.makeReturnValue = makeSuccess;
488 void AddOutputFiles(TestRun run)
490 char testFolder[MAX_LOCATION];
492 char * filePath = run.test.filePath;
493 StripLastDirectory(filePath, testFolder);
494 PathCat(testFolder, "release");
496 fl = { testFolder, extensions = "c, ec, sym, imp" }; // ["c", "ec", "sym", "imp"] perhaps?
500 RowOutputFiles of { };
501 char extension[MAX_LOCATION];
502 DateTime rightNow { };
503 f = FileOpen(fl.path, read);
508 of.filePath = fl.path;
511 GetExtension(fl.path, extension);
512 if(!strcmp(extension,"c"))
516 else if(!strcmp(extension,"ec"))
520 else if(!strcmp(extension,"sym"))
524 else if(!strcmp(extension,"imp"))
528 rightNow.GetLocalTime();
529 of.created = (TimeStamp)rightNow;
536 void CopyFile(File input, File output)
539 input.Seek(0, start);
542 uint count = input.Read(buffer, 1, sizeof(buffer));
545 int yo = output.Write(buffer, 1, count);
550 class RelativeTimeStamp : TimeStamp
552 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
560 rightNow = (TimeStamp)dt;
561 count = (int64)(rightNow - (TimeStamp)this);
614 PrintBuf(tempString, 1024, "<1 minute ago");
618 PrintBuf(tempString, 1024, count, " ", units, (count > 1)? "s" : "", " ago");
627 void OnDisplay(Surface surface,
628 int x, int y, int width,
629 TrumpDialog trumpDialog,
631 DataDisplayFlags flags)
636 b = theTestSuiteWindow.makeSuccess.bitmap;
640 b = theTestSuiteWindow.makeFailure.bitmap;
642 surface.Blit(b, x, y, 0, 0, b.width, b.height);
646 class TestSuiteWindow : Window
648 text = "Ecere Compiler Tests";
649 background = activeBorder;
650 borderStyle = sizable;
655 anchor = { horz = -3, vert = 80 };
657 BitmapResource makeSuccess { ":check.png" , window = this };
658 BitmapResource makeFailure { ":x.png", window = this };
662 testListBox.AddField(fieldName);
663 testListBox.AddField(fieldActive);
665 runsListBox.AddField(fieldBuildStatus);
666 runsListBox.AddField(fieldAuraColor);
667 runsListBox.AddField(fieldRun);
668 runsListBox.AddField(fieldSaved);
669 // LoadTests(); FIXME this causes a segfault (but not OnCreate)
670 Print("starting up...\n");
673 PaneSplitter windowPanes
675 this, leftPane = testListBox, rightPane = runSection, split = 200;
679 this, anchor = { top = 0, bottom = 30, left = 0, right = 0 };
681 PaneSplitter runPanes
683 runSection, leftPane = dataBox, rightPane = runsListBox, split = 100, orientation = horizontal;
694 runsListBox.Update(null);
699 void NewTest(RowTests tRow, char* testName, char* testFilePath)
702 tRow.id = tRow.sysID;
705 tRow.filePath = testFilePath;
708 DataRow AddTest(RowTests tRow)
712 row = testListBox.AddRow();
714 s = tRow.name; row.SetData(fieldName, s); delete s;
715 row.SetData(fieldActive, tRow.active);
719 void DeleteTest(ListBox testListBox, DataRow row)
721 // do we also delete all runs and files associated with this test?
725 delete tRow; // won't be needed in the (distant?) future :-)
726 testListBox.DeleteRow(row);
734 theTestSuiteWindow.AddTest(tRow);
739 DataField fieldName { width = 140, header = "Name" , dataType = class(char*), editable = true };
740 DataField fieldActive { width = 40, header = "Active", dataType = class(bool) };
745 anchor = { top = 2, bottom = 30, left = 2, right = 2 },
748 bool NotifyChanged(ListBox testListBox, DataRow row)
752 tRow.name = row.GetData(fieldName);
753 tRow.active = row.GetData(fieldActive);
758 bool NotifyKeyDown(ListBox testListBox, DataRow row, Key key, unichar ch)
762 DeleteTest(testListBox, row);
763 // bRemove.NotifyClicked(this, bRemove,0,0,0);
765 else if(key == space)
767 //bool newActiveStatus = !(*(bool*)row.GetData(fieldActive)); // FIXME is needed?
768 row.SetData(fieldActive, !row.GetData(fieldActive));
769 testListBox.NotifyChanged(this, testListBox, row);
775 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
780 { // print to data box
789 dataBox.Printf("Name: %s\n", tname);
790 dataBox.Printf("Location: %s\n", tpath);
791 dataBox.Printf("Active: %d\n", tactive);
792 delete tname; delete tpath;
797 AccessMacros amacs{ };
799 runs = amacs.allTestRuns(t);
804 BuildStatus buildStatus;
805 TimeStamp time = tr.time;
806 MD5Digest aura = tr.digest;
807 buildStatus = tr.makeReturnValue ? failure : success;
808 row = runsListBox.AddRow();
810 row.SetData(fieldBuildStatus, buildStatus);
811 row.SetData(fieldAuraColor, aura);
812 row.SetData(fieldRun, time);
813 row.SetData(fieldSaved, tr.save);
821 DataField fieldBuildStatus { width = 40, dataType = class(BuildStatus), header = "Make" };
822 DataField fieldAuraColor { width = 40, dataType = class(MD5Digest), header = "Aura" };
823 DataField fieldRun { width = 120, dataType = class(RelativeTimeStamp), header = "Run" };
824 DataField fieldSaved { width = 80, dataType = class(bool), header = "Save", editable = true };
830 anchor = { top = 0, bottom = 0, left = 0, right = 0 },
833 bool NotifyChanged(ListBox listBox, DataRow row)
835 TestRun tr = (TestRun)row.tag;
836 tr.save = row.GetData(fieldSaved);
846 anchor = { top = 0, bottom = 0, left = 0, right = 0 },
847 hasHorzScroll = true,
857 anchor = { bottom = 2, left = 2 };
859 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
861 FileFilter projectFilters[] =
863 { "eC project and source files (.ec, .epj)", "ec, epj" }
865 FileDialog f { filters = projectFilters, sizeFilters = sizeof(projectFilters), type = multiOpen };
871 for(i=0; i<f.numSelections; ++i)
873 char testName[MAX_LOCATION];
875 GetLastDirectory(f.multiFilePaths[i], testName);
876 NewTest(tRow, testName, f.multiFilePaths[i]);
878 if(i+1 == f.numSelections)
880 testListBox.SelectRow(row);
894 anchor = { bottom = 2, right = 2 };
896 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
899 for(row=testListBox.firstRow; row; row=row.next)
901 Test t = (Test)row.tag;
910 DateTime rightNow { };
914 runs.id = runs.sysID;
915 rightNow.GetLocalTime();
916 runs.time = (TimeStamp)rightNow;
919 bt.GenerateMakefile(t);
921 bt.AddOutputFiles(run);
930 Array<OutputFile> outputsLatest = AccessMacros::allOutputFiles(run);
931 Array<OutputFile> outputsReference = AccessMacros::allOutputFiles(t.reference);
932 dt.DiffDir(outputsReference, outputsLatest);
935 testListBox.NotifySelect(this, testListBox, testListBox.currentRow, mods);
943 text = "Accept Run (x)",
945 anchor={ bottom = 2, right = 52 };
947 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
950 MessageBox confirmation
953 text = "Accept Test",
954 contents = "Accept the selected test?"
956 if(confirmation.Modal() == yes)
959 row = runsListBox.currentRow;
962 tr = (TestRun)row.tag;
964 tr.test.reference = tr;
972 globalSettings.Load();
975 delete theGlobalSettings.diffTool;
976 theGlobalSettings.diffTool = CopyString("meld");
977 // theGlobalSettings.diffTool = CopyString("C:/Program Files/Araxis/Araxis Merge v6.5/compare.exe /wait");
982 TestSuiteWindow theTestSuiteWindow { };
983 TestSuiteGlobalSettings theGlobalSettings { };