From 4c4f967bfc501f199103796d3722bfff0dbb2563 Mon Sep 17 00:00:00 2001
From: Rob Hogan <robhogan@fb.com>
Date: Sun, 11 Sep 2022 14:33:08 -0700
Subject: [PATCH 1/3] Fix LogBoxSymbolication-test

Differential Revision: D39418412

fbshipit-source-id: e2b76fa91df28ce1418a487f45dbeb590a66d184
---
 .../LogBox/Data/__tests__/LogBoxSymbolication-test.js     | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Libraries/LogBox/Data/__tests__/LogBoxSymbolication-test.js b/Libraries/LogBox/Data/__tests__/LogBoxSymbolication-test.js
index 1d35a1e9867f..072be3035cfd 100644
--- a/Libraries/LogBox/Data/__tests__/LogBoxSymbolication-test.js
+++ b/Libraries/LogBox/Data/__tests__/LogBoxSymbolication-test.js
@@ -12,6 +12,7 @@
 'use strict';
 
 import type {StackFrame} from '../../../Core/NativeExceptionsManager';
+import type {SymbolicatedStackTrace} from '../../../Core/Devtools/symbolicateStackTrace';
 
 jest.mock('../../../Core/Devtools/symbolicateStackTrace');
 
@@ -19,7 +20,7 @@ const LogBoxSymbolication = require('../LogBoxSymbolication');
 
 const symbolicateStackTrace: JestMockFn<
   $ReadOnlyArray<Array<StackFrame>>,
-  Promise<Array<StackFrame>>,
+  Promise<SymbolicatedStackTrace>,
 > = (require('../../../Core/Devtools/symbolicateStackTrace'): any);
 
 const createStack = (methodNames: Array<string>) =>
