Selaa lähdekoodia

a new grammar is test ready

Vladislav Folts 11 vuotta sitten
vanhempi
commit
cc07bf2cb5
5 muutettua tiedostoa jossa 571 lisäystä ja 493 poistoa
  1. 0 1
      src/grammar.js
  2. 22 2
      test/test.js
  3. 351 490
      test/test_unit.js
  4. 178 0
      test/test_unit_common.js
  5. 20 0
      test/test_unit_eberon.js

+ 0 - 1
src/grammar.js

@@ -159,7 +159,6 @@ var typeDeclaration = context(and(identdef, "=", strucType), Context.TypeDeclara
 var procedureHeading = and("PROCEDURE"
                          , identdef
                          , context(optional(formalParameters), Context.FormalParametersProcDecl));
-var grammar;
 
 exports.makeProcedureDeclaration = function(procedureBody){
     return context(and(procedureHeading, ";",

+ 22 - 2
test/test.js

@@ -1,3 +1,5 @@
+"use strict";
+
 function TestError(s) {this.__s = s;}
 TestError.prototype.toString = function(){return this.__s;};
 
@@ -41,8 +43,26 @@ function run(tests){
 
     console.log("Running..." );
     var start = (new Date()).getTime();
-    if (typeof process != "undefined" && process.argv.length > 2)
-        runTest(process.argv[2], tests, stat, "");
+    if (typeof process != "undefined" && process.argv.length > 2){
+        var testName = process.argv[2];
+        while (!tests[testName]){
+            var dotPos = testName.indexOf(".");
+            if (dotPos == -1){
+                console.log("test '" + testName + "' not found");
+                return;
+            }
+
+            var suite = testName.substr(0, dotPos);
+            tests = tests[suite];
+            if (!tests){
+                console.log("suite '" + suite + "' not found");
+                return;
+            }
+            
+            testName = testName.substr(dotPos + 1);
+        }
+        runTest(testName, tests, stat, "");
+    }
     else
         runImpl(tests, stat, "");
     var stop = (new Date()).getTime();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 351 - 490
test/test_unit.js


+ 178 - 0
test/test_unit_common.js

@@ -0,0 +1,178 @@
+"use strict";
+
+var Class = require("rtl.js").Class;
+var Code = require("code.js");
+var Context = require("context.js");
+var Errors = require("js/Errors.js");
+var oc = require("oc.js");
+var RTL = require("rtl_code.js").RTL;
+var Scope = require("scope.js");
+var Stream = require("Stream.js");
+var Test = require("test.js");
+
+var TestError = Test.TestError;
+
+function context(grammar, source){
+    return {grammar: grammar, source: source};
+}
+
+function pass(/*...*/){return Array.prototype.slice.call(arguments);}
+
+function fail(/*...*/){return Array.prototype.slice.call(arguments);}
+
+var TestModuleGenerator = Class.extend({
+    init: function TestModuleGenerator(){},
+    prolog: function(){return undefined;},
+    epilog: function(){return undefined;}
+});
+
+var TestContext = Context.Context.extend({
+    init: function TestContext(){
+        Context.Context.prototype.init.call(
+                this,
+                Code.nullGenerator,
+                function(){return new TestModuleGenerator();},
+                new RTL());
+        this.pushScope(new Scope.Module("test"));
+    },
+    qualifyScope: function(){return "";}
+});
+
+function makeContext(){return new TestContext();}
+
+function testWithSetup(setup, pass, fail){
+    return function(){
+        var test = setup();
+        var i;
+        for(i = 0; i < pass.length; ++i)
+            test.expectOK(pass[i]);
+    
+        if (fail)
+            for(i = 0; i < fail.length; ++i){
+                var f = fail[i];
+                test.expectError(f[0], f[1]);
+            }
+    };
+}
+
+function parseInContext(grammar, s, context){
+    var stream = Stream.make(s);
+    if (!grammar(stream, context) || !Stream.eof(stream))
+        throw new Errors.Error("not parsed");
+}
+
+function runAndHandleErrors(action, s, handlerError){
+    try {
+        action(s);
+    }
+    catch (x){
+        if (!(x instanceof Errors.Error))
+            throw new Error("'" + s + "': " + x + "\n" 
+                            + (x.stack ? x.stack : "(no stack)"));
+        
+        if (handlerError)
+            handlerError(x);
+        //else
+        //  throw x;
+        //  console.log(s + ": " + x);
+        return false;
+    }
+    return true;
+}
+
+function setup(run){
+    return {
+        expectOK: function(s){
+            function handleError(e){throw new TestError(s + "\n\t" + e);}
+
+            if (!runAndHandleErrors(run, s, handleError))
+                throw new TestError(s + ": not parsed");
+        },
+        expectError: function(s, error){
+            function handleError(actualError){
+                var sErr = actualError.toString();
+                if (sErr != error)
+                    throw new TestError(s + "\n\texpected error: " + error + "\n\tgot: " + sErr );
+            }
+
+            if (runAndHandleErrors(run, s, handleError))
+                throw new TestError(s + ": should not be parsed, expect error: " + error);
+        }
+    };
+}
+
+function parseUsingGrammar(grammar, s, cxFactory){
+    var baseContext = makeContext();
+    var context = cxFactory ? cxFactory(baseContext) : baseContext;
+    parseInContext(grammar, s, context);
+}
+
+function setupParser(parser, contextFactory){
+    function parseImpl(s){
+        return parseUsingGrammar(parser, s, contextFactory);
+    }
+    return setup(parseImpl);
+}
+
+function setupWithContext(grammar, contextGrammar, source){
+    function innerMakeContext(){
+        var context = makeContext();
+        try {
+            parseInContext(contextGrammar, source, context);
+        }
+        catch (x) {
+            if (x instanceof Errors.Error)
+                throw new TestError("setup error: " + x + "\n" + source);
+            throw x;
+        }
+        return context;
+    }
+
+    return setupParser(grammar, innerMakeContext);
+}
+
+function testWithContext(context, contextGrammar, pass, fail){
+    return testWithSetup(
+        function(){return setupWithContext(context.grammar, contextGrammar, context.source);},
+        pass,
+        fail);
+}
+
+function testWithGrammar(grammar, pass, fail){
+    return testWithSetup(
+        function(){return setupParser(grammar);},
+        pass,
+        fail);
+}
+
+var TestContextWithModule = TestContext.extend({
+    init: function(module){
+        TestContext.prototype.init.call(this);
+        this.__module = module;
+    },
+    findModule: function(){return this.__module;}
+});
+
+function testWithModule(src, grammar, pass, fail){
+    return testWithSetup(
+        function(){
+            var imported = oc.compileModule(grammar, Stream.make(src), makeContext());
+            var module = imported.symbol().info();
+            return setup(function(s){
+                oc.compileModule(grammar,
+                                 Stream.make(s),
+                                 new TestContextWithModule(module));
+            });},
+        pass,
+        fail);
+}
+
+exports.context = context;
+exports.pass = pass;
+exports.fail = fail;
+exports.makeContext = makeContext;
+exports.setupParser = setupParser;
+exports.testWithContext = testWithContext;
+exports.testWithGrammar = testWithGrammar;
+exports.testWithModule = testWithModule;
+exports.testWithSetup = testWithSetup;

+ 20 - 0
test/test_unit_eberon.js

@@ -0,0 +1,20 @@
+"use strict";
+
+var grammar = require("eberon/eberon_grammar.js").grammar;
+var TestUnitCommon = require("test_unit_common.js");
+
+var pass = TestUnitCommon.pass;
+var fail = TestUnitCommon.fail;
+var context = TestUnitCommon.context;
+
+function testWithContext(context, pass, fail){
+    return TestUnitCommon.testWithContext(context, grammar.declarationSequence, pass, fail);
+}
+
+exports.suite = {
+"new method declaration": testWithContext(
+    context(grammar.declarationSequence, "TYPE T = RECORD END;"),
+    pass("PROCEDURE T.p(), NEW; END T.p;"),
+    fail()
+    )
+};

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä