'use strict'; require('./util/test-init'); var chai = require('chai'); chai.config.includeStack = true; var path = require('path'); var autotest = require('./autotest'); const fs = require('fs'); const jsdom = require("jsdom").jsdom; const morphdom = require('marko/morphdom'); const expect = require('chai').expect; function serializeNode(node) { // NOTE: We don't use XMLSerializer because we need to sort the attributes to correctly compare output HTML strings // BAD: return (new XMLSerializer()).serializeToString(node); var html = ''; function serializeHelper(node, indent) { if (node.nodeType === 1) { serializeElHelper(node, indent); } else if (node.nodeType === 3) { serializeTextHelper(node, indent); } else { throw new Error('Unexpected node type'); } } function serializeElHelper(el, indent) { var nodeName = el.tagName; var namespaceURI = el.namespaceURI; if (namespaceURI === 'http://www.w3.org/2000/svg') { nodeName = 'svg:' + nodeName; } else if (namespaceURI === 'http://www.w3.org/1998/Math/MathML') { nodeName = 'math:' + nodeName; } else if (namespaceURI !== 'http://www.w3.org/1999/xhtml') { nodeName = namespaceURI + ':' + nodeName; } html += indent + '<' + nodeName; var attributes = el.attributes; var attributesArray = []; for (var i=0; i' + fromHTML + ''); let toDocument = jsdom('' + toHTML + ''); let fromNode = fromDocument.body.firstChild; let toNode = toDocument.body.firstChild; var allFromNodes = collectNodes(fromNode); var elLookupBefore = buildElLookup(fromNode); var targetVEl = require('marko/runtime/vdom/vdom').___virtualize(toNode); var expectedHTML = serializeNode(toNode); fs.writeFileSync(path.join(dir, 'expected.html'), expectedHTML, { encoding: 'utf8' }); var morphedNode = morphdom( fromNode, targetVEl, {}, function onNodeAdded() {}, function onBeforeElUpdated(node) { if (node.$onBeforeElUpdated) { throw new Error('Duplicate onBeforeElUpdated for: ' + serializeNode(node)); } node.$onBeforeElUpdated = true; }, function onBeforeNodeDiscarded(node) { if (node.$onBeforeNodeDiscarded) { throw new Error('Duplicate onBeforeNodeDiscarded for: ' + serializeNode(node)); } node.$onBeforeNodeDiscarded = true; }, function onNodeDiscarded(node) { if (node.$onNodeDiscarded) { throw new Error('Duplicate onNodeDiscarded for: ' + serializeNode(node)); } node.$onNodeDiscarded = true; }, function onBeforeElChildrenUpdated(node) { if (node.$onBeforeElChildrenUpdated) { throw new Error('Duplicate onBeforeElChildrenUpdated for: ' + serializeNode(node)); } node.$onBeforeElChildrenUpdated = true; }); var actualHTML = serializeNode(morphedNode); helpers.compare(actualHTML, '.html'); var elLookupAfter = buildElLookup(morphedNode); Object.keys(elLookupBefore).forEach(function(elId) { var afterEl = elLookupAfter[elId]; if (afterEl) { var beforeEl = elLookupBefore[elId]; if (afterEl.tagName === beforeEl.tagName) { if (afterEl !== beforeEl) { throw new Error('Element mismatch. Expected keyed element to be the same in the before and after.\nBEFORE:\n' + serializeNode(beforeEl) + '\n\nAFTER:\n' + serializeNode(afterEl)); } expect(afterEl).to.equal(beforeEl); } } }); allFromNodes.forEach(function(node) { if (node.$onNodeDiscarded && isNodeInTree(node, morphedNode)) { throw new Error('"from" node was reported as being discarded, but it still in the final DOM tree. Node: ' + serializeNode(node)); } if (node.nodeType === 1 && node.$onNodeDiscarded !== true) { if (!node.$onBeforeElUpdated) { throw new Error('"from" element was not reported as being discarded, but it was not morphed. Node: ' + serializeNode(node)); } } // if (isNodeInTree(node, morphedNode)) { // if (node.$testOnFromNodeRemovedFlag) { // throw new Error('onFromNodeRemoved(node) called for node that is in the final DOM tree: ' + node); // } // } else { // if (!node.$testOnFromNodeRemovedFlag) { // throw new Error('"from" node was removed but onFromNodeRemoved(node) was not called: ' + node); // } // } }); return done(); }); });