Skip to content

Commit b5384ad

Browse files
committed
test(CLI): extract pure functions for appdelegate modification and update tests
1 parent 09ecb02 commit b5384ad

File tree

2 files changed

+117
-12
lines changed

2 files changed

+117
-12
lines changed

cli/commands/initCommand/initIos.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,32 @@ function findAppDelegate(searchPath) {
3535
return appDelegateFile ? path.join(searchPath, appDelegateFile) : null;
3636
}
3737

38-
async function setupObjectiveC(appDelegatePath) {
39-
const appDelegateContent = fs.readFileSync(appDelegatePath, 'utf-8');
38+
function modifyObjectiveCAppDelegate(appDelegateContent) {
4039
const IMPORT_STATEMENT = '#import <CodePush/CodePush.h>';
4140
if (appDelegateContent.includes(IMPORT_STATEMENT)) {
4241
console.log('AppDelegate already has CodePush imported.');
43-
return;
42+
return appDelegateContent;
4443
}
4544

46-
const newContent = appDelegateContent
45+
return appDelegateContent
4746
.replace('#import "AppDelegate.h"\n', `#import "AppDelegate.h"\n${IMPORT_STATEMENT}\n`)
4847
.replace('[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];', '[CodePush bundleURL];');
48+
}
4949

50+
function modifySwiftAppDelegate(appDelegateContent) {
51+
const CODEPUSH_CALL_STATEMENT = 'CodePush.bundleURL()';
52+
if (appDelegateContent.includes(CODEPUSH_CALL_STATEMENT)) {
53+
console.log('AppDelegate.swift already configured for CodePush.');
54+
return appDelegateContent;
55+
}
56+
57+
return appDelegateContent
58+
.replace('Bundle.main.url(forResource: "main", withExtension: "jsbundle")', CODEPUSH_CALL_STATEMENT);
59+
}
60+
61+
async function setupObjectiveC(appDelegatePath) {
62+
const appDelegateContent = fs.readFileSync(appDelegatePath, 'utf-8');
63+
const newContent = modifyObjectiveCAppDelegate(appDelegateContent);
5064
fs.writeFileSync(appDelegatePath, newContent);
5165
console.log('Successfully updated AppDelegate.m/mm.');
5266
}
@@ -59,14 +73,7 @@ async function setupSwift(appDelegatePath, projectDir, projectName) {
5973
}
6074

6175
const appDelegateContent = fs.readFileSync(appDelegatePath, 'utf-8');
62-
const CODEPUSH_CALL_STATEMENT = 'CodePush.bundleURL()';
63-
if (appDelegateContent.includes(CODEPUSH_CALL_STATEMENT)) {
64-
console.log('AppDelegate.swift already configured for CodePush.');
65-
return;
66-
}
67-
68-
const newContent = appDelegateContent
69-
.replace('Bundle.main.url(forResource: "main", withExtension: "jsbundle")', CODEPUSH_CALL_STATEMENT);
76+
const newContent = modifySwiftAppDelegate(appDelegateContent);
7077
fs.writeFileSync(appDelegatePath, newContent);
7178
console.log('Successfully updated AppDelegate.swift.');
7279
}
@@ -116,4 +123,6 @@ async function ensureBridgingHeader(projectDir, projectName) {
116123

117124
module.exports = {
118125
initIos: initIos,
126+
modifyObjectiveCAppDelegate,
127+
modifySwiftAppDelegate,
119128
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
const { modifyObjectiveCAppDelegate, modifySwiftAppDelegate } = require('../initIos');
2+
3+
const swiftTemplate = `
4+
import UIKit
5+
import React
6+
import React_RCTAppDelegate
7+
import ReactAppDependencyProvider
8+
9+
@main
10+
class AppDelegate: UIResponder, UIApplicationDelegate {
11+
var window: UIWindow?
12+
var reactNativeDelegate: ReactNativeDelegate?
13+
var reactNativeFactory: RCTReactNativeFactory?
14+
15+
func application(
16+
_ application: UIApplication,
17+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
18+
) -> Bool {
19+
let delegate = ReactNativeDelegate()
20+
let factory = RCTReactNativeFactory(delegate: delegate)
21+
delegate.dependencyProvider = RCTAppDependencyProvider()
22+
reactNativeDelegate = delegate
23+
reactNativeFactory = factory
24+
window = UIWindow(frame: UIScreen.main.bounds)
25+
factory.startReactNative(
26+
withModuleName: "HelloWorld",
27+
in: window,
28+
launchOptions: launchOptions
29+
)
30+
return true
31+
}
32+
}
33+
34+
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
35+
override func sourceURL(for bridge: RCTBridge) -> URL? {
36+
self.bundleURL()
37+
}
38+
39+
override func bundleURL() -> URL? {
40+
#if DEBUG
41+
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
42+
#else
43+
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
44+
#endif
45+
}
46+
}
47+
`;
48+
49+
const objcTemplate = `
50+
#import "AppDelegate.h"
51+
52+
#import <React/RCTBundleURLProvider.h>
53+
54+
@implementation AppDelegate
55+
56+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
57+
{
58+
self.moduleName = @"HelloWorld";
59+
// You can add your custom initial props in the dictionary below.
60+
// They will be passed down to the ViewController used by React Native.
61+
self.initialProps = @{};
62+
63+
return [super application:application didFinishLaunchingWithOptions:launchOptions];
64+
}
65+
66+
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
67+
{
68+
return [self bundleURL];
69+
}
70+
71+
- (NSURL *)bundleURL
72+
{
73+
#if DEBUG
74+
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
75+
#else
76+
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
77+
#endif
78+
}
79+
80+
@end
81+
`;
82+
83+
describe('iOS init command - pure functions', () => {
84+
it('should correctly modify Swift AppDelegate content', () => {
85+
const modifiedContent = modifySwiftAppDelegate(swiftTemplate);
86+
expect(modifiedContent).toContain('CodePush.bundleURL()');
87+
expect(modifiedContent).not.toContain('Bundle.main.url(forResource: "main", withExtension: "jsbundle")');
88+
});
89+
90+
it('should correctly modify Objective-C AppDelegate content', () => {
91+
const modifiedContent = modifyObjectiveCAppDelegate(objcTemplate);
92+
expect(modifiedContent).toContain('#import <CodePush/CodePush.h>');
93+
expect(modifiedContent).toContain('[CodePush bundleURL]');
94+
expect(modifiedContent).not.toContain('[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];');
95+
});
96+
});

0 commit comments

Comments
 (0)