text: /**
   * Copyright (c) 2013-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   */
  'use strict';
  
  jest
    .enableAutomock()
    .unmock('BatchedBridge')
    .unmock('defineLazyObjectProperty')
    .unmock('MessageQueue')
    .unmock('NativeModules');
  
  let BatchedBridge;
  let NativeModules;
  
  const MODULE_IDS = 0;
  const METHOD_IDS = 1;
  const PARAMS = 2;
  const CALL_ID = 3;
  
  const assertQueue = (flushedQueue, index, moduleID, methodID, params) => {
    expect(flushedQueue[MODULE_IDS][index]).toEqual(moduleID);
    expect(flushedQueue[METHOD_IDS][index]).toEqual(methodID);
    expect(flushedQueue[PARAMS][index]).toEqual(params);
  };
  
  // Important things to test:
  //
  // [x] Calling remote method actually queues it up on the BatchedBridge
  //
  // [x] Both error and success callbacks are invoked.
  //
  // [x] When simulating an error callback from remote method, both error and
  // success callbacks are cleaned up.
  //
  // [ ] Remote invocation throws if not supplying an error callback.
  describe('MessageQueue', function() {
    beforeEach(function() {
      jest.resetModules();
  
      global.__fbBatchedBridgeConfig = require('MessageQueueTestConfig');
      BatchedBridge = require('BatchedBridge');
      NativeModules = require('NativeModules');
    });
  
    it('should generate native modules', () => {
      NativeModules.RemoteModule1.remoteMethod('foo');
      const flushedQueue = BatchedBridge.flushedQueue();
      assertQueue(flushedQueue, 0, 0, 0, ['foo']);
    });
  
    it('should make round trip and clear memory', function() {
      const onFail = jasmine.createSpy();
      const onSucc = jasmine.createSpy();
  
      // Perform communication
      NativeModules.RemoteModule1.promiseMethod('paloAlto', 'menloPark', onFail, onSucc);
      NativeModules.RemoteModule2.promiseMethod('mac', 'windows', onFail, onSucc);
  
      const resultingRemoteInvocations = BatchedBridge.flushedQueue();
  
      // As always, the message queue has four fields
      expect(resultingRemoteInvocations.length).toBe(4);
      expect(resultingRemoteInvocations[MODULE_IDS].length).toBe(2);
      expect(resultingRemoteInvocations[METHOD_IDS].length).toBe(2);
      expect(resultingRemoteInvocations[PARAMS].length).toBe(2);
      expect(typeof resultingRemoteInvocations[CALL_ID]).toEqual('number');
  
      expect(resultingRemoteInvocations[0][0]).toBe(0); // `RemoteModule1`
      expect(resultingRemoteInvocations[1][0]).toBe(1); // `promiseMethod`
      expect([                                          // the arguments
        resultingRemoteInvocations[2][0][0],
        resultingRemoteInvocations[2][0][1]
      ]).toEqual(['paloAlto', 'menloPark']);
      // Callbacks ids are tacked onto the end of the remote arguments.
      const firstFailCBID = resultingRemoteInvocations[2][0][2];
      const firstSuccCBID = resultingRemoteInvocations[2][0][3];
  
      expect(resultingRemoteInvocations[0][1]).toBe(1); // `RemoteModule2`
      expect(resultingRemoteInvocations[1][1]).toBe(1); // `promiseMethod`
      expect([                                          // the arguments
        resultingRemoteInvocations[2][1][0],
        resultingRemoteInvocations[2][1][1]
      ]).toEqual(['mac', 'windows']);
      const secondFailCBID = resultingRemoteInvocations[2][1][2];
      const secondSuccCBID = resultingRemoteInvocations[2][1][3];
  
      // Handle the first remote invocation by signaling failure.
      BatchedBridge.__invokeCallback(firstFailCBID, ['firstFailure']);
      // The failure callback was already invoked, the success is no longer valid
      expect(function() {
        BatchedBridge.__invokeCallback(firstSuccCBID, ['firstSucc']);
      }).toThrow();
      expect(onFail.calls.count()).toBe(1);
      expect(onSucc.calls.count()).toBe(0);
  
      // Handle the second remote invocation by signaling success.
      BatchedBridge.__invokeCallback(secondSuccCBID, ['secondSucc']);
      // The success callback was already invoked, the fail cb is no longer valid
      expect(function() {
        BatchedBridge.__invokeCallback(secondFailCBID, ['secondFail']);
      }).toThrow();
      expect(onFail.calls.count()).toBe(1);
      expect(onSucc.calls.count()).toBe(1);
    });
  });
  