diff options
author | Thomas Schmid <schmid-thomas@gmx.net> | 2020-05-25 01:55:24 +0300 |
---|---|---|
committer | Thomas Schmid <schmid-thomas@gmx.net> | 2020-05-25 01:55:24 +0300 |
commit | 8b82f53df8d2ac513aa9d908ac3d4258cd8b2f8d (patch) | |
tree | ddae52c345bcbdbf33c6f5c65df9a0bc7ab98288 /tests | |
parent | 2e6ad5a701a7dd162c904c80327a469581c74484 (diff) |
merge
Diffstat (limited to 'tests')
-rw-r--r-- | tests/js/AbstractTestSuite.js | 11 | ||||
-rw-r--r-- | tests/js/NodeSuite.js | 174 | ||||
-rw-r--r-- | tests/js/NodeUnit.js | 134 |
3 files changed, 319 insertions, 0 deletions
diff --git a/tests/js/AbstractTestSuite.js b/tests/js/AbstractTestSuite.js new file mode 100644 index 00000000..9d465f35 --- /dev/null +++ b/tests/js/AbstractTestSuite.js @@ -0,0 +1,11 @@ +(function (exports) { + + "use strict"; + + class AbstractTestSuite { + + } + + exports.AbstractTestSuite = AbstractTestSuite; + +})(module.exports || this); diff --git a/tests/js/NodeSuite.js b/tests/js/NodeSuite.js new file mode 100644 index 00000000..9e2a7e66 --- /dev/null +++ b/tests/js/NodeSuite.js @@ -0,0 +1,174 @@ +// Create the namespace... + +// Our server is implemented within an anonymous method... + +(function (exports) { + + "use strict"; + + const {existsSync} = require('fs'); + const { readFile } = require('fs').promises; + const path = require("path"); + + const { AbstractTestSuite } = require("./AbstractTestSuite.js"); + + class NodeTestSuite { + + /** + * Turns tracing on or off + */ + trace() { + } + + async run(tests) { + const queue = []; + this.tests = tests; + + for (const [name, value] of this.tests.entries()) { + + if (typeof (value) === "undefined") + continue; + + if (value.disabled) + continue; + + if (!value.script) + continue; + + queue.push(name); + } + + while (queue.length) { + await this.runTest(queue.shift()); + } + } + + startLog(test) { + console.log("\x1b[34mStarting Test"); + } + + logTrace(message) { + this.log(message, "Trace"); + }; + + logError(message) { + this.log(message, "Error"); + }; + + log(message, style) { + console.log(`${style} ${message}`); + } + + extend(name) { + + const base = this.tests.get(name); + + if (!base) + return []; + + let scripts = []; + if (base.extend) + scripts = this.extend(base.extend); + + if (!base.require) + return scripts; + + for (const item of base.require) { + scripts.push(item); + } + + return scripts; + } + + /** + * Checks it this test can be run in the given environment. + * Browser implementations are similar but not identical. + * Especially node diverges a lot from browsers. + * + * @param {string} name + * the unique test name + * + * @returns {boolean} + * the in case this test is compatible whit this runtime otherwise false. + */ + isCompatible(name) { + + const base = this.tests.get(name); + + if (!base.agents) + return true; + + let agents = base.agents; + + if (!Array.isArray(agents)) + agents = [agents]; + + const userAgent = "Node"; + for (const agent of agents) { + this.logTrace("Checking if environment is compatible with " + agent + " ..."); + if (userAgent.indexOf(agent) > -1) { + this.logTrace("... Yes"); + return true; + } + + this.logTrace("... No"); + } + + this.logTrace(" ... no compatible environment found."); + return false; + } + + async runTest(name) { + + this.startLog(name); + this.log("Test profile '" + name + "'", "Header"); + + if (!this.isCompatible(name)) { + this.log("Skipping test " + name + " is incompatible with browser..."); + return; + } + + const scripts = [ + "./tests/js/NodeUnit.js", + ... this.extend(name), + this.tests.get(name).script + ]; + + const vm = require('vm'); + + const context = {}; + vm.createContext(context); + + for (let script of scripts) { + // FixMe remove the path vodoo... + if (script.startsWith("./../common/")) + script = path.join("./src/common/", script); + + if (script.startsWith("./validators/")) + script = path.join("./tests/tests/", script); + + if (script.startsWith("./sieve/")) + script = path.join("./tests/tests/", script); + + if (!existsSync(script)) + throw new Error(`No such file ${path.resolve(script)}`); + + try { + console.log("Loading Script "+path.resolve(script)); + (new vm.Script(await readFile(script), { filename: path.resolve(script) })) + .runInContext(context); + } catch (ex) { + console.log(ex); + console.log(ex.stack); + + throw ex; + } + } + + context.net.tschmid.yautt.test.run(); + } + } + + exports.TestSuite = NodeTestSuite; + +})(module.exports || this); diff --git a/tests/js/NodeUnit.js b/tests/js/NodeUnit.js new file mode 100644 index 00000000..02a240ec --- /dev/null +++ b/tests/js/NodeUnit.js @@ -0,0 +1,134 @@ +(function (exports) { + + "use strict"; + + if (!exports.net) + exports.net = {}; + + if (!exports.net.tschmid) + exports.net.tschmid = {}; + + if (!exports.net.tschmid.yautt) + exports.net.tschmid.yautt = {}; + + if (!exports.net.tschmid.yautt.test) + exports.net.tschmid.yautt.test = {}; + + exports.net.tschmid.yautt.test.tests = []; + + + function log(message, level) { + + if (typeof (level) !== "string") + level = "Info"; + + console.log(`${level} ${message}`); + } + + function logError(message) { + log(message, "Error"); + } + + /** + * Logs the string at trace level + * @param {string} message + * the message to log. + *; + */ + function logTrace(message) { + log(message, "Trace"); + } + + + /** + * Checks if the actual value is a equals to true. + * + * @param {boolean} actual + * the actual value which should be tested + * @param {string} [message] + * the message to display in case of a failure. + * + */ + function assertTrue(actual, message) { + this.assertEquals(true, actual, message); + } + + /** + * Checks if the actual value is a equals to false. + * + * @param {boolean} actual + * the actual value which should be tested + * @param {string} [message] + * the message to display in case of a failure. + * + */ + function assertFalse(actual, message) { + this.assertEquals(false, actual, message); + } + + /** + * Checks if the actual value matches the expectation. + * In case it does not it throws an exception. + * + * @param {any} expected + * the expected value + * @param {any} actual + * the actual value which should be tested + * @param {string} [message] + * the message to display in case of a failure + * + */ + function assertEquals(expected, actual, message) { + + if (expected === actual) { + logTrace(`Assert successful: ${expected}\n`); + return; + } + + if (typeof (message) === 'undefined' || message === null) + message = `Assert failed\nExpected (${expected.length} Bytes): \n${expected}\n\nBut got (${actual.length} Bytes)\n${actual}`; + + throw new Error(`${message}`); + } + + /** + * Registers a function which contains a test to run. + * @param {*} test + * the function to call which contains the test. + * + */ + function add(test) { + + + if (!exports.net.tschmid.yautt.test.tests) + exports.net.tschmid.yautt.test.tests = []; + + exports.net.tschmid.yautt.test.tests.push(test); + } + + function run() { + + const tests = exports.net.tschmid.yautt.test.tests; + + if (!tests || !tests.length) + throw new Error("Empty test configuration"); + + for (const test of tests) + test(); + } + + + exports.net.tschmid.yautt.test.log = log; + exports.net.tschmid.yautt.test.logTrace = logTrace; + exports.net.tschmid.yautt.test.logError = logError; + + exports.net.tschmid.yautt.test.assertEquals = assertEquals; + exports.net.tschmid.yautt.test.assertTrue = assertTrue; + exports.net.tschmid.yautt.test.assertFalse = assertFalse; + + exports.net.tschmid.yautt.test.add = add; + + exports.net.tschmid.yautt.test.run = run; + +})(this); + |