mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
225 lines
7.3 KiB
JavaScript
225 lines
7.3 KiB
JavaScript
'use strict';
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const marko = require('marko');
|
|
const fsExtra = require('fs-extra');
|
|
const domToHTML = require('./domToHTML');
|
|
const domToString = require('./domToString');
|
|
const jsdom = require("jsdom").jsdom;
|
|
const expect = require('chai').expect;
|
|
|
|
const defaultDocument = jsdom('<html><body></body></html>');
|
|
require('../../').setDocument(defaultDocument); // We need this to parse HTML fragments on the server
|
|
|
|
|
|
function createAsyncVerifier(main, helpers, out) {
|
|
var events = [];
|
|
var eventsByAwaitInstance = {};
|
|
|
|
var addEventListener = function(event) {
|
|
out.on(event, function(arg) {
|
|
var name = arg.name;
|
|
|
|
if (!eventsByAwaitInstance[name]) {
|
|
eventsByAwaitInstance[name] = [];
|
|
}
|
|
|
|
eventsByAwaitInstance[name].push(event);
|
|
|
|
events.push({
|
|
event: event,
|
|
arg: arg
|
|
});
|
|
});
|
|
};
|
|
|
|
addEventListener('await:begin');
|
|
addEventListener('await:beforeRender');
|
|
addEventListener('await:finish');
|
|
|
|
return {
|
|
verify() {
|
|
if (main.checkEvents) {
|
|
main.checkEvents(events, helpers, out);
|
|
}
|
|
|
|
// Make sure all of the await instances were correctly ended
|
|
Object.keys(eventsByAwaitInstance).forEach(function(name) {
|
|
var events = eventsByAwaitInstance[name];
|
|
expect(events).to.deep.equal([
|
|
'await:begin',
|
|
'await:beforeRender',
|
|
'await:finish'
|
|
]);
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = function runRenderTest(dir, helpers, done, options) {
|
|
let output = options.output || 'html';
|
|
|
|
require('marko/compiler').configure({output: output});
|
|
|
|
let isVDOM = output === 'vdom';
|
|
let checkAsyncEvents = options.checkAsyncEvents === true;
|
|
|
|
let actualDir;
|
|
|
|
if (isVDOM) {
|
|
actualDir = path.join(dir, '../~vdom.skip/' + path.basename(dir));
|
|
|
|
fsExtra.removeSync(actualDir);
|
|
|
|
fsExtra.copySync(dir, actualDir, {
|
|
filter: function(file) {
|
|
if (file.endsWith('.marko.js') || file.indexOf('.generated.') !== -1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
} else {
|
|
actualDir = dir;
|
|
}
|
|
|
|
let templatePath = path.join(actualDir, 'template.marko');
|
|
let mainPath = path.join(actualDir, 'test.js');
|
|
let main = fs.existsSync(mainPath) ? require(mainPath) : {};
|
|
let loadOptions = main && main.loadOptions;
|
|
|
|
if (isVDOM && main.vdomSkip) {
|
|
return done();
|
|
}
|
|
|
|
if (main.writeToDisk === false) {
|
|
require('marko/compiler').defaultOptions.writeToDisk = false;
|
|
}
|
|
|
|
if (main.preserveWhitespaceGlobal === true) {
|
|
require('marko/compiler').defaultOptions.preserveWhitespace = true;
|
|
}
|
|
|
|
var oldDone = done;
|
|
done = function(err) {
|
|
require('marko/compiler').configure();
|
|
|
|
if (err) {
|
|
return oldDone(err);
|
|
}
|
|
|
|
return oldDone();
|
|
};
|
|
|
|
try {
|
|
if (main.checkError) {
|
|
let e;
|
|
|
|
try {
|
|
marko.load(templatePath, loadOptions);
|
|
} catch(_e) {
|
|
e = _e;
|
|
let errorFile = path.join(actualDir, 'error.txt');
|
|
fs.writeFileSync(errorFile, e.stack.toString(), { encoding: 'utf8' });
|
|
}
|
|
|
|
if (!e) {
|
|
throw new Error('Error expected');
|
|
}
|
|
|
|
main.checkError(e);
|
|
return done();
|
|
} else {
|
|
let template = marko.load(templatePath, loadOptions);
|
|
let templateData = Object.assign({}, main.templateData || {});
|
|
|
|
let out = template.createOut();
|
|
let asyncEventsVerifier;
|
|
|
|
if (checkAsyncEvents) {
|
|
asyncEventsVerifier = createAsyncVerifier(main, helpers, out);
|
|
}
|
|
|
|
template.render(templateData, out, function(err, renderOutput) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
if (isVDOM) {
|
|
let vdomTree = renderOutput;
|
|
|
|
var getExpectedHtml = function(callback) {
|
|
var expectedHtml;
|
|
try {
|
|
expectedHtml = fs.readFileSync(path.join(dir, 'vdom-expected.html'), { encoding: 'utf8'});
|
|
} catch(e) {}
|
|
|
|
if (expectedHtml) {
|
|
return callback(null, expectedHtml);
|
|
}
|
|
|
|
require('marko/compiler').configure({ output: 'html' });
|
|
let htmlTemplatePath = path.join(dir, 'template.marko');
|
|
let htmlTemplate = marko.load(htmlTemplatePath);
|
|
let htmlMainPath = path.join(dir, 'test.js');
|
|
let htmlMain = fs.existsSync(htmlMainPath) ? require(htmlMainPath) : {};
|
|
|
|
htmlTemplate.render(htmlMain.templateData || {}, function(err, html) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
let document = jsdom('<html><body>' + html + '</body></html>');
|
|
let expectedHtml = domToString(document.body, { childrenOnly: true });
|
|
callback(null, expectedHtml);
|
|
});
|
|
};
|
|
|
|
|
|
getExpectedHtml(function(err, expectedHtml) {
|
|
fs.writeFileSync(path.join(dir, 'vdom-expected.generated.html'), expectedHtml, { encoding: 'utf8' });
|
|
|
|
let actualizedDom = vdomTree.actualize(defaultDocument);
|
|
|
|
// NOTE: We serialie the virtual DOM tree into an HTML string and reparse so that we can
|
|
// normalize the text
|
|
let vdomHtml = domToHTML(actualizedDom);
|
|
let vdomRealDocument = jsdom('<html><body>' + vdomHtml + '</body></html>');
|
|
let vdomString = domToString(vdomRealDocument.body, { childrenOnly: true });
|
|
helpers.compare(vdomString, 'vdom-', '.generated.html');
|
|
|
|
if (checkAsyncEvents) {
|
|
asyncEventsVerifier.verify();
|
|
}
|
|
|
|
done();
|
|
});
|
|
} else {
|
|
let html = renderOutput;
|
|
if (main.checkHtml) {
|
|
fs.writeFileSync(path.join(dir, 'actual.html'), html, { encoding: 'utf8' });
|
|
main.checkHtml(html);
|
|
} else {
|
|
helpers.compare(html, '.html');
|
|
}
|
|
|
|
if (checkAsyncEvents) {
|
|
asyncEventsVerifier.verify();
|
|
}
|
|
|
|
done();
|
|
}
|
|
});
|
|
|
|
out.end();
|
|
}
|
|
} finally {
|
|
if (main.writeToDisk === false) {
|
|
delete require('marko/compiler').defaultOptions.writeToDisk;
|
|
}
|
|
|
|
if (main.preserveWhitespaceGlobal === true) {
|
|
delete require('marko/compiler').defaultOptions.preserveWhitespace;
|
|
}
|
|
}
|
|
}; |