text: /**
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * @emails react-core
   */
  
  'use strict';
  
  describe('EventPluginRegistry', () => {
    let EventPluginRegistry;
    let createPlugin;
  
    beforeEach(() => {
      jest.resetModuleRegistry();
      // These tests are intentionally testing the private injection interface.
      // The public API surface of this is covered by other tests so
      // if `EventPluginRegistry` is ever deleted, these tests should be
      // safe to remove too.
      EventPluginRegistry = require('legacy-events/EventPluginRegistry');
  
      createPlugin = function(properties) {
        return Object.assign({extractEvents: function() {}}, properties);
      };
    });
  
    it('should be able to inject ordering before plugins', () => {
      const OnePlugin = createPlugin();
      const TwoPlugin = createPlugin();
      const ThreePlugin = createPlugin();
  
      EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);
      EventPluginRegistry.injectEventPluginsByName({
        one: OnePlugin,
        two: TwoPlugin,
      });
      EventPluginRegistry.injectEventPluginsByName({
        three: ThreePlugin,
      });
  
      expect(EventPluginRegistry.plugins.length).toBe(3);
      expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);
      expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);
      expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);
    });
  
    it('should be able to inject plugins before and after ordering', () => {
      const OnePlugin = createPlugin();
      const TwoPlugin = createPlugin();
      const ThreePlugin = createPlugin();
  
      EventPluginRegistry.injectEventPluginsByName({
        one: OnePlugin,
        two: TwoPlugin,
      });
      EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);
      EventPluginRegistry.injectEventPluginsByName({
        three: ThreePlugin,
      });
  
      expect(EventPluginRegistry.plugins.length).toBe(3);
      expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);
      expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);
      expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);
    });
  
    it('should be able to inject repeated plugins and out-of-order', () => {
      const OnePlugin = createPlugin();
      const TwoPlugin = createPlugin();
      const ThreePlugin = createPlugin();
  
      EventPluginRegistry.injectEventPluginsByName({
        one: OnePlugin,
        three: ThreePlugin,
      });
      EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);
      EventPluginRegistry.injectEventPluginsByName({
        two: TwoPlugin,
        three: ThreePlugin,
      });
  
      expect(EventPluginRegistry.plugins.length).toBe(3);
      expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);
      expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);
      expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);
    });
  
    it('should throw if plugin does not implement `extractEvents`', () => {
      const BadPlugin = {};
  
      EventPluginRegistry.injectEventPluginOrder(['bad']);
  
      expect(function() {
        EventPluginRegistry.injectEventPluginsByName({
          bad: BadPlugin,
        });
      }).toThrowError(
        'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
          'method, but `bad` does not.',
      );
    });
  
    it('should throw if plugin does not exist in ordering', () => {
      const OnePlugin = createPlugin();
      const RandomPlugin = createPlugin();
  
      EventPluginRegistry.injectEventPluginOrder(['one']);
  
      expect(function() {
        EventPluginRegistry.injectEventPluginsByName({
          one: OnePlugin,
          random: RandomPlugin,
        });
      }).toThrowError(
        'EventPluginRegistry: Cannot inject event plugins that do not exist ' +
          'in the plugin ordering, `random`.',
      );
    });
  
    it('should throw if ordering is injected more than once', () => {
      const pluginOrdering = [];
  
      EventPluginRegistry.injectEventPluginOrder(pluginOrdering);
  
      expect(function() {
        EventPluginRegistry.injectEventPluginOrder(pluginOrdering);
      }).toThrowError(
        'EventPluginRegistry: Cannot inject event plugin ordering more than ' +
          'once. You are likely trying to load more than one copy of React.',
      );
    });
  
    it('should throw if different plugins injected using same name', () => {
      const OnePlugin = createPlugin();
      const TwoPlugin = createPlugin();
  
      EventPluginRegistry.injectEventPluginsByName({same: OnePlugin});
  
      expect(function() {
        EventPluginRegistry.injectEventPluginsByName({same: TwoPlugin});
      }).toThrowError(
        'EventPluginRegistry: Cannot inject two different event plugins using ' +
          'the same name, `same`.',
      );
    });
  
    it('should publish registration names of injected plugins', () => {
      const OnePlugin = createPlugin({
        eventTypes: {
          click: {registrationName: 'onClick'},
          focus: {registrationName: 'onFocus'},
        },
      });
      const TwoPlugin = createPlugin({
        eventTypes: {
          magic: {
            phasedRegistrationNames: {
              bubbled: 'onMagicBubble',
              captured: 'onMagicCapture',
            },
          },
        },
      });
  
      EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});
      EventPluginRegistry.injectEventPluginOrder(['one', 'two']);
  
      expect(
        Object.keys(EventPluginRegistry.registrationNameModules).length,
      ).toBe(2);
      expect(EventPluginRegistry.registrationNameModules.onClick).toBe(OnePlugin);
      expect(EventPluginRegistry.registrationNameModules.onFocus).toBe(OnePlugin);
  
      EventPluginRegistry.injectEventPluginsByName({two: TwoPlugin});
  
      expect(
        Object.keys(EventPluginRegistry.registrationNameModules).length,
      ).toBe(4);
      expect(EventPluginRegistry.registrationNameModules.onMagicBubble).toBe(
        TwoPlugin,
      );
      expect(EventPluginRegistry.registrationNameModules.onMagicCapture).toBe(
        TwoPlugin,
      );
    });
  
    it('should throw if multiple registration names collide', () => {
      const OnePlugin = createPlugin({
        eventTypes: {
          photoCapture: {registrationName: 'onPhotoCapture'},
        },
      });
      const TwoPlugin = createPlugin({
        eventTypes: {
          photo: {
            phasedRegistrationNames: {
              bubbled: 'onPhotoBubble',
              captured: 'onPhotoCapture',
            },
          },
        },
      });
  
      EventPluginRegistry.injectEventPluginsByName({
        one: OnePlugin,
        two: TwoPlugin,
      });
  
      expect(function() {
        EventPluginRegistry.injectEventPluginOrder(['one', 'two']);
      }).toThrowError(
        'EventPluginRegistry: More than one plugin attempted to publish the same ' +
          'registration name, `onPhotoCapture`.',
      );
    });
  
    it('should throw if an invalid event is published', () => {
      const OnePlugin = createPlugin({
        eventTypes: {
          badEvent: {
            /* missing configuration */
          },
        },
      });
  
      EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});
  
      expect(function() {
        EventPluginRegistry.injectEventPluginOrder(['one']);
      }).toThrowError(
        'EventPluginRegistry: Failed to publish event `badEvent` for plugin ' +
          '`one`.',
      );
    });
  });
  