move demo/static/src/ts/core to src/

This commit is contained in:
Géry Debongnie
2019-03-14 11:23:10 +01:00
parent 2ffb0fd64c
commit f08ff9e5c2
103 changed files with 32 additions and 32 deletions
+98
View File
@@ -0,0 +1,98 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var patch = snabbdom.init([]);
var attachTo = require('../helpers/attachto').default;
var h = require('../h').default;
describe('attachTo', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('adds element to target', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', 'Test')),
]),
]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.children.length, 2);
});
it('updates element at target', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', 'First text')),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', 'New text')),
]),
]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.children[0].innerHTML, 'First text');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.children[0].innerHTML, 'New text');
});
it('element can be inserted before modal', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', 'Text')),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
h('div', 'A new element'),
attachTo(elm, h('div#attached', 'Text')),
]),
]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.children[0].innerHTML, 'Text');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.children[0].innerHTML, 'Text');
});
it('removes element at target', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', 'First text')),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
]),
]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.children[0].innerHTML, 'First text');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.children.length, 1);
});
it('remove hook receives real element', function() {
function rm(vnode, cb) {
assert.equal(vnode.elm.tagName, 'DIV');
assert.equal(vnode.elm.innerHTML, 'First text');
cb();
}
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
attachTo(elm, h('div#attached', {hook: {remove: rm}}, 'First text')),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
]),
]);
elm = patch(vnode0, vnode1).elm;
elm = patch(vnode1, vnode2).elm;
});
});
+97
View File
@@ -0,0 +1,97 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var patch = snabbdom.init([
require('../modules/attributes').default,
]);
var h = require('../h').default;
describe('attributes', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('have their provided values', function() {
var vnode1 = h('div', {attrs: {href: '/foo', minlength: 1, selected: true, disabled: false}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttribute('href'), '/foo');
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.hasAttribute('selected'), true);
assert.strictEqual(elm.getAttribute('selected'), '');
assert.strictEqual(elm.hasAttribute('disabled'), false);
});
it('can be memoized', function() {
var cachedAttrs = {href: '/foo', minlength: 1, selected: true};
var vnode1 = h('div', {attrs: cachedAttrs});
var vnode2 = h('div', {attrs: cachedAttrs});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttribute('href'), '/foo');
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.getAttribute('selected'), '');
elm = patch(vnode1, vnode2).elm;
assert.strictEqual(elm.getAttribute('href'), '/foo');
assert.strictEqual(elm.getAttribute('minlength'), '1');
assert.strictEqual(elm.getAttribute('selected'), '');
});
it('are not omitted when falsy values are provided', function() {
var vnode1 = h('div', {attrs: {href: null, minlength: 0, value: '', title:'undefined'}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttribute('href'), 'null');
assert.strictEqual(elm.getAttribute('minlength'), '0');
assert.strictEqual(elm.getAttribute('value'), '');
assert.strictEqual(elm.getAttribute('title'), 'undefined');
});
it('are set correctly when namespaced', function() {
var vnode1 = h('div', {attrs: {'xlink:href': '#foo'}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), '#foo');
});
it('should not touch class nor id fields', function() {
elm = document.createElement('div');
elm.id = 'myId';
elm.className = 'myClass';
vnode0 = elm;
var vnode1 = h('div#myId.myClass', {attrs: {}}, ['Hello']);
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.tagName, 'DIV');
assert.strictEqual(elm.id, 'myId');
assert.strictEqual(elm.className, 'myClass');
assert.strictEqual(elm.textContent, 'Hello');
});
describe('boolean attribute', function() {
it('is present and empty string if the value is truthy', function() {
var vnode1 = h('div', {attrs: {required: true, readonly: 1, noresize: 'truthy'}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.hasAttribute('required'), true);
assert.strictEqual(elm.getAttribute('required'), '');
assert.strictEqual(elm.hasAttribute('readonly'), true);
assert.strictEqual(elm.getAttribute('readonly'), '1');
assert.strictEqual(elm.hasAttribute('noresize'), true);
assert.strictEqual(elm.getAttribute('noresize'), 'truthy');
});
it('is omitted if the value is false', function() {
var vnode1 = h('div', {attrs: {required: false}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.hasAttribute('required'), false);
assert.strictEqual(elm.getAttribute('required'), null);
});
it('is not omitted if the value is falsy but casted to string', function() {
var vnode1 = h('div', {attrs: {readonly: 0, noresize: null}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.getAttribute('readonly'), '0');
assert.strictEqual(elm.getAttribute('noresize'), 'null');
});
});
describe('Object.prototype property', function() {
it('is not considered as a boolean attribute and shouldn\'t be omitted', function() {
var vnode1 = h('div', {attrs: {constructor: true}});
elm = patch(vnode0, vnode1).elm;
assert.strictEqual(elm.hasAttribute('constructor'), true);
assert.strictEqual(elm.getAttribute('constructor'), '');
var vnode2 = h('div', {attrs: {constructor: false}});
elm = patch(vnode0, vnode2).elm;
assert.strictEqual(elm.hasAttribute('constructor'), false);
});
});
});
+1114
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
var assert = require('assert');
var fakeRaf = require('fake-raf');
var snabbdom = require('../snabbdom');
fakeRaf.use();
var patch = snabbdom.init([
require('../modules/dataset').default,
]);
var h = require('../h').default;
describe('dataset', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('is set on initial element creation', function() {
elm = patch(vnode0, h('div', {dataset: {foo: 'foo'}})).elm;
assert.equal(elm.dataset.foo, 'foo');
});
it('updates dataset', function() {
var vnode1 = h('i', {dataset: {foo: 'foo', bar: 'bar'}});
var vnode2 = h('i', {dataset: {baz: 'baz'}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.dataset.foo, 'foo');
assert.equal(elm.dataset.bar, 'bar');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.dataset.baz, 'baz');
assert.equal(elm.dataset.foo, undefined);
});
it('can be memoized', function() {
var cachedDataset = {foo: 'foo', bar: 'bar'};
var vnode1 = h('i', {dataset: cachedDataset});
var vnode2 = h('i', {dataset: cachedDataset});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.dataset.foo, 'foo');
assert.equal(elm.dataset.bar, 'bar');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.dataset.foo, 'foo');
assert.equal(elm.dataset.bar, 'bar');
});
it('handles string conversions', function() {
var vnode1 = h('i', {dataset: {empty: '', dash: '-', dashed:'foo-bar', camel: 'fooBar', integer:0, float:0.1}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.dataset.empty, '');
assert.equal(elm.dataset.dash, '-');
assert.equal(elm.dataset.dashed, 'foo-bar');
assert.equal(elm.dataset.camel, 'fooBar');
assert.equal(elm.dataset.integer, '0');
assert.equal(elm.dataset.float, '0.1');
});
});
fakeRaf.restore();
+178
View File
@@ -0,0 +1,178 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var patch = snabbdom.init([
require('../modules/eventlisteners.js').default,
]);
var h = require('../h').default;
describe('event listeners', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('attaches click event handler to element', function() {
var result = [];
function clicked(ev) { result.push(ev); }
var vnode = h('div', {on: {click: clicked}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode).elm;
elm.click();
assert.equal(1, result.length);
});
it('does not attach new listener', function() {
var result = [];
//function clicked(ev) { result.push(ev); }
var vnode1 = h('div', {on: {click: function(ev) { result.push(1); }}}, [
h('a', 'Click my parent'),
]);
var vnode2 = h('div', {on: {click: function(ev) { result.push(2); }}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
elm = patch(vnode1, vnode2).elm;
elm.click();
assert.deepEqual(result, [1, 2]);
});
it('does calls handler for function in array', function() {
var result = [];
function clicked(ev) { result.push(ev); }
var vnode = h('div', {on: {click: [clicked, 1]}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode).elm;
elm.click();
assert.deepEqual(result, [1]);
});
it('handles changed value in array', function() {
var result = [];
function clicked(ev) { result.push(ev); }
var vnode1 = h('div', {on: {click: [clicked, 1]}}, [
h('a', 'Click my parent'),
]);
var vnode2 = h('div', {on: {click: [clicked, 2]}}, [
h('a', 'Click my parent'),
]);
var vnode3 = h('div', {on: {click: [clicked, 3]}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
elm = patch(vnode1, vnode2).elm;
elm.click();
elm = patch(vnode2, vnode3).elm;
elm.click();
assert.deepEqual(result, [1, 2, 3]);
});
it('handles changed several values in array', function() {
var result = [];
function clicked() { result.push([].slice.call(arguments, 0, arguments.length-2)); }
var vnode1 = h('div', {on: {click: [clicked, 1, 2, 3]}}, [
h('a', 'Click my parent'),
]);
var vnode2 = h('div', {on: {click: [clicked, 1, 2]}}, [
h('a', 'Click my parent'),
]);
var vnode3 = h('div', {on: {click: [clicked, 2, 3]}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
elm = patch(vnode1, vnode2).elm;
elm.click();
elm = patch(vnode2, vnode3).elm;
elm.click();
assert.deepEqual(result, [[1, 2, 3], [1, 2], [2, 3]]);
});
it('detach attached click event handler to element', function() {
var result = [];
function clicked(ev) { result.push(ev); }
var vnode1 = h('div', {on: {click: clicked}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(1, result.length);
var vnode2 = h('div', {on: {}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode1, vnode2).elm;
elm.click();
assert.equal(1, result.length);
});
it('multiple event handlers for same event on same element', function() {
var called = 0;
function clicked(ev, vnode) {
++called;
// Check that the first argument is an event
assert.equal(true, 'target' in ev);
// Check that the second argument was a vnode
assert.equal(vnode.sel, 'div');
}
var vnode1 = h('div', {on: {click: [[clicked], [clicked], [clicked]]}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(3, called);
var vnode2 = h('div', {on: {click: [[clicked], [clicked]]}}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode1, vnode2).elm;
elm.click();
assert.equal(5, called);
});
it('access to virtual node in event handler', function() {
var result = [];
function clicked(ev, vnode) { result.push(this); result.push(vnode); }
var vnode1 = h('div', {on: {click: clicked }}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(2, result.length);
assert.equal(vnode1, result[0]);
assert.equal(vnode1, result[1]);
}),
it('access to virtual node in event handler with argument', function() {
var result = [];
function clicked(arg, ev, vnode) { result.push(this); result.push(vnode); }
var vnode1 = h('div', {on: {click: [clicked, 1] }}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(2, result.length);
assert.equal(vnode1, result[0]);
assert.equal(vnode1, result[1]);
}),
it('access to virtual node in event handler with arguments', function() {
var result = [];
function clicked(arg1, arg2, ev, vnode) { result.push(this); result.push(vnode); }
var vnode1 = h('div', {on: {click: [clicked, 1, "2"] }}, [
h('a', 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(2, result.length);
assert.equal(vnode1, result[0]);
assert.equal(vnode1, result[1]);
});
it('shared handlers in parent and child nodes', function() {
var result = [];
var sharedHandlers = {
click: function(ev) { result.push(ev); }
};
var vnode1 = h('div', {on: sharedHandlers}, [
h('a', {on: sharedHandlers}, 'Click my parent'),
]);
elm = patch(vnode0, vnode1).elm;
elm.click();
assert.equal(1, result.length);
elm.firstChild.click();
assert.equal(3, result.length);
});
});
+53
View File
@@ -0,0 +1,53 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var h = require('../h').default;
var patch = snabbdom.init([
require('../modules/attributes').default
]);
describe('svg', function () {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('svg');
vnode0 = elm;
});
it('removes child svg elements', function(){
var a = h('svg', {}, [
h('g'),
h('g')
]);
var b = h('svg', {}, [
h('g')
]);
var result = patch(patch(vnode0, a), b).elm;
assert.equal(result.childNodes.length, 1);
});
it('adds correctly xlink namespaced attribute', function(){
var xlinkNS = 'http://www.w3.org/1999/xlink';
var testUrl = '/test';
var a = h('svg', {}, [
h('use', {
attrs: { 'xlink:href': testUrl }
}, [])
]);
var result = patch(vnode0, a).elm;
assert.equal(result.childNodes.length, 1);
assert.equal(result.childNodes[0].getAttribute('xlink:href'), testUrl);
assert.equal(result.childNodes[0].getAttributeNS(xlinkNS,'href'), testUrl);
});
it('adds correctly xml namespaced attribute', function(){
var xmlNS = 'http://www.w3.org/XML/1998/namespace';
var testAttrValue = 'und';
var a = h('svg', { attrs: { 'xml:lang': testAttrValue } }, []);
var result = patch(vnode0, a).elm;
assert.equal(result.getAttributeNS(xmlNS, 'lang'), testAttrValue);
assert.equal(result.getAttribute('xml:lang'), testAttrValue);
});
})
+151
View File
@@ -0,0 +1,151 @@
var assert = require('assert');
var fakeRaf = require('fake-raf');
var snabbdom = require('../snabbdom');
fakeRaf.use();
var patch = snabbdom.init([
require('../modules/style').default,
]);
var h = require('../h').default;
var toVNode = require('../tovnode').default;
describe('style', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('is being styled', function() {
elm = patch(vnode0, h('div', {style: {fontSize: '12px'}})).elm;
assert.equal(elm.style.fontSize, '12px');
});
it('can be memoized', function() {
var cachedStyles = {fontSize: '14px', display: 'inline'};
var vnode1 = h('i', {style: cachedStyles});
var vnode2 = h('i', {style: cachedStyles});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.fontSize, '14px');
assert.equal(elm.style.display, 'inline');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.style.fontSize, '14px');
assert.equal(elm.style.display, 'inline');
});
it('updates styles', function() {
var vnode1 = h('i', {style: {fontSize: '14px', display: 'inline'}});
var vnode2 = h('i', {style: {fontSize: '12px', display: 'block'}});
var vnode3 = h('i', {style: {fontSize: '10px', display: 'block'}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.fontSize, '14px');
assert.equal(elm.style.display, 'inline');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.style.fontSize, '12px');
assert.equal(elm.style.display, 'block');
elm = patch(vnode2, vnode3).elm;
assert.equal(elm.style.fontSize, '10px');
assert.equal(elm.style.display, 'block');
});
it('explicialy removes styles', function() {
var vnode1 = h('i', {style: {fontSize: '14px'}});
var vnode2 = h('i', {style: {fontSize: ''}});
var vnode3 = h('i', {style: {fontSize: '10px'}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.fontSize, '14px');
patch(vnode1, vnode2);
assert.equal(elm.style.fontSize, '');
patch(vnode2, vnode3);
assert.equal(elm.style.fontSize, '10px');
});
it('implicially removes styles from element', function() {
var vnode1 = h('div', [h('i', {style: {fontSize: '14px'}})]);
var vnode2 = h('div', [h('i')]);
var vnode3 = h('div', [h('i', {style: {fontSize: '10px'}})]);
patch(vnode0, vnode1);
assert.equal(elm.firstChild.style.fontSize, '14px');
patch(vnode1, vnode2);
assert.equal(elm.firstChild.style.fontSize, '');
patch(vnode2, vnode3);
assert.equal(elm.firstChild.style.fontSize, '10px');
});
it('updates css variables', function() {
var vnode1 = h('div', {style: {'--myVar': 1}});
var vnode2 = h('div', {style: {'--myVar': 2}});
var vnode3 = h('div', {style: {'--myVar': 3}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.getPropertyValue('--myVar'), 1);
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.style.getPropertyValue('--myVar'), 2);
elm = patch(vnode2, vnode3).elm;
assert.equal(elm.style.getPropertyValue('--myVar'), 3);
});
it('explicialy removes css variables', function() {
var vnode1 = h('i', {style: {'--myVar': 1}});
var vnode2 = h('i', {style: {'--myVar': ''}});
var vnode3 = h('i', {style: {'--myVar': 2}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.getPropertyValue('--myVar'), 1);
patch(vnode1, vnode2);
assert.equal(elm.style.getPropertyValue('--myVar'), '');
patch(vnode2, vnode3);
assert.equal(elm.style.getPropertyValue('--myVar'), 2);
});
it('implicially removes css variables from element', function() {
var vnode1 = h('div', [h('i', {style: {'--myVar': 1}})]);
var vnode2 = h('div', [h('i')]);
var vnode3 = h('div', [h('i', {style: {'--myVar': 2}})]);
patch(vnode0, vnode1);
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), 1);
patch(vnode1, vnode2);
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), '');
patch(vnode2, vnode3);
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), 2);
});
it('updates delayed styles in next frame', function() {
var patch = snabbdom.init([
require('../modules/style').default,
]);
var vnode1 = h('i', {style: {fontSize: '14px', delayed: {fontSize: '16px'}}});
var vnode2 = h('i', {style: {fontSize: '18px', delayed: {fontSize: '20px'}}});
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.style.fontSize, '14px');
fakeRaf.step();
fakeRaf.step();
assert.equal(elm.style.fontSize, '16px');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.style.fontSize, '18px');
fakeRaf.step();
fakeRaf.step();
assert.equal(elm.style.fontSize, '20px');
});
it('applies tranform as transition on remove', function(done) {
var btn = h('button', { style: {
transition: 'transform 0.5s',
remove: { transform: 'translateY(100%)' }
}}, ['A button']);
var vnode1 = h('div.parent', {}, [btn]);
var vnode2 = h('div.parent', {}, [null]);
document.body.appendChild(vnode0);
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.strictEqual(document.querySelectorAll('button').length, 1);
setTimeout(function () {
assert.strictEqual(document.querySelectorAll('button').length, 0);
done();
}, 700);
});
describe('using toVNode()', function () {
it('handles (ignoring) comment nodes', function() {
var comment = document.createComment('yolo');
var prevElm = document.createElement('div');
prevElm.appendChild(comment);
var nextVNode = h('div', [h('span', 'Hi')]);
elm = patch(toVNode(prevElm), nextVNode).elm;
assert.strictEqual(elm, prevElm);
assert.equal(elm.tagName, 'DIV');
assert.strictEqual(elm.childNodes.length, 1);
assert.strictEqual(elm.childNodes[0].tagName, 'SPAN');
assert.strictEqual(elm.childNodes[0].textContent, 'Hi');
});
});
});
fakeRaf.restore();
+232
View File
@@ -0,0 +1,232 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var patch = snabbdom.init([
]);
var h = require('../h').default;
var thunk = require('../thunk').default;
describe('thunk', function() {
var elm, vnode0;
beforeEach(function() {
elm = vnode0 = document.createElement('div');
});
it('returns vnode with data and render function', function() {
function numberInSpan(n) {
return h('span', 'Number is ' + n);
}
var vnode = thunk('span', 'num', numberInSpan, [22]);
assert.deepEqual(vnode.sel, 'span');
assert.deepEqual(vnode.data.key, 'num');
assert.deepEqual(vnode.data.args, [22]);
});
it('calls render function once on data change', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
var vnode1 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode2 = h('div', [
thunk('span', 'num', numberInSpan, [2])
]);
patch(vnode0, vnode1);
assert.equal(called, 1);
patch(vnode1, vnode2);
assert.equal(called, 2);
});
it('does not call render function on data unchanged', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
var vnode1 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode2 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
patch(vnode0, vnode1);
assert.equal(called, 1);
patch(vnode1, vnode2);
assert.equal(called, 1);
});
it('calls render function once on data-length change', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
var vnode1 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode2 = h('div', [
thunk('span', 'num', numberInSpan, [1, 2])
]);
patch(vnode0, vnode1);
assert.equal(called, 1);
patch(vnode1, vnode2);
assert.equal(called, 2);
});
it('calls render function once on function change', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
function numberInSpan2(n) {
called++;
return h('span', {key: 'num'}, 'Number really is ' + n);
}
var vnode1 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode2 = h('div', [
thunk('span', 'num', numberInSpan2, [1])
]);
patch(vnode0, vnode1);
assert.equal(called, 1);
patch(vnode1, vnode2);
assert.equal(called, 2);
});
it('renders correctly', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
var vnode1 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode2 = h('div', [
thunk('span', 'num', numberInSpan, [1])
]);
var vnode3 = h('div', [
thunk('span', 'num', numberInSpan, [2])
]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
elm = patch(vnode2, vnode3).elm;
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
assert.equal(elm.firstChild.innerHTML, 'Number is 2');
assert.equal(called, 2);
});
it('supports leaving out the `key` argument', function() {
function vnodeFn(s) {
return h('span.number', 'Hello ' + s);
}
var vnode1 = thunk('span.number', vnodeFn, ['World!']);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.innerText, 'Hello World!');
});
it('renders correctly when root', function() {
var called = 0;
function numberInSpan(n) {
called++;
return h('span', {key: 'num'}, 'Number is ' + n);
}
var vnode1 = thunk('span', 'num', numberInSpan, [1]);
var vnode2 = thunk('span', 'num', numberInSpan, [1]);
var vnode3 = thunk('span', 'num', numberInSpan, [2]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.tagName.toLowerCase(), 'span');
assert.equal(elm.innerHTML, 'Number is 1');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.tagName.toLowerCase(), 'span');
assert.equal(elm.innerHTML, 'Number is 1');
elm = patch(vnode2, vnode3).elm;
assert.equal(elm.tagName.toLowerCase(), 'span');
assert.equal(elm.innerHTML, 'Number is 2');
assert.equal(called, 2);
});
it('can be replaced and removed', function() {
function numberInSpan(n) {
return h('span', {key: 'num'}, 'Number is ' + n);
}
function oddEven(n) {
var prefix = (n % 2) === 0 ? 'Even' : 'Odd';
return h('div', {key: oddEven}, prefix + ': ' + n);
}
var vnode1 = h('div', [thunk('span', 'num', numberInSpan, [1])]);
var vnode2 = h('div', [thunk('div', 'oddEven', oddEven, [4])]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.firstChild.tagName.toLowerCase(), 'div');
assert.equal(elm.firstChild.innerHTML, 'Even: 4');
});
it('can be replaced and removed when root', function() {
function numberInSpan(n) {
return h('span', {key: 'num'}, 'Number is ' + n);
}
function oddEven(n) {
var prefix = (n % 2) === 0 ? 'Even' : 'Odd';
return h('div', {key: oddEven}, prefix + ': ' + n);
}
var vnode1 = thunk('span', 'num', numberInSpan, [1]);
var vnode2 = thunk('div', 'oddEven', oddEven, [4]);
elm = patch(vnode0, vnode1).elm;
assert.equal(elm.tagName.toLowerCase(), 'span');
assert.equal(elm.innerHTML, 'Number is 1');
elm = patch(vnode1, vnode2).elm;
assert.equal(elm.tagName.toLowerCase(), 'div');
assert.equal(elm.innerHTML, 'Even: 4');
});
it('invokes destroy hook on thunks', function() {
var called = 0;
function destroyHook() {
called++;
}
function numberInSpan(n) {
return h('span', {key: 'num', hook: {destroy: destroyHook}}, 'Number is ' + n);
}
var vnode1 = h('div', [
h('div', 'Foo'),
thunk('span', 'num', numberInSpan, [1]),
h('div', 'Foo')
]);
var vnode2 = h('div', [
h('div', 'Foo'),
h('div', 'Foo')
]);
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.equal(called, 1);
});
it('invokes remove hook on thunks', function() {
var called = 0;
function hook() {
called++;
}
function numberInSpan(n) {
return h('span', {key: 'num', hook: {remove: hook}}, 'Number is ' + n);
}
var vnode1 = h('div', [
h('div', 'Foo'),
thunk('span', 'num', numberInSpan, [1]),
h('div', 'Foo')
]);
var vnode2 = h('div', [
h('div', 'Foo'),
h('div', 'Foo')
]);
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.equal(called, 1);
});
});