Skip to content

Commit

Permalink
More core tests and better reliability (#258)
Browse files Browse the repository at this point in the history
* More core tests and better reliability

* Fix tsc error
  • Loading branch information
tbranyen committed Mar 31, 2022
1 parent cab7fb3 commit 218ed21
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 33 deletions.
14 changes: 1 addition & 13 deletions packages/diffhtml/lib/tasks/parse-new-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,12 @@ import Transaction from '../transaction';
export default function parseNewTree(transaction) {
const { state, input, config: options } = transaction;
const { measure } = state;
const { inner } = options;

if (typeof input === 'string') {
measure('parsing input for new tree');

const { childNodes } = parse(input, undefined, options);

let vTree;

// If we are dealing with innerHTML, use all the Nodes.
if (inner) {
vTree = createTree(childNodes);
}
// If we are dealing with outerHTML, use the first element or the element
// itself.
else {
vTree = createTree(childNodes[0] || childNodes);
}
const vTree = createTree(childNodes);

if (vTree) {
transaction.newTree = vTree;
Expand Down
36 changes: 18 additions & 18 deletions packages/diffhtml/lib/tasks/reconcile-trees.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export default function reconcileTrees(transaction) {
const { state, mount, input, config: options } = transaction;
const { inner } = options;
const mountAsHTMLEl = /** @type {HTMLElement} */ (mount);
const inputAsVTree = /** @type {VTree} */(input);

// Look if any changes happened before the async mutation callback.
if (state.mutationObserver && !state.isDirty) {
Expand Down Expand Up @@ -52,15 +51,25 @@ export default function reconcileTrees(transaction) {

const { nodeName, attributes } = state.oldTree;

// TODO When `inner === false` this means we are doing outerHTML operation.
// The way this works is that anything that doesn't match the oldTree element
// gets diffed internally. Anything that matches the root element at the top
// level gets absorbed into the root element. Order is not important. Elements
// which are matched subsequently are merged, but only the first occurance of
// an attribute is counted. The rules are complicated, but if we match the
// browser behavior here, it will be significantly easier to convince of it's
// validity and to document.

// If we are in a render transaction where no markup was previously parsed
// then reconcile trees will attempt to create a tree based on the incoming
// markup (JSX/html/etc).
if (!transaction.newTree) {
transaction.newTree = createTree(input);
}

const inputAsVTree = /** @type {VTree} */(transaction.newTree);

// When `inner === false` this means we are doing outerHTML operation. The
// way this works is that anything that doesn't match the oldTree element
// gets diffed internally. Anything that matches the root element at the top
// level gets absorbed into the root element. Order is not important.
// Elements which are matched subsequently are merged, but only the first
// occurance of an attribute is counted. The rules are complicated, but if we
// match the browser behavior here, it will be significantly easier to
// convince of it's validity and to document.
//
// To mimic browser behavior, we loop the input and take any tree that matches
// the root element and unwrap into the root element. We take the attributes
// from that element and apply to the root element. This ultimately renders a
Expand Down Expand Up @@ -96,15 +105,6 @@ export default function reconcileTrees(transaction) {
}
}

// If we are in a render transaction where no markup was previously parsed
// then reconcile trees will attempt to create a tree based on the incoming
// markup (JSX/html/etc).
if (!transaction.newTree) {
// Reset the old tree with the newly created VTree association.
transaction.newTree = createTree(input);

}

// Associate the old tree with this brand new transaction.
transaction.oldTree = state.oldTree;

Expand Down
2 changes: 1 addition & 1 deletion packages/diffhtml/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"watch-lite": "NODE_ENV=umd rollup -c rollup.lite.main.config.js -w",
"test": "mocha",
"test:ci": "npm run test-cov && cat coverage/lcov.info | coveralls",
"test-cov": "NODE_ENV=test+cov c8 -r=lcov mocha test/_setup test test/integration/*.js",
"test-cov": "NODE_ENV=test+cov c8 -r=lcov mocha",
"test-watch": "NODE_ENV=test mocha --color test/_setup test test/integration/*.js -w",
"test-debug": "NODE_ENV=test mocha --inspect --debug-brk test/_setup test test/integration/*.js"
},
Expand Down
20 changes: 19 additions & 1 deletion packages/diffhtml/test/integration/basics.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,27 @@ describe('Integration: Basics', function() {
});

describe('Expose API', function() {
it('exposes diffhtml global', function() {
it('will expose the diffhtml global', function() {
assert.equal(typeof diff, 'object');
});

it('will use the last core version loaded', async function() {
delete global[Symbol.for('diffHTML')];
const testBinding = { VERSION: 'test' };
global[Symbol.for('diffHTML')] = testBinding;
const { default: api } = await import('../../lib/index?' + Date.now());

assert.strictEqual(global[Symbol.for('diffHTML')], api);
});

it('will use the last lite version loaded', async function() {
delete global[Symbol.for('diffHTML')];
const testBinding = { VERSION: 'test' };
global[Symbol.for('diffHTML')] = testBinding;
const { default: api } = await import('../../lib/lite?' + Date.now());

assert.strictEqual(global[Symbol.for('diffHTML')], api);
});
});

describe('Call API', function() {
Expand Down
18 changes: 18 additions & 0 deletions packages/diffhtml/test/integration/outer.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,24 @@ describe('Integration: outerHTML', function() {
strictEqual(this.fixture.firstChild.tagName, 'P');
});

it('will respect executeScripts option', function() {
document.body.appendChild(this.fixture);

diff.outerHTML(this.fixture, `
<div>
<script>
const script1 = document.createElement('script');
script1.id = 'test';
document.body.firstElementChild.appendChild(script1);
</script>
</div>
`, { executeScripts: true });

strictEqual(Boolean(document.querySelector('#test')), true);

document.body.removeChild(this.fixture);
});

it('can use a virtual dom element', function() {
diff.outerHTML(this.fixture.firstChild, {
nodeName: 'div',
Expand Down

0 comments on commit 218ed21

Please sign in to comment.