test_compile.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. "use strict";
  2. var nodejs = require("nodejs.js");
  3. var oc = require("oc");
  4. var oberon = require("oberon/oberon_grammar.js").language;
  5. var eberon = require("eberon/eberon_grammar.js").language;
  6. var fs = require("fs");
  7. var path = require("path");
  8. var Test = require("test.js");
  9. function normalizeLineEndings(text){
  10. return text.replace(/\r\n/g, '\n')
  11. .replace(/\s+$/,''); // ending spaces
  12. }
  13. function filterOutRtlCode(text){
  14. var prefix = "var RTL$ = {";
  15. if (text.substr(0, prefix.length) != prefix)
  16. return text;
  17. var suffix = "\n};";
  18. var end = text.indexOf(suffix);
  19. if (end == -1)
  20. return text;
  21. return "<rtl code>" + text.substr(end + suffix.length);
  22. }
  23. function compareResults(result, name, dirs){
  24. result = filterOutRtlCode(result);
  25. fs.writeFileSync(path.join(dirs.output, name), result);
  26. var expected = fs.readFileSync(path.join(dirs.expected, name), "utf8");
  27. if (normalizeLineEndings(result) != normalizeLineEndings(expected))
  28. throw new Test.TestError("Failed");
  29. }
  30. function compile(src, language){
  31. var text = fs.readFileSync(src, "utf8");
  32. var errors = "";
  33. var result = oc.compile(text, language, function(e){errors += e;});
  34. if (errors)
  35. throw new Test.TestError(errors);
  36. return result;
  37. }
  38. function compileNodejs(src, dirs, language){
  39. language.rtl.nodejsModule = "test_rtl.js"; // make test results the same for oberon/eberon
  40. var subdir = path.basename(src);
  41. subdir = subdir.substr(0, subdir.length - path.extname(subdir).length);
  42. var outDir = path.join(dirs.output, subdir);
  43. fs.mkdirSync(outDir);
  44. var errors = "";
  45. nodejs.compile([src], language, function(e){errors += e;}, [], outDir);
  46. if (errors)
  47. throw new Test.TestError(errors);
  48. cmpDirs(path.join(dirs.expected, subdir), outDir);
  49. }
  50. function expectOk(src, dirs, grammar){
  51. var result = compile(src, grammar);
  52. var resultName = path.basename(src).replace(".ob", ".js");
  53. compareResults(result, resultName, dirs);
  54. }
  55. function expectError(src, dirs, language){
  56. var text = fs.readFileSync(src, "utf8");
  57. var errors = "";
  58. try {
  59. oc.compile(text, language, function(e){errors += e + "\n";});
  60. }
  61. catch (e){
  62. errors += e;
  63. }
  64. if (!errors.length)
  65. throw new Test.TestError("compiler error expected");
  66. var resultName = path.basename(src).replace(".ob", ".txt");
  67. compareResults(errors, resultName, dirs);
  68. }
  69. function run(src, dirs, language){
  70. var result = compile(src, language);
  71. var resultName = path.basename(src).replace(".ob", ".js");
  72. var resultPath = path.join(dirs.output, resultName);
  73. fs.writeFileSync(resultPath, result);
  74. require(resultPath);
  75. }
  76. function makeTest(test, src, dirs, grammar){
  77. return function(){test(src, dirs, grammar);};
  78. }
  79. function makeTests(test, dirs, grammar){
  80. var output = dirs.output;
  81. if (fs.existsSync(output))
  82. rmTree(output);
  83. fs.mkdirSync(output);
  84. var sources = fs.readdirSync(dirs.input);
  85. var tests = {};
  86. for(var i = 0; i < sources.length; ++i){
  87. var source = sources[i];
  88. var filePath = path.join(dirs.input, source);
  89. if (fs.statSync(filePath).isFile())
  90. tests[source] = makeTest(test, filePath, dirs, grammar);
  91. }
  92. return tests;
  93. }
  94. function rmTree(root){
  95. fs.readdirSync(root).forEach(function(file){
  96. var filePath = path.join(root, file);
  97. if (fs.statSync(filePath).isDirectory())
  98. rmTree(filePath);
  99. else
  100. fs.unlinkSync(filePath);
  101. });
  102. fs.rmdirSync(root);
  103. }
  104. function cmpDirs(expected, result){
  105. fs.readdirSync(expected).forEach(function(file){
  106. var expectedFile = path.join(expected, file);
  107. var resultFile = path.join(result, file);
  108. var expectedContent = fs.readFileSync(expectedFile, "utf8");
  109. var resultContent = fs.readFileSync(resultFile, "utf8");
  110. if ( normalizeLineEndings(expectedContent)
  111. != normalizeLineEndings(resultContent))
  112. throw new Test.TestError(
  113. "Files '" + expectedFile + "' and '"
  114. + resultFile + "' do not match.");
  115. });
  116. }
  117. var testDirs = {input: "input", output: "output", expected: "expected"};
  118. function makeTestDirs(subdir){
  119. if (!subdir)
  120. return testDirs;
  121. var result = {};
  122. for(var p in testDirs)
  123. result[p] = path.join(testDirs[p], subdir);
  124. return result;
  125. }
  126. function outputSubdir(dirs, subdir){
  127. var result = {};
  128. for(var p in dirs)
  129. result[p] = (p == "output") ? path.join(dirs[p], subdir) : dirs[p];
  130. return result;
  131. }
  132. function main(){
  133. var okDirs = makeTestDirs();
  134. var errDirs = makeTestDirs("errors");
  135. var runDirs = makeTestDirs("run");
  136. var nodejsDirs = makeTestDirs("nodejs");
  137. var oberonDirs = makeTestDirs("oberon");
  138. var eberonDirs = makeTestDirs("eberon");
  139. var eberonRunDirs = makeTestDirs("eberon/run");
  140. var eberonErrDirs = makeTestDirs("eberon/errors");
  141. function makeCommonTests(language, subdir){
  142. return {
  143. "expect OK": makeTests(expectOk, outputSubdir(okDirs, subdir), language),
  144. "expect compile error": makeTests(expectError, outputSubdir(errDirs, subdir), language),
  145. "run": makeTests(run, outputSubdir(runDirs, subdir), language),
  146. "nodejs": makeTests(compileNodejs, outputSubdir(nodejsDirs, subdir), language)
  147. };
  148. }
  149. var result =
  150. Test.run({"common": {"oberon": makeCommonTests(oberon, "oberon"),
  151. "eberon": makeCommonTests(eberon, "eberon")
  152. },
  153. "oberon": {"expect OK": makeTests(expectOk, oberonDirs, oberon)},
  154. "eberon": {"expect OK": makeTests(expectOk, eberonDirs, eberon),
  155. "run": makeTests(run, eberonRunDirs, eberon),
  156. "expect compile error": makeTests(expectError, eberonErrDirs, eberon)
  157. }
  158. });
  159. return result ? 0 : -1;
  160. }
  161. process.exit(main());