PCTest.Mod 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. MODULE PCTest; (** AUTHOR "negelef"; PURPOSE "PaCo tester"; *)
  2. IMPORT TestSuite, Diagnostics, Streams, PCS, PC, Commands, Modules,
  3. Strings, CompilerInterface, Texts, TextUtilities, Files;
  4. TYPE
  5. Tester = OBJECT (TestSuite.Tester)
  6. VAR
  7. log: Streams.Writer;
  8. execute: BOOLEAN;
  9. options: ARRAY 100 OF CHAR;
  10. PROCEDURE &InitTester *(log: Streams.Writer; diagnostics: Diagnostics.Diagnostics; execute: BOOLEAN; CONST options: ARRAY OF CHAR);
  11. BEGIN Init (diagnostics); SELF.log := log; SELF.execute := execute; COPY (options, SELF.options);
  12. END InitTester;
  13. PROCEDURE Handle* (r: Streams.Reader; pos: LONGINT; CONST name: ARRAY OF CHAR; type: TestSuite.TestType): INTEGER;
  14. CONST ModuleName = "Test";
  15. VAR result: INTEGER; error: BOOLEAN; msg: ARRAY 128 OF CHAR; res: WORD;
  16. BEGIN
  17. result := TestSuite.Failure;
  18. log.String ("testing: "); log.String (name); log.Ln;
  19. PC.Module (PCS.InitWithReader (r, 1000, pos), name, options, -1, log, diagnostics, error);
  20. IF ~error THEN
  21. IF execute THEN
  22. Modules.FreeModule (ModuleName, res, msg);
  23. result := TestSuite.Negative;
  24. IF Modules.ThisModule (ModuleName, res, msg) # NIL THEN END;
  25. END;
  26. result := TestSuite.Positive;
  27. ELSIF ~execute THEN
  28. result := TestSuite.Negative;
  29. END;
  30. FINALLY
  31. RETURN result;
  32. END Handle;
  33. END Tester;
  34. PROCEDURE DriveTest (context: Commands.Context; execute: BOOLEAN);
  35. VAR diagnostics: Diagnostics.StreamDiagnostics; tester: Tester; report: TestSuite.StreamReport;
  36. BEGIN
  37. NEW (diagnostics, context.out);
  38. NEW (tester, context.out, diagnostics, execute, "\s");
  39. NEW (report, context.out);
  40. TestSuite.Drive (context, tester);
  41. tester.Print (report);
  42. END DriveTest;
  43. PROCEDURE Compile* (context: Commands.Context);
  44. BEGIN DriveTest (context, FALSE);
  45. END Compile;
  46. PROCEDURE Execute* (context: Commands.Context);
  47. BEGIN DriveTest (context, TRUE);
  48. END Execute;
  49. (* Interface with PET *)
  50. PROCEDURE DriveTextTests(
  51. reader: Streams.Reader;
  52. CONST regrfile: ARRAY OF CHAR;
  53. execute: BOOLEAN;
  54. log: Streams.Writer;
  55. diagnostics: Diagnostics.Diagnostics);
  56. VAR
  57. tester: Tester; report: TestSuite.StreamReport;
  58. BEGIN
  59. NEW(tester, log, diagnostics, execute, "\s");
  60. NEW(report, log);
  61. IF TestSuite.DriveByReader(reader, log, regrfile, tester) THEN
  62. tester.Print(report);
  63. END;
  64. END DriveTextTests;
  65. PROCEDURE ParseTests(
  66. text : Texts.Text;
  67. CONST source: ARRAY OF CHAR;
  68. VAR regrfile: ARRAY OF CHAR;
  69. VAR r: Streams.Reader;
  70. diagnostics: Diagnostics.Diagnostics): BOOLEAN;
  71. VAR
  72. buffer : POINTER TO ARRAY OF CHAR;
  73. length, pos1, pos2: SIZE;
  74. regrbuf: ARRAY Files.PrefixLength+Files.NameLength+20 OF CHAR;
  75. reader: Streams.StringReader;
  76. BEGIN
  77. regrfile := "";
  78. ASSERT((text # NIL) & (diagnostics # NIL));
  79. text.AcquireRead;
  80. length := text.GetLength();
  81. text.ReleaseRead;
  82. IF length = 0 THEN length := 1 END;
  83. NEW(buffer, length);
  84. TextUtilities.TextToStr(text, buffer^);
  85. (* prepare the reader *)
  86. NEW(reader, LEN(buffer)); reader.SetRaw(buffer^, 0, LEN(buffer));
  87. r := reader;
  88. (* Determine the regression test file *)
  89. pos1 := 0; pos2 := -1;
  90. pos1 := Strings.Find(buffer^, 0, "$");
  91. IF pos1 # -1 THEN
  92. INC(pos1);
  93. pos2 := Strings.Find(buffer^, pos1, "$");
  94. END;
  95. NEW(reader, LEN(regrbuf));
  96. WHILE (pos2 # -1) & (regrfile = "") DO
  97. reader.SetRaw(buffer^, LONGINT(pos1), LONGINT(pos2-pos1)); (* TODO *)
  98. reader.SkipWhitespace; reader.String(regrbuf);
  99. Strings.LowerCase(regrbuf);
  100. IF Strings.StartsWith2("regression", regrbuf) THEN
  101. reader.SkipWhitespace; reader.String(regrfile);
  102. END;
  103. (* prepare for next iteration *)
  104. pos1 := pos2;
  105. INC(pos1);
  106. pos2 := Strings.Find(buffer^, pos1, "$");
  107. END;
  108. ASSERT(r.Pos() = 0);
  109. RETURN TRUE; (* no checks yet *)
  110. END ParseTests;
  111. PROCEDURE ParseOptions(
  112. CONST options: ARRAY OF CHAR;
  113. VAR execute, regression: BOOLEAN;
  114. CONST regrfile: ARRAY OF CHAR);
  115. VAR
  116. r: Streams.StringReader;
  117. opt: ARRAY 20 OF CHAR;
  118. BEGIN
  119. (* Default values *)
  120. execute := FALSE;
  121. regression := FALSE;
  122. NEW(r, LEN(options));
  123. r.SetRaw(options, 0, LEN(options));
  124. WHILE r.res = Streams.Ok DO
  125. r.SkipWhitespace; r.String(opt);
  126. IF opt = "\e" THEN execute := TRUE;
  127. ELSIF opt = "\r" THEN regression := TRUE;
  128. END;
  129. END;
  130. END ParseOptions;
  131. PROCEDURE RunTests(
  132. text : Texts.Text;
  133. CONST source: ARRAY OF CHAR;
  134. pos: LONGINT; (* ignore *)
  135. CONST pc,opt: ARRAY OF CHAR;
  136. log: Streams.Writer; diagnostics : Diagnostics.Diagnostics; VAR error: BOOLEAN);
  137. VAR
  138. execute, regression: BOOLEAN;
  139. regrfile: Files.FileName;
  140. reader: Streams.Reader;
  141. BEGIN
  142. ASSERT((text # NIL) & (diagnostics # NIL));
  143. error := ~ParseTests(text, source, regrfile, reader, diagnostics);
  144. IF ~error THEN
  145. ParseOptions(opt, execute, regression, regrfile);
  146. IF ~regression THEN
  147. regrfile := "";
  148. END;
  149. DriveTextTests(reader, regrfile, execute, log, diagnostics);
  150. END;
  151. IF error THEN
  152. log.String(" not done");
  153. ELSE
  154. log.String(" done");
  155. END;
  156. IF (regrfile = "") & regression THEN
  157. log.Ln; log.Ln;
  158. log.String("Warning: Couldn't do regression because there was no file specified!"); log.Ln;
  159. log.String("Put somewhere in the test file a line like '# $Regression: regressionFileName$'"); log.Ln;
  160. END;
  161. log.Update;
  162. END RunTests;
  163. PROCEDURE Cleanup;
  164. BEGIN
  165. CompilerInterface.Unregister("TestTool");
  166. END Cleanup;
  167. BEGIN
  168. CompilerInterface.Register("TestTool", "Run test cases against PC compiler", "Test", RunTests);
  169. Modules.InstallTermHandler(Cleanup);
  170. END PCTest.
  171. System.Free PCTest TestSuite~
  172. WMUtilities.Call PCTest.Compile Oberon.Compilation.Test ~ Verbose testing mode
  173. WMUtilities.Call PCTest.Compile Oberon.Compilation.Test Oberon.Compilation.tmp ~ Regression testing mode
  174. WMUtilities.Call PCTest.Execute Oberon.Execution.Test ~ Verbose testing mode
  175. WMUtilities.Call PCTest.Execute Oberon.Execution.Test Oberon.Execution.tmp ~ Regression testing mode