diff --git a/spec/unit/ReEmitter.spec.ts b/spec/unit/ReEmitter.spec.ts new file mode 100644 index 000000000..d1c853fe6 --- /dev/null +++ b/spec/unit/ReEmitter.spec.ts @@ -0,0 +1,49 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { EventEmitter } from "events"; +import { ReEmitter } from "../../src/ReEmitter"; + +const EVENTNAME = "UnknownEntry"; + +class EventSource extends EventEmitter { + doTheThing() { + this.emit(EVENTNAME, "foo", "bar"); + } +} + +class EventTarget extends EventEmitter { + +} + +describe("ReEmitter", function() { + it("Re-Emits events with the same args", function() { + const src = new EventSource(); + const tgt = new EventTarget(); + + const handler = jest.fn(); + tgt.on(EVENTNAME, handler); + + const reEmitter = new ReEmitter(tgt); + reEmitter.reEmit(src, [EVENTNAME]); + + src.doTheThing(); + + // Args should be the args passed to 'emit' after the event name, and + // also the source object of the event which re-emitter adds + expect(handler).toHaveBeenCalledWith("foo", "bar", src); + }); +}); diff --git a/src/ReEmitter.js b/src/ReEmitter.js deleted file mode 100644 index 84a856bb2..000000000 --- a/src/ReEmitter.js +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/** - * @module - */ - -export class ReEmitter { - constructor(target) { - this.target = target; - - // We keep one bound event handler for each event name so we know - // what event is arriving - this.boundHandlers = {}; - } - - _handleEvent(eventName, ...args) { - this.target.emit(eventName, ...args); - } - - reEmit(source, eventNames) { - // We include the source as the last argument for event handlers which may need it, - // such as read receipt listeners on the client class which won't have the context - // of the room. - const forSource = (handler, ...args) => { - handler(...args, source); - }; - for (const eventName of eventNames) { - if (this.boundHandlers[eventName] === undefined) { - this.boundHandlers[eventName] = this._handleEvent.bind(this, eventName); - } - - const boundHandler = forSource.bind(this, this.boundHandlers[eventName]); - source.on(eventName, boundHandler); - } - } -} diff --git a/src/ReEmitter.ts b/src/ReEmitter.ts new file mode 100644 index 000000000..f65912aa4 --- /dev/null +++ b/src/ReEmitter.ts @@ -0,0 +1,39 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 Vector Creations Ltd +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { EventEmitter } from "events"; + +export class ReEmitter { + private target: EventEmitter; + + constructor(target: EventEmitter) { + this.target = target; + } + + reEmit(source: EventEmitter, eventNames: string[]) { + for (const eventName of eventNames) { + // We include the source as the last argument for event handlers which may need it, + // such as read receipt listeners on the client class which won't have the context + // of the room. + const forSource = (...args) => { + this.target.emit(eventName, ...args, source); + }; + source.on(eventName, forSource); + } + } +}