@@ -33,7 +34,10 @@ const createStack = (methodNames: Array<string>) =>
 describe('LogBoxSymbolication', () => {
   beforeEach(() => {
     jest.resetModules();
-    symbolicateStackTrace.mockImplementation(async stack => stack);
+    symbolicateStackTrace.mockImplementation(async stack => ({
+      stack,
+      codeFrame: null,
+    }));
   });
 
   it('symbolicates different stacks', () => {

From ffe0cd91fc288f5688b4e53805d63ce5565e6294 Mon Sep 17 00:00:00 2001
From: Rob Hogan <robhogan@fb.com>
Date: Sun, 11 Sep 2022 14:33:08 -0700
Subject: [PATCH 2/3] Allow LogBoxLog-test to work with native promises

Differential Revision: D39418413

fbshipit-source-id: 7b4c96c62ada4ef7cd5231b305c926068026df38
---
 .../LogBox/Data/__tests__/LogBoxLog-test.js   | 28 +++++++++++--------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/Libraries/LogBox/Data/__tests__/LogBoxLog-test.js b/Libraries/LogBox/Data/__tests__/LogBoxLog-test.js
index bd26449ba0a9..98b758d9b62d 100644
--- a/Libraries/LogBox/Data/__tests__/LogBoxLog-test.js
+++ b/Libraries/LogBox/Data/__tests__/LogBoxLog-test.js
@@ -57,6 +57,10 @@ const createStack = (methodNames: Array<string>) =>
     methodName,
   }));
 
+// Adds a new task to the end of the microtask queue, so that awaiting this
+// function will run all queued immediates
+const runMicrotasks = async () => {};
+
 describe('LogBoxLog', () => {
   beforeEach(() => {
     jest.resetModules();
@@ -132,7 +136,7 @@ describe('LogBoxLog', () => {
     expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
   });
 
-  it('updates when symbolication finishes', () => {
+  it('updates when symbolication finishes', async () => {
     const log = getLogBoxLog();
 
     const callback = jest.fn();
@@ -141,7 +145,7 @@ describe('LogBoxLog', () => {
     expect(callback).toBeCalledWith('PENDING');
     expect(getLogBoxSymbolication().symbolicate).toBeCalled();
 
-    jest.runAllTicks();
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(2);
     expect(callback).toBeCalledWith('COMPLETE');
@@ -156,13 +160,14 @@ describe('LogBoxLog', () => {
     getLogBoxSymbolication().symbolicate.mockClear();
 
     log.symbolicate(callback);
-    jest.runAllTicks();
+
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(0);
     expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
   });
 
-  it('updates when symbolication fails', () => {
+  it('updates when symbolication fails', async () => {
     const error = new Error('...');
     getLogBoxSymbolication().symbolicate.mockImplementation(async stack => {
       throw error;
@@ -176,7 +181,7 @@ describe('LogBoxLog', () => {
     expect(callback).toBeCalledWith('PENDING');
     expect(getLogBoxSymbolication().symbolicate).toBeCalled();
 
-    jest.runAllTicks();
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(2);
     expect(callback).toBeCalledWith('FAILED');
@@ -191,7 +196,8 @@ describe('LogBoxLog', () => {
     getLogBoxSymbolication().symbolicate.mockClear();
 
     log.symbolicate(callback);
-    jest.runAllTicks();
+
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(0);
     expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
@@ -221,7 +227,7 @@ describe('LogBoxLog', () => {
     expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
   });
 
-  it('retry updates when symbolication finishes', () => {
+  it('retry updates when symbolication finishes', async () => {
     const log = getLogBoxLog();
 
     const callback = jest.fn();
@@ -230,7 +236,7 @@ describe('LogBoxLog', () => {
     expect(callback).toBeCalledWith('PENDING');
     expect(getLogBoxSymbolication().symbolicate).toBeCalled();
 
-    jest.runAllTicks();
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(2);
     expect(callback).toBeCalledWith('COMPLETE');
@@ -251,7 +257,7 @@ describe('LogBoxLog', () => {
     expect(getLogBoxSymbolication().symbolicate).not.toBeCalled();
   });
 
-  it('retry updates when symbolication fails', () => {
+  it('retry updates when symbolication fails', async () => {
     const error = new Error('...');
     getLogBoxSymbolication().symbolicate.mockImplementation(async stack => {
       throw error;
@@ -265,7 +271,7 @@ describe('LogBoxLog', () => {
     expect(callback).toBeCalledWith('PENDING');
     expect(getLogBoxSymbolication().symbolicate).toBeCalled();
 
-    jest.runAllTicks();
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(2);
     expect(callback).toBeCalledWith('FAILED');
@@ -289,7 +295,7 @@ describe('LogBoxLog', () => {
     expect(callback).toBeCalledWith('PENDING');
     expect(getLogBoxSymbolication().symbolicate).toBeCalled();
 
-    jest.runAllTicks();
+    await runMicrotasks();
 
     expect(callback).toBeCalledTimes(2);
     expect(callback).toBeCalledWith('COMPLETE');

From 64656776ef739ba5e8e96a1acc5d94dc300fcac6 Mon Sep 17 00:00:00 2001
From: Rob Hogan <robhogan@fb.com>
Date: Sun, 11 Sep 2022 14:33:27 -0700
Subject: [PATCH 3/3] Stop polyfilling Promise in Jest tests

Summary:
We've used this Promise polyfill in Jest setup since at least 2015 ([`3ff3987`](https://github.com/facebook/react-native/commit/3ff39870ce776c653823e1733363be0401896294)), when native Promise implementations were either non-existent or new and unstable. We no longer need it.

It causes issues with "modern" timers in Jest, as documented in:
 - https://github.com/facebook/react-native/issues/29303
 - https://github.com/facebook/jest/issues/10221

It can also obscure real issues due to its default silent handling of uncaught rejections, eg: D39418412.

Changelog:
[General][Changed] - Don't polyfill Promise in Jest setup

Differential Revision: D39417597

fbshipit-source-id: 1773032343f914a37789c7bc43760838f2d86d31
---
 jest/setup.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/jest/setup.js b/jest/setup.js
index e422cb64460d..36b922f3529d 100644
--- a/jest/setup.js
+++ b/jest/setup.js
@@ -21,7 +21,6 @@ global.performance = {
   now: jest.fn(Date.now),
 };
 
-global.Promise = jest.requireActual('promise');
 global.regeneratorRuntime = jest.requireActual('regenerator-runtime/runtime');
 global.window = global;
 
