2
0

test_unit_common.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. "use strict";
  2. var Class = require("rtl.js").Class;
  3. var Code = require("js/Code.js");
  4. var Context = require("context.js");
  5. var Errors = require("js/Errors.js");
  6. var oc = require("oc.js");
  7. var RTL = require("rtl_code.js").RTL;
  8. var Scope = require("js/Scope.js");
  9. var Stream = require("js/Stream.js");
  10. var Test = require("test.js");
  11. var TestError = Test.TestError;
  12. function context(grammar, source){
  13. return {grammar: grammar, source: source};
  14. }
  15. function pass(/*...*/){return Array.prototype.slice.call(arguments);}
  16. function fail(/*...*/){return Array.prototype.slice.call(arguments);}
  17. var TestModuleGenerator = Class.extend({
  18. init: function TestModuleGenerator(){},
  19. prolog: function(){return undefined;},
  20. epilog: function(){return undefined;}
  21. });
  22. var TestContext = Context.Context.extend({
  23. init: function TestContext(language){
  24. Context.Context.prototype.init.call(
  25. this,
  26. { codeGenerator: language.codeGenerator.nil,
  27. moduleGenerator: function(){return new TestModuleGenerator();},
  28. rtl: new RTL(),
  29. types: language.types,
  30. stdSymbols: language.stdSymbols
  31. });
  32. this.pushScope(new Scope.Module("test", language.stdSymbols));
  33. },
  34. qualifyScope: function(){return "";},
  35. handleMessage: function(){}
  36. });
  37. function makeContext(language){return new TestContext(language);}
  38. function testWithSetup(setup, pass, fail){
  39. return function(){
  40. var test = setup();
  41. var i;
  42. for(i = 0; i < pass.length; ++i)
  43. test.expectOK(pass[i]);
  44. if (fail)
  45. for(i = 0; i < fail.length; ++i){
  46. var f = fail[i];
  47. test.expectError(f[0], f[1]);
  48. }
  49. };
  50. }
  51. function parseInContext(grammar, s, context){
  52. var stream = new Stream.Type(s);
  53. if (!grammar(stream, context) || !Stream.eof(stream))
  54. throw new Errors.Error("not parsed");
  55. }
  56. function runAndHandleErrors(action, s, handlerError){
  57. try {
  58. action(s);
  59. }
  60. catch (x){
  61. if (!(x instanceof Errors.Error))
  62. throw new Error("'" + s + "': " + x + "\n"
  63. + (x.stack ? x.stack : "(no stack)"));
  64. if (handlerError)
  65. handlerError(x);
  66. //else
  67. // throw x;
  68. // console.log(s + ": " + x);
  69. return false;
  70. }
  71. return true;
  72. }
  73. function setup(run){
  74. return {
  75. expectOK: function(s){
  76. function handleError(e){throw new TestError(s + "\n\t" + e);}
  77. if (!runAndHandleErrors(run, s, handleError))
  78. throw new TestError(s + ": not parsed");
  79. },
  80. expectError: function(s, error){
  81. function handleError(actualError){
  82. var sErr = actualError.toString();
  83. if (sErr != error)
  84. throw new TestError(s + "\n\texpected error: " + error + "\n\tgot: " + sErr );
  85. }
  86. if (runAndHandleErrors(run, s, handleError))
  87. throw new TestError(s + ": should not be parsed, expect error: " + error);
  88. }
  89. };
  90. }
  91. function parseUsingGrammar(parser, language, s, cxFactory){
  92. var baseContext = makeContext(language);
  93. var context = cxFactory ? cxFactory(baseContext) : baseContext;
  94. parseInContext(parser, s, context);
  95. context.currentScope().close();
  96. }
  97. function setupParser(parser, language, contextFactory){
  98. function parseImpl(s){
  99. return parseUsingGrammar(parser, language, s, contextFactory);
  100. }
  101. return setup(parseImpl);
  102. }
  103. function setupWithContext(grammar, contextGrammar, language, source){
  104. function innerMakeContext(){
  105. var context = makeContext(language);
  106. try {
  107. parseInContext(contextGrammar, source, context);
  108. }
  109. catch (x) {
  110. if (x instanceof Errors.Error)
  111. throw new TestError("setup error: " + x + "\n" + source);
  112. throw x;
  113. }
  114. return context;
  115. }
  116. return setupParser(grammar, language, innerMakeContext);
  117. }
  118. function testWithContext(context, contextGrammar, language, pass, fail){
  119. return testWithSetup(
  120. function(){return setupWithContext(context.grammar, contextGrammar, language, context.source);},
  121. pass,
  122. fail);
  123. }
  124. function testWithGrammar(parser, language, pass, fail){
  125. return testWithSetup(
  126. function(){return setupParser(parser, language);},
  127. pass,
  128. fail);
  129. }
  130. var TestContextWithModule = TestContext.extend({
  131. init: function(module, language){
  132. TestContext.prototype.init.call(this, language);
  133. this.__module = module;
  134. },
  135. findModule: function(){return this.__module;}
  136. });
  137. function testWithModule(src, language, pass, fail){
  138. var grammar = language.grammar;
  139. return testWithSetup(
  140. function(){
  141. var imported = oc.compileModule(grammar, new Stream.Type(src), makeContext(language));
  142. var module = imported.symbol().info();
  143. return setup(function(s){
  144. oc.compileModule(grammar,
  145. new Stream.Type(s),
  146. new TestContextWithModule(module, language));
  147. });},
  148. pass,
  149. fail);
  150. }
  151. function nthLine(s, n){
  152. var result = 0;
  153. while (n--)
  154. result = s.indexOf('\n', result) + 1;
  155. return result;
  156. }
  157. function assert(cond){
  158. if (!cond){
  159. var stack = new Error().stack;
  160. var from = nthLine(stack, 2);
  161. stack = stack.substring(from, stack.indexOf('\n', from));
  162. throw new TestError("assertion failed: " + stack);
  163. }
  164. }
  165. exports.assert = assert;
  166. exports.context = context;
  167. exports.pass = pass;
  168. exports.fail = fail;
  169. exports.setupParser = setupParser;
  170. exports.testWithContext = testWithContext;
  171. exports.testWithGrammar = testWithGrammar;
  172. exports.testWithModule = testWithModule;
  173. exports.testWithSetup = testWithSetup;