Add event tests and bugfixes

This commit is contained in:
Timothy Farrell 2017-01-29 23:02:20 -06:00
parent 1300129ecc
commit 8a5d746412
2 changed files with 105 additions and 6 deletions

View File

@ -62,7 +62,7 @@ describe('Projector', () => {
}); });
describe('queueFrame', () => { describe('queueFrame', () => {
describe('patch to add elements', () => { describe('add elements patch', () => {
it('patch to add a basic element with a class', () => { it('patch to add a basic element with a class', () => {
expect(container.childNodes.length).toBe(0); expect(container.childNodes.length).toBe(0);
@ -117,9 +117,24 @@ describe('Projector', () => {
expect(document.querySelector('.child')).toBe(child); expect(document.querySelector('.child')).toBe(child);
expect(projector.getElement(child._id)).toBe(child); expect(projector.getElement(child._id)).toBe(child);
}); });
it('patch to add an eventHandler', done => {
function eventHandler(evt) {
expect(evt.target._id).toBe(id);
done();
}
projector.subscribe(eventHandler);
const id = add(h('input', { type: 'text', value: 'test', onclick: true }));
waitForNextFrame()
.then(() => {
projector.getElement(id).click();
})
.catch(console.error.bind(console));
});
}); });
describe('patch to update elements', () => { describe('update element patch', () => {
it('patch to change a class', done => { it('patch to change a class', done => {
const id = add(h('div', { className: 'first' })); const id = add(h('div', { className: 'first' }));
waitForNextFrame() waitForNextFrame()
@ -161,10 +176,54 @@ describe('Projector', () => {
.then(done) .then(done)
.catch(console.error.bind(console)); .catch(console.error.bind(console));
}); });
it('patch to add an eventHandler', done => {
function eventHandler(evt) {
expect(evt.target._id).toBe(id);
done();
}
projector.subscribe(eventHandler);
const id = add(h('input', { type: 'text', value: 'test' }));
waitForNextFrame()
.then(() => {
patch(id, { onclick: true });
return waitForNextFrame();
})
.then(() => {
projector.getElement(id).click();
})
.catch(console.error.bind(console));
});
it('patch to remove an eventHandler', done => {
let callCount = 1;
function eventHandler(evt) {
expect(evt.target._id).toBe(id);
patch(id, { onclick: null });
if (0 === callCount--) {
fail('Should not be called twice.');
}
}
projector.subscribe(eventHandler);
const id = add(h('input', { type: 'text', value: 'test', onclick: true }));
waitForNextFrame()
.then(() => {
projector.getElement(id).click();
return waitForNextFrame();
})
.then(() => {
projector.getElement(id).click();
return waitForNextFrame();
})
.then(done)
.catch(console.error.bind(console));
});
}); });
describe('patch to remove an element', () => { describe('remove element patch', () => {
it('', done => { it('remove an element', done => {
const id = add(h('div', {}, [h('span', { className: 'child' })])); const id = add(h('div', {}, [h('span', { className: 'child' })]));
const parent = projector.getElement(id); const parent = projector.getElement(id);
const child = parent.childNodes[0]; const child = parent.childNodes[0];
@ -181,4 +240,33 @@ describe('Projector', () => {
}); });
}); });
}); });
describe('subscribe', () => {
it('do not propagate a removed sibling event', done => {
let callCount = 1;
function eventHandler(evt) {
expect(evt.target._id).toBe(Bid);
patch(Bid, { onclick: null });
if (0 === callCount--) {
fail('Should not be called twice.');
}
}
projector.subscribe(eventHandler);
const Aid = add(h('input', { type: 'text', value: 'A', onclick: true }));
const Bid = add(h('input', { type: 'text', value: 'B', onclick: true }));
waitForNextFrame()
.then(() => {
projector.getElement(Bid).click();
return waitForNextFrame();
})
.then(() => {
// debugger;
projector.getElement(Bid).click();
return waitForNextFrame();
})
.then(done)
.catch(console.error.bind(console));
});
});
}); });

View File

@ -16,16 +16,27 @@ export function Projector(domRoot) {
let runningNextFrame; let runningNextFrame;
function eventHandler(evt) { function eventHandler(evt) {
const eventName = evt.type;
const eventSet = eventMap.get(eventName);
if (!eventSet || (evt.target && !eventSet.has(evt.target._id))) {
return;
}
if (OVERRIDING_EVENTS.includes(eventName)) { if (OVERRIDING_EVENTS.includes(eventName)) {
evt.preventDefault(); evt.preventDefault();
} }
evt.stopPropagation();
eventCallbacks.forEach(cb => cb(evt)); eventCallbacks.forEach(cb => cb(evt));
} }
function removeEvent(eventSet, id, eventName) { function removeEvent(eventSet, id, eventName) {
eventSet.remove(element._id); eventSet.delete(id);
if (!eventSet.size) { if (!eventSet.size) {
domRoot.removeEventListener(eventName, eventHandler); domRoot.removeEventListener(eventName, eventHandler);
// Probably unnecessary to remove the eventSet from the map.
// eventMap.delete(eventName);
} }
} }
@ -76,8 +87,8 @@ export function Projector(domRoot) {
} else if (type === 1) { } else if (type === 1) {
element = document.createElement(name); element = document.createElement(name);
} }
setAttributes(element, props);
elementMap.set((element._id = id), element); elementMap.set((element._id = id), element);
setAttributes(element, props);
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
element.appendChild(createElement(children[i])); element.appendChild(createElement(children[i]));