Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/event/target.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ class EventTarget {
if (filter(this.listeners[type], item => item === listener).length === 0) {
this.listeners[type].push(listener);
}
} else if (typeof listener === 'object' && Object.prototype.hasOwnProperty.call(listener, 'handleEvent')) {
if (!Array.isArray(this.listeners[type])) {
this.listeners[type] = [];
}

// Only add the same function once
if (filter(this.listeners[type], item => item === listener.handleEvent).length === 0) {
this.listeners[type].push(listener.handleEvent);
}
}
}

Expand Down
100 changes: 100 additions & 0 deletions tests/unit/event-target.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,35 @@ test('adding/removing "message" event listeners works', t => {
mock.dispatchEvent(eventObject);
});

test('adding/removing "message" for objects with handleEvent function works', t => {
const mock = new Mock();
const eventObject = createEvent({
type: 'message'
});

const fooListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};

const barListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};

mock.addEventListener('message', fooListener);
mock.addEventListener('message', barListener);
mock.dispatchEvent(eventObject);

mock.removeEventListener('message', fooListener);
mock.dispatchEvent(eventObject);

mock.removeEventListener('message', barListener);
mock.dispatchEvent(eventObject);
});

test('events to different object should not share events', t => {
const mock = new Mock();
const mockFoo = new MockFoo();
Expand Down Expand Up @@ -65,6 +94,38 @@ test('events to different object should not share events', t => {
mockFoo.dispatchEvent(eventObject);
});

test('events to different object should not share events', t => {
const mock = new Mock();
const mockFoo = new MockFoo();
const eventObject = createEvent({
type: 'message'
});

const fooListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};
const barListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};

mock.addEventListener('message', fooListener);
mockFoo.addEventListener('message', barListener);
mock.dispatchEvent(eventObject);
mockFoo.dispatchEvent(eventObject);

mock.removeEventListener('message', fooListener);
mock.dispatchEvent(eventObject);
mockFoo.dispatchEvent(eventObject);

mockFoo.removeEventListener('message', barListener);
mock.dispatchEvent(eventObject);
mockFoo.dispatchEvent(eventObject);
});

test('that adding the same function twice for the same event type is only added once', t => {
const mock = new Mock();
const fooListener = event => {
Expand All @@ -81,6 +142,26 @@ test('that adding the same function twice for the same event type is only added
t.is(mock.listeners.message.length, 2);
});

test('that adding the same function twice for the same event type is only added once', t => {
const mock = new Mock();
const fooListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};
const barListener = {
handleEvent: event => {
t.is(event.type, 'message');
}
};

mock.addEventListener('message', fooListener);
mock.addEventListener('message', fooListener);
mock.addEventListener('message', barListener);

t.is(mock.listeners.message.length, 2);
});

test('that dispatching an event with multiple data arguments works correctly', t => {
const mock = new Mock();
const eventObject = createEvent({
Expand All @@ -97,3 +178,22 @@ test('that dispatching an event with multiple data arguments works correctly', t
mock.addEventListener('message', fooListener);
mock.dispatchEvent(eventObject, 'foo', 'bar', 'baz');
});

test('that dispatching an event with multiple data arguments works correctly', t => {
const mock = new Mock();
const eventObject = createEvent({
type: 'message'
});

const fooListener = {
handleEvent: (...data) => {
t.is(data.length, 3);
t.is(data[0], 'foo');
t.is(data[1], 'bar');
t.is(data[2], 'baz');
}
};

mock.addEventListener('message', fooListener);
mock.dispatchEvent(eventObject, 'foo', 'bar', 'baz');
});