portfolio/packages/projector/spec/projector.spec.js

185 lines
4.8 KiB
JavaScript

// const { Projector } = require('../lib/index.js');
let COUNTER = 0;
describe('Projector', () => {
let projector;
let container;
beforeEach(() => {
container = document.createElement('div');
container.className = 'testContainer';
document.body.appendChild(container);
projector = Projector.Projector(container);
});
afterEach(() => {
container.parentNode.removeChild(container);
container = null;
});
function add(data, parentId = null, before) {
projector.queueFrame([[0, parentId, data, before]]);
return data.i;
}
function patch(id, props) {
projector.queueFrame([[1, id, props]]);
}
function remove(id) {
projector.queueFrame([[2, id]]);
}
function h(tagName, props, children = []) {
return {
t: 1,
n: tagName,
p: props,
c: children,
i: COUNTER++
};
}
function waitForNextFrame() {
return new Promise(resolve => {
requestAnimationFrame(() => {
setTimeout(resolve, 1);
}, container);
});
}
describe('getElement', () => {
it('getElement(null) method should to return the container.', () => {
expect(projector.getElement(null)).toBe(container);
});
it('getElement(id) method should to return the patched node.', () => {
const id = add(h('div', { className: 'first' }));
expect(projector.getElement(id)._id).toBe(id);
});
});
describe('queueFrame', () => {
describe('patch to add elements', () => {
it('patch to add a basic element with a class', () => {
expect(container.childNodes.length).toBe(0);
const id = add(h('div', { className: 'first' }));
expect(container.childNodes.length).toBe(1);
const newEl = document.querySelector('.first');
expect(newEl._id).toBe(id);
expect(newEl.parentNode).toBe(container);
expect(newEl.className).toBe('first');
});
it('patch to add a text element', () => {
expect(container.childNodes.length).toBe(0);
const id = add({
t: 3,
n: '',
p: { textContent: 'howdy' },
c: [],
i: COUNTER++
});
expect(container.childNodes.length).toBe(1);
const newEl = container.childNodes[0];
expect(newEl._id).toBe(id);
expect(newEl.parentNode).toBe(container);
expect(newEl.textContent).toBe('howdy');
});
it('patch to add a sibling element with a class', done => {
const id = add(h('div', { className: 'first' }));
waitForNextFrame()
.then(() => {
const siblingId = add(h('div', { className: 'second' }), null, id);
expect(container.childNodes.length).toBe(2);
const el = document.querySelector('.second');
expect(el._id).toBe(siblingId);
expect(el.parentNode).toBe(container);
expect(el.nextSibling._id).toBe(id);
})
.then(done)
.catch(console.error.bind(console));
});
it('patch to add a tree of elements', () => {
const id = add(h('div', {}, [h('span', { className: 'child' })]));
const parent = projector.getElement(id);
expect(container.childNodes.length).toBe(1);
const child = parent.childNodes[0];
expect(document.querySelector('.child')).toBe(child);
expect(projector.getElement(child._id)).toBe(child);
});
});
describe('patch to update elements', () => {
it('patch to change a class', done => {
const id = add(h('div', { className: 'first' }));
waitForNextFrame()
.then(() => {
patch(id, { className: 'second' });
expect(container.childNodes.length).toBe(1);
const el = document.querySelector('.second');
expect(el._id).toBe(id);
expect(el.parentNode).toBe(container);
expect(el.className).toBe('second');
})
.then(done)
.catch(console.error.bind(console));
});
it('patch to update text', done => {
expect(container.childNodes.length).toBe(0);
const id = add({
t: 3,
n: '',
p: { textContent: 'howdy' },
c: [],
i: COUNTER++
});
expect(container.childNodes.length).toBe(1);
const newEl = container.childNodes[0];
expect(newEl._id).toBe(id);
expect(newEl.parentNode).toBe(container);
expect(newEl.textContent).toBe('howdy');
waitForNextFrame()
.then(() => {
patch(id, { textContent: 'pardner' });
expect(newEl.textContent).toBe('pardner');
})
.then(done)
.catch(console.error.bind(console));
});
});
describe('patch to remove an element', () => {
it('', done => {
const id = add(h('div', {}, [h('span', { className: 'child' })]));
const parent = projector.getElement(id);
const child = parent.childNodes[0];
expect(projector.getElement(child._id)).toBe(child);
remove(child._id);
waitForNextFrame()
.then(() => {
expect(parent.childNodes.length).toBe(0);
expect(child.parentNode).toBe(null);
expect(projector.getElement(child._id)).toBe(undefined);
})
.then(done)
.catch(console.error.bind(console));
});
});
});
});