1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. describe('events', () => {
    
  11.   let dispatcher;
    
  12. 
    
  13.   beforeEach(() => {
    
  14.     const EventEmitter = require('../events').default;
    
  15. 
    
  16.     dispatcher = new EventEmitter();
    
  17.   });
    
  18. 
    
  19.   // @reactVersion >=16
    
  20.   it('can dispatch an event with no listeners', () => {
    
  21.     dispatcher.emit('event', 123);
    
  22.   });
    
  23. 
    
  24.   // @reactVersion >=16
    
  25.   it('handles a listener being attached multiple times', () => {
    
  26.     const callback = jest.fn();
    
  27. 
    
  28.     dispatcher.addListener('event', callback);
    
  29.     dispatcher.addListener('event', callback);
    
  30. 
    
  31.     dispatcher.emit('event', 123);
    
  32.     expect(callback).toHaveBeenCalledTimes(1);
    
  33.     expect(callback).toHaveBeenCalledWith(123);
    
  34.   });
    
  35. 
    
  36.   // @reactVersion >=16
    
  37.   it('notifies all attached listeners of events', () => {
    
  38.     const callback1 = jest.fn();
    
  39.     const callback2 = jest.fn();
    
  40.     const callback3 = jest.fn();
    
  41. 
    
  42.     dispatcher.addListener('event', callback1);
    
  43.     dispatcher.addListener('event', callback2);
    
  44.     dispatcher.addListener('other-event', callback3);
    
  45.     dispatcher.emit('event', 123);
    
  46. 
    
  47.     expect(callback1).toHaveBeenCalledTimes(1);
    
  48.     expect(callback1).toHaveBeenCalledWith(123);
    
  49.     expect(callback2).toHaveBeenCalledTimes(1);
    
  50.     expect(callback2).toHaveBeenCalledWith(123);
    
  51.     expect(callback3).not.toHaveBeenCalled();
    
  52.   });
    
  53. 
    
  54.   // @reactVersion >= 16.0
    
  55.   it('calls later listeners before re-throwing if an earlier one throws', () => {
    
  56.     const callbackThatThrows = jest.fn(() => {
    
  57.       throw Error('expected');
    
  58.     });
    
  59.     const callback = jest.fn();
    
  60. 
    
  61.     dispatcher.addListener('event', callbackThatThrows);
    
  62.     dispatcher.addListener('event', callback);
    
  63. 
    
  64.     expect(() => {
    
  65.       dispatcher.emit('event', 123);
    
  66.     }).toThrow('expected');
    
  67. 
    
  68.     expect(callbackThatThrows).toHaveBeenCalledTimes(1);
    
  69.     expect(callbackThatThrows).toHaveBeenCalledWith(123);
    
  70.     expect(callback).toHaveBeenCalledTimes(1);
    
  71.     expect(callback).toHaveBeenCalledWith(123);
    
  72.   });
    
  73. 
    
  74.   // @reactVersion >= 16.0
    
  75.   it('removes attached listeners', () => {
    
  76.     const callback1 = jest.fn();
    
  77.     const callback2 = jest.fn();
    
  78. 
    
  79.     dispatcher.addListener('event', callback1);
    
  80.     dispatcher.addListener('other-event', callback2);
    
  81.     dispatcher.removeListener('event', callback1);
    
  82.     dispatcher.emit('event', 123);
    
  83.     expect(callback1).not.toHaveBeenCalled();
    
  84.     dispatcher.emit('other-event', 123);
    
  85.     expect(callback2).toHaveBeenCalledTimes(1);
    
  86.     expect(callback2).toHaveBeenCalledWith(123);
    
  87.   });
    
  88. 
    
  89.   // @reactVersion >= 16.0
    
  90.   it('removes all listeners', () => {
    
  91.     const callback1 = jest.fn();
    
  92.     const callback2 = jest.fn();
    
  93.     const callback3 = jest.fn();
    
  94. 
    
  95.     dispatcher.addListener('event', callback1);
    
  96.     dispatcher.addListener('event', callback2);
    
  97.     dispatcher.addListener('other-event', callback3);
    
  98.     dispatcher.removeAllListeners();
    
  99.     dispatcher.emit('event', 123);
    
  100.     dispatcher.emit('other-event', 123);
    
  101. 
    
  102.     expect(callback1).not.toHaveBeenCalled();
    
  103.     expect(callback2).not.toHaveBeenCalled();
    
  104.     expect(callback3).not.toHaveBeenCalled();
    
  105.   });
    
  106. 
    
  107.   // @reactVersion >= 16.0
    
  108.   it('should call the initial listeners even if others are added or removed during a dispatch', () => {
    
  109.     const callback1 = jest.fn(() => {
    
  110.       dispatcher.removeListener('event', callback2);
    
  111.       dispatcher.addListener('event', callback3);
    
  112.     });
    
  113.     const callback2 = jest.fn();
    
  114.     const callback3 = jest.fn();
    
  115. 
    
  116.     dispatcher.addListener('event', callback1);
    
  117.     dispatcher.addListener('event', callback2);
    
  118. 
    
  119.     dispatcher.emit('event', 123);
    
  120.     expect(callback1).toHaveBeenCalledTimes(1);
    
  121.     expect(callback1).toHaveBeenCalledWith(123);
    
  122.     expect(callback2).toHaveBeenCalledTimes(1);
    
  123.     expect(callback2).toHaveBeenCalledWith(123);
    
  124.     expect(callback3).not.toHaveBeenCalled();
    
  125. 
    
  126.     dispatcher.emit('event', 456);
    
  127.     expect(callback1).toHaveBeenCalledTimes(2);
    
  128.     expect(callback1).toHaveBeenCalledWith(456);
    
  129.     expect(callback2).toHaveBeenCalledTimes(1);
    
  130.     expect(callback3).toHaveBeenCalledTimes(1);
    
  131.     expect(callback3).toHaveBeenCalledWith(456);
    
  132.   });
    
  133. });