Skip to content

Commit 06fc1cc

Browse files
committed
feat(react-native-cli): update insert command for 0.79 projects
1 parent 6de1670 commit 06fc1cc

7 files changed

Lines changed: 155 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [Unreleased]
4+
5+
- (react-native-cli) Update insert command for 0.79 projects [#2410](https://github.com/bugsnag/bugsnag-js/pull/2410)
6+
37
## [8.3.1] - 2025-04-09
48

59
### Changed

packages/react-native-cli/src/lib/Insert.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const COCOA_OBJ_C_APP_LAUNCH_REGEX = /(-\s*\(BOOL\)\s*application:\s*\(UIApplica
1616

1717
const BUGSNAG_COCOA_SWIFT_IMPORT = 'import Bugsnag'
1818
const BUGSNAG_COCOA_SWIFT_INIT = 'Bugsnag.start()'
19-
const COCOA_SWIFT_APP_LAUNCH_REGEX = /(override func application\s*\(\s*_ application:\s*UIApplication,\s*didFinishLaunchingWithOptions launchOptions:\s*\[UIApplication\.LaunchOptionsKey\s*:\s*Any\]\?\s*=\s*nil\)\s*->\s*Bool\s*\{\s)/
19+
const COCOA_SWIFT_APP_LAUNCH_REGEX = /((?:override )?func application\s*\(\s*_\s+application:\s*UIApplication,\s*didFinishLaunchingWithOptions\s+launchOptions:\s*\[UIApplication\.LaunchOptionsKey\s*:?\s*Any\]\?\s*(?:=\s*nil)?\s*\)\s*->\s*Bool\s*\{\s)/
2020

2121
const BUGSNAG_JAVA_IMPORT = 'import com.bugsnag.android.Bugsnag;'
2222
const BUGSNAG_JAVA_INIT = 'Bugsnag.start(this);'

packages/react-native-cli/src/lib/__test__/Insert.test.ts

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,15 @@ test('insertIos(): success', async () => {
9494
)
9595
})
9696

97-
test('insertIos(): success (swift)', async () => {
97+
test('insertIos(): success (swift 0.78)', async () => {
9898
type readdir = (path: string) => Promise<string[]>
9999
const readdirMock = fs.readdir as unknown as jest.MockedFunction<readdir>
100100

101101
readdirMock
102102
.mockResolvedValueOnce(['BugsnagReactNativeCliTest.xcodeproj'])
103103
.mockResolvedValueOnce(['a', 'b', 'AppDelegate.swift', 'c', 'd'])
104104

105-
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-before.swift'))
105+
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-before-078.swift'))
106106
const readFileMock = fs.readFile as jest.MockedFunction<typeof fs.readFile>
107107
readFileMock.mockResolvedValue(appDelegate)
108108

@@ -113,7 +113,31 @@ test('insertIos(): success (swift)', async () => {
113113
expect(readFileMock).toHaveBeenCalledWith('/random/path/ios/BugsnagReactNativeCliTest/AppDelegate.swift', 'utf8')
114114
expect(writeFileMock).toHaveBeenCalledWith(
115115
'/random/path/ios/BugsnagReactNativeCliTest/AppDelegate.swift',
116-
await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after.swift')),
116+
await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after-078.swift')),
117+
'utf8'
118+
)
119+
})
120+
121+
test('insertIos(): success (swift 0.79+)', async () => {
122+
type readdir = (path: string) => Promise<string[]>
123+
const readdirMock = fs.readdir as unknown as jest.MockedFunction<readdir>
124+
125+
readdirMock
126+
.mockResolvedValueOnce(['BugsnagReactNativeCliTest.xcodeproj'])
127+
.mockResolvedValueOnce(['a', 'b', 'AppDelegate.swift', 'c', 'd'])
128+
129+
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-before-079.swift'))
130+
const readFileMock = fs.readFile as jest.MockedFunction<typeof fs.readFile>
131+
readFileMock.mockResolvedValue(appDelegate)
132+
133+
const writeFileMock = fs.writeFile as jest.MockedFunction<typeof fs.writeFile>
134+
writeFileMock.mockResolvedValue()
135+
136+
await insertIos('/random/path', logger)
137+
expect(readFileMock).toHaveBeenCalledWith('/random/path/ios/BugsnagReactNativeCliTest/AppDelegate.swift', 'utf8')
138+
expect(writeFileMock).toHaveBeenCalledWith(
139+
'/random/path/ios/BugsnagReactNativeCliTest/AppDelegate.swift',
140+
await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after-079.swift')),
117141
'utf8'
118142
)
119143
})
@@ -140,15 +164,37 @@ test('insertIos(): already present', async () => {
140164
expect(logger.warn).toHaveBeenCalledWith('Bugsnag is already included, skipping')
141165
})
142166

143-
test('insertIos(): already present (swift)', async () => {
167+
test('insertIos(): already present (swift 0.78)', async () => {
168+
type readdir = (path: string) => Promise<string[]>
169+
const readdirMock = fs.readdir as unknown as jest.MockedFunction<readdir>
170+
171+
readdirMock
172+
.mockResolvedValueOnce(['BugsnagReactNativeCliTest.xcodeproj'])
173+
.mockResolvedValueOnce(['a', 'b', 'AppDelegate.swift', 'c', 'd'])
174+
175+
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after-078.swift'))
176+
const readFileMock = fs.readFile as jest.MockedFunction<typeof fs.readFile>
177+
readFileMock.mockResolvedValue(appDelegate)
178+
179+
const writeFileMock = fs.writeFile as jest.MockedFunction<typeof fs.writeFile>
180+
writeFileMock.mockResolvedValue()
181+
182+
await insertIos('/random/path', logger)
183+
expect(readFileMock).toHaveBeenCalledWith('/random/path/ios/BugsnagReactNativeCliTest/AppDelegate.swift', 'utf8')
184+
expect(writeFileMock).not.toHaveBeenCalled()
185+
186+
expect(logger.warn).toHaveBeenCalledWith('Bugsnag is already included, skipping')
187+
})
188+
189+
test('insertIos(): already present (swift 0.79+)', async () => {
144190
type readdir = (path: string) => Promise<string[]>
145191
const readdirMock = fs.readdir as unknown as jest.MockedFunction<readdir>
146192

147193
readdirMock
148194
.mockResolvedValueOnce(['BugsnagReactNativeCliTest.xcodeproj'])
149195
.mockResolvedValueOnce(['a', 'b', 'AppDelegate.swift', 'c', 'd'])
150196

151-
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after.swift'))
197+
const appDelegate = await loadFixture(path.join(__dirname, 'fixtures', 'AppDelegate-after-079.swift'))
152198
const readFileMock = fs.readFile as jest.MockedFunction<typeof fs.readFile>
153199
readFileMock.mockResolvedValue(appDelegate)
154200

packages/react-native-cli/src/lib/__test__/fixtures/AppDelegate-after.swift renamed to packages/react-native-cli/src/lib/__test__/fixtures/AppDelegate-after-078.swift

File renamed without changes.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import Bugsnag
2+
import UIKit
3+
import React
4+
import React_RCTAppDelegate
5+
import ReactAppDependencyProvider
6+
7+
@main
8+
class AppDelegate: UIResponder, UIApplicationDelegate {
9+
var window: UIWindow?
10+
11+
var reactNativeDelegate: ReactNativeDelegate?
12+
var reactNativeFactory: RCTReactNativeFactory?
13+
14+
func application(
15+
_ application: UIApplication,
16+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
17+
) -> Bool {
18+
Bugsnag.start()
19+
20+
let delegate = ReactNativeDelegate()
21+
let factory = RCTReactNativeFactory(delegate: delegate)
22+
delegate.dependencyProvider = RCTAppDependencyProvider()
23+
24+
reactNativeDelegate = delegate
25+
reactNativeFactory = factory
26+
27+
window = UIWindow(frame: UIScreen.main.bounds)
28+
29+
factory.startReactNative(
30+
withModuleName: "reactnative",
31+
in: window,
32+
launchOptions: launchOptions
33+
)
34+
35+
return true
36+
}
37+
}
38+
39+
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
40+
override func sourceURL(for bridge: RCTBridge) -> URL? {
41+
self.bundleURL()
42+
}
43+
44+
override func bundleURL() -> URL? {
45+
#if DEBUG
46+
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
47+
#else
48+
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
49+
#endif
50+
}
51+
}

packages/react-native-cli/src/lib/__test__/fixtures/AppDelegate-before.swift renamed to packages/react-native-cli/src/lib/__test__/fixtures/AppDelegate-before-078.swift

File renamed without changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import UIKit
2+
import React
3+
import React_RCTAppDelegate
4+
import ReactAppDependencyProvider
5+
6+
@main
7+
class AppDelegate: UIResponder, UIApplicationDelegate {
8+
var window: UIWindow?
9+
10+
var reactNativeDelegate: ReactNativeDelegate?
11+
var reactNativeFactory: RCTReactNativeFactory?
12+
13+
func application(
14+
_ application: UIApplication,
15+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
16+
) -> Bool {
17+
let delegate = ReactNativeDelegate()
18+
let factory = RCTReactNativeFactory(delegate: delegate)
19+
delegate.dependencyProvider = RCTAppDependencyProvider()
20+
21+
reactNativeDelegate = delegate
22+
reactNativeFactory = factory
23+
24+
window = UIWindow(frame: UIScreen.main.bounds)
25+
26+
factory.startReactNative(
27+
withModuleName: "reactnative",
28+
in: window,
29+
launchOptions: launchOptions
30+
)
31+
32+
return true
33+
}
34+
}
35+
36+
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
37+
override func sourceURL(for bridge: RCTBridge) -> URL? {
38+
self.bundleURL()
39+
}
40+
41+
override func bundleURL() -> URL? {
42+
#if DEBUG
43+
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
44+
#else
45+
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
46+
#endif
47+
}
48+
}

0 commit comments

Comments
 (0)