mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
37dc1d44a5
Summary: Changelog: [Internal] This diff replaced all the internal occurrences of "Immediate" with "ReactNativeMicrotask" in the legacy bridge and then polyfilled the original immediate APIs during the timer setup phases as aliases of them. Note that this diff is part of a larger refactoring. Reviewed By: RSNara Differential Revision: D29785430 fbshipit-source-id: 7325d2a7358a6c9baa3e9abb8acf90414de5072f
166 lines
5.1 KiB
JavaScript
166 lines
5.1 KiB
JavaScript
/**
|
|
* 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 oncall+react_native
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
let MessageQueue;
|
|
let MessageQueueTestModule;
|
|
let queue;
|
|
|
|
const MODULE_IDS = 0;
|
|
const METHOD_IDS = 1;
|
|
const PARAMS = 2;
|
|
|
|
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] Local modules can be invoked through the queue.
|
|
//
|
|
// [ ] Local modules that throw exceptions are gracefully caught. In that case
|
|
// local callbacks stored by IDs are cleaned up.
|
|
describe('MessageQueue', function() {
|
|
beforeEach(function() {
|
|
jest.resetModules();
|
|
MessageQueue = require('../MessageQueue');
|
|
MessageQueueTestModule = require('../__mocks__/MessageQueueTestModule');
|
|
queue = new MessageQueue();
|
|
queue.registerCallableModule(
|
|
'MessageQueueTestModule',
|
|
MessageQueueTestModule,
|
|
);
|
|
queue.createDebugLookup(0, 'MessageQueueTestModule', [
|
|
'testHook1',
|
|
'testHook2',
|
|
]);
|
|
});
|
|
|
|
it('should enqueue native calls', () => {
|
|
queue.enqueueNativeCall(0, 1, [2]);
|
|
const flushedQueue = queue.flushedQueue();
|
|
assertQueue(flushedQueue, 0, 0, 1, [2]);
|
|
});
|
|
|
|
it('should call a local function with the function name', () => {
|
|
MessageQueueTestModule.testHook2 = jest.fn();
|
|
expect(MessageQueueTestModule.testHook2.mock.calls.length).toEqual(0);
|
|
queue.__callFunction('MessageQueueTestModule', 'testHook2', [2]);
|
|
expect(MessageQueueTestModule.testHook2.mock.calls.length).toEqual(1);
|
|
});
|
|
|
|
it('should store callbacks', () => {
|
|
queue.enqueueNativeCall(0, 1, ['foo'], null, null);
|
|
const flushedQueue = queue.flushedQueue();
|
|
assertQueue(flushedQueue, 0, 0, 1, ['foo']);
|
|
});
|
|
|
|
it('should call the stored callback', () => {
|
|
let done = false;
|
|
queue.enqueueNativeCall(
|
|
0,
|
|
1,
|
|
[],
|
|
() => {},
|
|
() => {
|
|
done = true;
|
|
},
|
|
);
|
|
queue.__invokeCallback(1, []);
|
|
expect(done).toEqual(true);
|
|
});
|
|
|
|
it('should throw when calling the same callback twice', () => {
|
|
queue.enqueueNativeCall(
|
|
0,
|
|
1,
|
|
[],
|
|
() => {},
|
|
() => {},
|
|
);
|
|
queue.__invokeCallback(1, []);
|
|
expect(() => queue.__invokeCallback(1, [])).toThrow();
|
|
});
|
|
|
|
it('should throw when calling both success and failure callback', () => {
|
|
queue.enqueueNativeCall(
|
|
0,
|
|
1,
|
|
[],
|
|
() => {},
|
|
() => {},
|
|
);
|
|
queue.__invokeCallback(1, []);
|
|
expect(() => queue.__invokeCallback(0, [])).toThrow();
|
|
});
|
|
|
|
it('should throw when calling with unknown module', () => {
|
|
const unknownModule = 'UnknownModule',
|
|
unknownMethod = 'UnknownMethod';
|
|
expect(() => queue.__callFunction(unknownModule, unknownMethod)).toThrow(
|
|
`Module ${unknownModule} is not a registered callable module (calling ${unknownMethod}). A frequent cause of the error is that the application entry file path is incorrect.
|
|
This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.`,
|
|
);
|
|
});
|
|
|
|
it('should return lazily registered module', () => {
|
|
const dummyModule = {},
|
|
name = 'modulesName';
|
|
queue.registerLazyCallableModule(name, () => dummyModule);
|
|
|
|
expect(queue.getCallableModule(name)).toEqual(dummyModule);
|
|
});
|
|
|
|
it('should not initialize lazily registered module before it was used for the first time', () => {
|
|
const dummyModule = {},
|
|
name = 'modulesName';
|
|
const factory = jest.fn(() => dummyModule);
|
|
queue.registerLazyCallableModule(name, factory);
|
|
expect(factory).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should initialize lazily registered module only once', () => {
|
|
const dummyModule = {},
|
|
name = 'modulesName';
|
|
const factory = jest.fn(() => dummyModule);
|
|
queue.registerLazyCallableModule(name, factory);
|
|
queue.getCallableModule(name);
|
|
queue.getCallableModule(name);
|
|
expect(factory).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should check if the global error handler is not overridden by the DebuggerInternal object', () => {
|
|
const dummyModule = {
|
|
dummy: function() {},
|
|
};
|
|
const name = 'emptyModuleName';
|
|
const factory = jest.fn(() => dummyModule);
|
|
queue.__shouldPauseOnThrow = jest.fn(() => false);
|
|
queue.registerLazyCallableModule(name, factory);
|
|
queue.callFunctionReturnFlushedQueue(name, 'dummy', []);
|
|
expect(queue.__shouldPauseOnThrow).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('should check if the global error handler is overridden by the DebuggerInternal object', () => {
|
|
const dummyModule = {
|
|
dummy: function() {},
|
|
};
|
|
const name = 'emptyModuleName';
|
|
const factory = jest.fn(() => dummyModule);
|
|
queue.__shouldPauseOnThrow = jest.fn(() => true);
|
|
queue.registerLazyCallableModule(name, factory);
|
|
queue.callFunctionReturnFlushedQueue(name, 'dummy', []);
|
|
expect(queue.__shouldPauseOnThrow).toHaveBeenCalledTimes(2);
|
|
});
|
|
});
|