test/examples-test.js
const fs = require("fs");
const should = require("should");
const sinon = require("sinon");
const { Parser } = require("../lib/parser/parse.js");
const { Eggvm } = require("../lib/interp/eggvm.js");
const parser = new Parser();
describe("Testing programs from 'examples/' folder", () => {
// Spy calls to 'console.log'
beforeEach(() => {
this.logSpy = sinon.spy(console, "log");
});
afterEach(() => {
this.logSpy.restore();
});
// Method to test the number and values of 'logSpy' calls
const assertOutput = outs => {
this.logSpy.callCount.should.be.eql(outs.length);
outs.forEach((output, index) => {
this.logSpy
.getCall(index)
.calledWithExactly(output)
.should.be.true();
});
};
// Method for creating and executing the dynamic tests
const executeTests = tests => {
tests.forEach((outputs, file) => {
// Path to the related .evm file
const fileEVM = file + ".evm";
describe(`Test for ${file}`, () => {
// -- TEST PARSING --
it("should be parsed correctly", () => {
const rawData = fs.readFileSync(fileEVM);
const expectedTree = JSON.parse(rawData);
parser.parseFromFile(file).should.match(expectedTree);
});
// -- TEST EXECUTION --
if (Array.isArray(outputs)) {
it("should print the expected output after execution", () => {
// Eggvm.runFromEVM(fileEVM);
Eggvm.runFromEVM(fileEVM);
assertOutput(outputs);
});
} else {
it(`should throw an exception of type ${outputs.name}`, () => {
should.throws(() => {
Eggvm.runFromFile(file);
}, outputs);
});
}
});
});
};
// Define tests
const tests = new Map();
tests.set("examples/one.egg", [50]);
tests.set("examples/two.egg", [9]);
tests.set("examples/scope.egg", [9, 8]);
tests.set("examples/scope-err.egg", ReferenceError);
tests.set("examples/boolean.egg", ["true"]);
tests.set("examples/string.egg", ["s"]);
tests.set("examples/sum.egg", [395.5]);
tests.set("examples/reto.egg", ["sum(array[1, 2, 3]) := 6"]);
tests.set("examples/array.egg", [[1, 4], 5]);
tests.set("examples/array-index.egg", [1, [2, 3], 3, 3, 2]);
tests.set("examples/array-properties.egg", [1, [5, 3], 3]);
tests.set("examples/set-error.egg", TypeError);
tests.set("examples/set-error2.egg", TypeError);
tests.set("examples/method3.egg", ["A-B-C"]);
tests.set("examples/method-concatenation.egg", ["1-hello egg"]);
tests.set("examples/property.egg", [2, 3]);
tests.set("examples/string-apply.egg", [5, "4.00", 19]);
tests.set("examples/operators-arithm.egg", [6, 5, 10, -5, 0, -10]);
tests.set("examples/map.egg", [
new Map([["x", 4], ["y", new Map([["z", 3]])]]),
4,
new Map([["z", 3]]),
3,
new Map([["z", 50]])
]);
tests.set("examples/map-colon.egg", [
new Map([["x", 4], ["y", new Map([["z", 3]])]]),
4,
new Map([["z", 3]]),
3,
new Map([["z", 50]])
]);
tests.set("examples/multi-sub-set.egg", [
1,
new Map([["x", 2], ["y", [3, 4]]]),
[3, 4],
new Map([["x", 2], ["y", 5]]),
[0, 1]
]);
tests.set("examples/map-sub.egg", [1, new Map([["d", 5], ["e", 3]]), 3]);
tests.set("examples/fun-inside-map.egg", [7, 4]);
tests.set("examples/missing.egg", [9]);
tests.set("examples/missing-err.egg", SyntaxError);
tests.set("examples/objects.egg", [0, 4, 5]);
tests.set("examples/regex.egg", [true, 0, "2015", "02"]);
tests.set("examples/dot.egg", ["1-4-5", 5]);
tests.set("examples/dot-obj-2.egg", [0, 0, 0, 5, 5, 5]);
tests.set("examples/dot-num.egg", ["4.00", "4.00", "4.00"]);
tests.set("examples/for.egg", [0, 1, 2, 3, 4]);
tests.set("examples/foreach.egg", [1, 2, 3, "A", "B", "C"]);
tests.set("examples/client.egg", ["inside module", 5, 5, 3]);
tests.set("examples/ects-context.egg", [0, 4, 5]);
tests.set("examples/child.egg", [5, 5, 5]);
tests.set("examples/trycatch.egg", ["Caught error! 42", 20, "Finally called"]);
tests.set("examples/trycatch-2.egg", [
"Inner catch. Rethrowing...",
"Outer catch. 42"
]);
// Execute all the defined tests
executeTests(tests);
});