karma-qooxdoo
Version:
A Karma plugin - qooxdoo unit testing framework adapter.
265 lines (239 loc) • 8.88 kB
JavaScript
var fs = require("fs");
var path = require('path');
var qooxdooProxies = {};
var createPattern = function(file, included, served, watched) {
return {
pattern : file,
included : typeof included === "boolean" ? included : true,
served : typeof served === "boolean" ? served : true,
watched : typeof watched === "boolean" ? watched : false
}
};
var initQooxdoo = function(logger, config, customFilehandlers) {
var log = logger.create('framework.qooxdoo');
var files = config.files;
var basePath = config.basePath;
// if the jasmine framework is used, we use the jasmine test runner
var testRunner = config.frameworks.indexOf("jasmine") > -1 ? "jasmine" : "qooxdoo";
var includeFiles = false;
for (var pre in config.preprocessors) {
config.preprocessors[pre].forEach(function(prePro){
if (prePro === 'coverage') {
includeFiles = true;
return;
}
});
if (includeFiles === true) {
break;
}
}
var qooxdooCustomFileHandler = function (request, response) {
var url = request.url;
var normalizedPath = url.indexOf('?') > -1 ? url.substring(0, url.indexOf('?')) : url;
for (var proxy in qooxdooProxies) {
if (normalizedPath.startsWith(proxy)) {
normalizedPath = path.join(qooxdooProxies[proxy],normalizedPath.substring(proxy.length));
break;
}
}
var content = fs.readFileSync(normalizedPath);
response.writeHead(200);
response.end(content);
};
// hard coded proxy as it is always needed
qooxdooProxies['/script'] = path.join(basePath,'test','script');
var testsSourceFile = '';
var errorMessage = '';
var relPath = ''
var included = false;
if (config.qooxdooFramework && config.qooxdooFramework.testSources === true) {
// testing sources => add source files to the server
switch (testRunner) {
case "jasmine":
if (config.qooxdooFramework.codePath) {
testsSourceFile = path.resolve(basePath, path.join(config.qooxdooFramework.codePath, config.qooxdooFramework.scriptFile));
} else {
testsSourceFile = path.resolve(basePath, path.join('source', 'script', config.qooxdooFramework.scriptFile));
}
relPath = "source";
includeFiles = true;
included = true;
break;
default: // qooxdoo testrunner
testsSourceFile = path.resolve(basePath, path.join('test','script','tests-source.js'));
relPath = path.join('test','html');
break;
}
if (!fs.existsSync(testsSourceFile)) {
log.error("Aborted due to missing test sources.\n" + testsSourceFile + "not found\n");
process.exit();
}
if (config.qooxdooFramework.dbFile) {
const tmp = path.resolve(basePath, path.join(config.qooxdooFramework.codePath, config.qooxdooFramework.dbFile));
if (fs.existsSync(tmp)) {
db = require(tmp);
}
}
var source = fs.readFileSync(testsSourceFile).toString();
var qx = {
$$appRoot: path.dirname(testsSourceFile) + path.sep
};
// read libinfo
matches = source.match(/var libinfo = {([^;]+)};\n/ms);
if (!matches) {
// qx compiler produces different format
matches = source.match(/qx\.\$\$libraries = {};\n\[([^\]]+)\]/m)
if (matches) {
var libraries = matches[1].split(",").map(e => e.trim().replace(/"/g, ""))
qx.$$libraries = {}
libraries.forEach(ns => qx.$$libraries[ns] = {
sourceUri: qx.$$appRoot + "../transpiled/",
resourceUri: qx.$$appRoot + "../resource"
});
} else if (db.libraries) {
qx.$$libraries = {}
for (const ns in db.libraries) {
qx.$$libraries[ns] = {
sourceUri: qx.$$appRoot + "../transpiled/",
resourceUri: qx.$$appRoot + "../resource"
}
}
} else {
console.error("unable to parse libraries in " + testsSourceFile)
}
} else {
eval("qx.$$libraries = {" + matches[1] + "};");
}
// read loader settings
const lines = source.split('\n')
let inLoader = false
let openBrackets = 0
let loaderCode = []
lines.some((line, lno) => {
if (inLoader) {
for (let i = 0, l = line.length; i < l; i++) {
if (line[i] === '{' && (i === 0 || line[i - 1] !== '\\')) {
openBrackets++
} else if (line[i] === '}' && (i === 0 || line[i - 1] !== '\\')) {
openBrackets--
}
}
if (openBrackets === 0) {
inLoader = false
return true
}
if (line.match(/^\s*isLoadParallel:.*/)) {
loaderCode.push('isLoadParallel: false,')
} else if (line.match(/^\s*splashscreen:.*/)) {
loaderCode.push('splashscreen: null,')
} else {
loaderCode.push(line)
}
} else if (/qx.\$\$loader = \{\r?/.test(line)) {
inLoader = true
openBrackets = 1
}
})
loaderCode = loaderCode.join('\n')
eval("var loader = qx.$$loader = { " + loaderCode + " };");
qx.$$loader.addNoCacheParam = false;
// load project files
var bootUris = [];
var partsUris = [];
var bootPart = loader.parts.boot[0];
for (var key in loader.packages) {
if (key == bootPart) {
bootUris.push.apply(bootUris, loader.decodeUris(loader.packages[key].uris).reverse());
} else {
partsUris.push.apply(partsUris, loader.decodeUris(loader.packages[key].uris).reverse());
}
}
var loadUri = function(uri, includedOverride) {
// uris are relative to the test/html directory
var absolutePath = path.resolve(basePath, relPath, uri);
var relativePath = absolutePath.startsWith(basePath) ? absolutePath.replace(basePath, "") : null;
if (includeFiles) {
files.unshift(createPattern(absolutePath, includedOverride, true, config.autoWatch));
}
if (relativePath) {
// proxy to base
var source = relativePath.split(path.sep)[1];
var target = path.join(basePath,source);
if (testRunner === "qooxdoo" && !qooxdooProxies["/"+source]) {
qooxdooProxies["/"+source] = target;
}
}
else {
var parts = uri.split(path.sep);
var part = parts.shift();
while (part === "..") {
part = parts.shift();
}
if (testRunner === "qooxdoo" && !qooxdooProxies["/"+part]) {
qooxdooProxies["/"+part] = absolutePath.substring(0, absolutePath.indexOf(part) + part.length);
}
}
};
// do not include the part uris
partsUris.forEach(function(uri) {
loadUri(uri, false);
});
bootUris.forEach(function(uri) {
loadUri(uri, included);
});
files.unshift(createPattern(testsSourceFile));
// loads urisBefore
var urisBefore = loader.decodeUris(loader.urisBefore, "resourceUri");
urisBefore.reverse();
urisBefore.forEach(function(uri) {
// uris are relative to the test/html directory
var absolutePath = path.resolve(basePath, relPath, uri);
var relativePath = absolutePath.startsWith(basePath) ? absolutePath.replace(basePath, "") : null;
if (includeFiles) {
files.unshift(createPattern(absolutePath, included));
}
if (relativePath) {
var source = uri.split(path.sep)[0];
if (testRunner === "qooxdoo" && !qooxdooProxies["/"+source]) {
qooxdooProxies["/"+source] = path.join(basePath,'source',source);
}
} else {
var parts = uri.split(path.sep);
var part = parts.shift();
while (part === "..") {
part = parts.shift();
}
if (testRunner === "qooxdoo" && !qooxdooProxies["/"+part]) {
qooxdooProxies["/"+part] = absolutePath.substring(0, absolutePath.indexOf(part) + part.length);
}
}
});
if (includeFiles === false) {
for (var source in qooxdooProxies) {
customFilehandlers.push({
urlRegex : new RegExp("^" + source + ".*$"),
handler : qooxdooCustomFileHandler
});
}
}
}
else {
if (config.qooxdooFramework.codePath) {
testsSourceFile = path.resolve(basePath, config.qooxdooFramework.codePath, config.qooxdooFramework.scriptFile);
} else {
testsSourceFile = path.resolve(basePath, path.join('test','script','tests.js'));
}
if (!fs.existsSync(testsSourceFile)) {
log.error("Aborted due to missing tests.\n" + testsSourceFile + " not found\n");
process.exit();
}
files.push(createPattern(testsSourceFile));
}
if (testRunner === "qooxdoo") {
files.push(createPattern(path.resolve(__dirname, "qooxdoo-adapter.js")));
}
};
initQooxdoo.$inject = ['logger', 'config', 'customFileHandlers'];
module.exports = {
'framework:qooxdoo' : ['factory', initQooxdoo]
};