Flutter Engine
The Flutter Engine
FlutterDartProjectTest.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <OCMock/OCMock.h>
6#import <XCTest/XCTest.h>
7
8#include "flutter/common/constants.h"
9#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
10#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
11
13
14@interface FlutterDartProjectTest : XCTestCase
15@end
16
17@implementation FlutterDartProjectTest
18
19- (void)setUp {
20}
21
22- (void)tearDown {
23}
24
26 FlutterDartProject* project = [[FlutterDartProject alloc] init];
27 int64_t old_gen_heap_size =
28 std::round([NSProcessInfo processInfo].physicalMemory * .48 / flutter::kMegaByteSizeInBytes);
29 XCTAssertEqual(project.settings.old_gen_heap_size, old_gen_heap_size);
30}
31
33 FlutterDartProject* project = [[FlutterDartProject alloc] init];
34 CGFloat scale = [UIScreen mainScreen].scale;
35 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width * scale;
36 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height * scale;
37 size_t resource_cache_max_bytes_threshold = screenWidth * screenHeight * 12 * 4;
38 XCTAssertEqual(project.settings.resource_cache_max_bytes_threshold,
39 resource_cache_max_bytes_threshold);
40}
41
43 NSBundle* mainBundle = [NSBundle mainBundle];
44 NSDictionary* appTransportSecurity =
45 [mainBundle objectForInfoDictionaryKey:@"NSAppTransportSecurity"];
46 XCTAssertTrue([FlutterDartProject allowsArbitraryLoads:appTransportSecurity]);
47 XCTAssertEqualObjects(
48 @"[[\"invalid-site.com\",true,false],[\"sub.invalid-site.com\",false,false]]",
49 [FlutterDartProject domainNetworkPolicy:appTransportSecurity]);
50}
51
53 // The FLTLeakDartVM's value is defined in Info.plist
54 NSBundle* mainBundle = [NSBundle mainBundle];
55 NSNumber* leakDartVM = [mainBundle objectForInfoDictionaryKey:@"FLTLeakDartVM"];
56 XCTAssertEqual(leakDartVM.boolValue, NO);
57
59 // Check settings.leak_vm value is same as the value defined in Info.plist.
60 XCTAssertEqual(settings.leak_vm, NO);
61}
62
64 NSBundle* found =
65 FLTFrameworkBundleInternal(@"doesNotExist", NSBundle.mainBundle.privateFrameworksURL);
66 XCTAssertNil(found);
67}
68
70 NSString* presentBundleID = @"io.flutter.flutter";
71 NSBundle* found =
72 FLTFrameworkBundleInternal(presentBundleID, NSBundle.mainBundle.privateFrameworksURL);
73 XCTAssertNotNil(found);
74}
75
77 NSBundle* bundle = FLTGetApplicationBundle();
78 XCTAssertEqual(bundle, [NSBundle mainBundle]);
79}
80
82 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
83 NSURL* url = [[NSBundle mainBundle].bundleURL URLByAppendingPathComponent:@"foo/ext.appex"];
84 OCMStub([mockMainBundle bundleURL]).andReturn(url);
85 NSBundle* bundle = FLTGetApplicationBundle();
86 [mockMainBundle stopMocking];
87 XCTAssertEqualObjects(bundle.bundleURL, [NSBundle mainBundle].bundleURL);
88}
89
91 {
92 // Found asset path in info.plist
93 id mockBundle = OCMClassMock([NSBundle class]);
94 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
95 NSString* resultAssetsPath = @"path/to/foo/assets";
96 OCMStub([mockBundle pathForResource:@"foo/assets" ofType:nil]).andReturn(resultAssetsPath);
97 NSString* path = FLTAssetsPathFromBundle(mockBundle);
98 XCTAssertEqualObjects(path, @"path/to/foo/assets");
99 }
100 {
101 // Found asset path in info.plist, is not overriden by main bundle
102 id mockBundle = OCMClassMock([NSBundle class]);
103 id mockMainBundle = OCMPartialMock(NSBundle.mainBundle);
104 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
105 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
106 NSString* resultAssetsPath = @"path/to/foo/assets";
107 OCMStub([mockBundle pathForResource:@"foo/assets" ofType:nil]).andReturn(resultAssetsPath);
108 NSString* path = FLTAssetsPathFromBundle(mockBundle);
109 XCTAssertEqualObjects(path, @"path/to/foo/assets");
110 [mockMainBundle stopMocking];
111 }
112 {
113 // No asset path in info.plist, defaults to main bundle
114 id mockBundle = OCMClassMock([NSBundle class]);
115 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
116 NSString* resultAssetsPath = @"path/to/foo/assets";
117 OCMStub([mockBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:nil])
118 .andReturn(nil);
119 OCMStub([mockMainBundle pathForResource:@"Frameworks/App.framework/flutter_assets" ofType:nil])
120 .andReturn(resultAssetsPath);
121 NSString* path = FLTAssetsPathFromBundle(mockBundle);
122 XCTAssertEqualObjects(path, @"path/to/foo/assets");
123 [mockMainBundle stopMocking];
124 }
125}
126
128 {
129 // Found assets path in info.plist
130 id mockBundle = OCMClassMock([NSBundle class]);
131 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
132 XCTAssertEqualObjects(FLTAssetPath(mockBundle), @"foo/assets");
133 }
134 {
135 // No assets path in info.plist, use default value
136 id mockBundle = OCMClassMock([NSBundle class]);
137 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
138 XCTAssertEqualObjects(FLTAssetPath(mockBundle), kDefaultAssetPath);
139 }
140}
141
142- (void)testLookUpForAssets {
143 {
144 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
145 // Found assets path in info.plist
146 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
147 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar"];
148 // This is testing public API, changing this assert is likely to break plugins.
149 XCTAssertEqualObjects(assetsPath, @"foo/assets/bar");
150 [mockBundle stopMocking];
151 }
152 {
153 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
154 // No assets path in info.plist, use default value
155 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
156 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar"];
157 // This is testing public API, changing this assert is likely to break plugins.
158 XCTAssertEqualObjects(assetsPath, @"Frameworks/App.framework/flutter_assets/bar");
159 [mockBundle stopMocking];
160 }
161}
162
164 {
165 id mockBundle = OCMClassMock([NSBundle class]);
166 // Found assets path in info.plist
167 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
168 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar" fromBundle:mockBundle];
169 // This is testing public API, changing this assert is likely to break plugins.
170 XCTAssertEqualObjects(assetsPath, @"foo/assets/bar");
171 }
172 {
173 // No assets path in info.plist, use default value
174 id mockBundle = OCMClassMock([NSBundle class]);
175 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
176 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar" fromBundle:mockBundle];
177 // This is testing public API, changing this assert is likely to break plugins.
178 XCTAssertEqualObjects(assetsPath, @"Frameworks/App.framework/flutter_assets/bar");
179 }
180}
181
183 {
184 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
185 // Found assets path in info.plist
186 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
187 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar" fromPackage:@"bar_package"];
188 // This is testing public API, changing this assert is likely to break plugins.
189 XCTAssertEqualObjects(assetsPath, @"foo/assets/packages/bar_package/bar");
190 [mockBundle stopMocking];
191 }
192 {
193 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
194 // No assets path in info.plist, use default value
195 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
196 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar" fromPackage:@"bar_package"];
197 // This is testing public API, changing this assert is likely to break plugins.
198 XCTAssertEqualObjects(assetsPath,
199 @"Frameworks/App.framework/flutter_assets/packages/bar_package/bar");
200 [mockBundle stopMocking];
201 }
202}
203
205 {
206 id mockBundle = OCMClassMock([NSBundle class]);
207 // Found assets path in info.plist
208 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
209 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar"
210 fromPackage:@"bar_package"
211 fromBundle:mockBundle];
212 // This is testing public API, changing this assert is likely to break plugins.
213 XCTAssertEqualObjects(assetsPath, @"foo/assets/packages/bar_package/bar");
214 }
215 {
216 id mockBundle = OCMClassMock([NSBundle class]);
217 // No assets path in info.plist, use default value
218 OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(nil);
219 NSString* assetsPath = [FlutterDartProject lookupKeyForAsset:@"bar"
220 fromPackage:@"bar_package"
221 fromBundle:mockBundle];
222 // This is testing public API, changing this assert is likely to break plugins.
223 XCTAssertEqualObjects(assetsPath,
224 @"Frameworks/App.framework/flutter_assets/packages/bar_package/bar");
225 }
226}
227
229 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
230 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"NO");
231
233 // Check settings.enable_impeller value is same as the value defined in Info.plist.
234 XCTAssertEqual(settings.enable_impeller, NO);
235 [mockMainBundle stopMocking];
236}
237
240 XCTAssertEqual(settings.warn_on_impeller_opt_out, YES);
241}
242
244 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
245 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES");
246
248 // Check settings.enable_impeller value is same as the value defined in Info.plist.
249 XCTAssertEqual(settings.enable_impeller, YES);
250 [mockMainBundle stopMocking];
251}
252
254 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
255 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"NO");
256 id mockProcessInfo = OCMPartialMock([NSProcessInfo processInfo]);
257 NSArray* arguments = @[ @"process_name", @"--enable-impeller" ];
258 OCMStub([mockProcessInfo arguments]).andReturn(arguments);
259
260 auto settings = FLTDefaultSettingsForBundle(nil, mockProcessInfo);
261 // Check settings.enable_impeller value is same as the value on command line.
262 XCTAssertEqual(settings.enable_impeller, YES);
263 [mockMainBundle stopMocking];
264}
265
267 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
268 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableDartAsserts"]).andReturn(@"YES");
269 id mockProcessInfo = OCMPartialMock([NSProcessInfo processInfo]);
270 NSArray* arguments = @[ @"process_name" ];
271 OCMStub([mockProcessInfo arguments]).andReturn(arguments);
272
273 auto settings = FLTDefaultSettingsForBundle(nil, mockProcessInfo);
274
275 XCTAssertEqual(settings.dart_flags.size(), 1u);
276 XCTAssertEqual(settings.dart_flags[0], "--enable-asserts");
277 [mockMainBundle stopMocking];
278}
279
281 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
282 OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES");
283 id mockProcessInfo = OCMPartialMock([NSProcessInfo processInfo]);
284 NSArray* arguments = @[ @"process_name", @"--enable-impeller=false" ];
285 OCMStub([mockProcessInfo arguments]).andReturn(arguments);
286
287 auto settings = FLTDefaultSettingsForBundle(nil, mockProcessInfo);
288 // Check settings.enable_impeller value is same as the value on command line.
289 XCTAssertEqual(settings.enable_impeller, NO);
290 [mockMainBundle stopMocking];
291}
292
294 NSString* bundleId = [FlutterDartProject defaultBundleIdentifier];
295 id mockAppBundle = OCMClassMock([NSBundle class]);
296 OCMStub([mockAppBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"NO");
297 OCMStub([mockAppBundle bundleWithIdentifier:bundleId]).andReturn(mockAppBundle);
298
300 // Check settings.enable_impeller value is same as the value defined in Info.plist.
301 XCTAssertEqual(settings.enable_impeller, NO);
302
303 [mockAppBundle stopMocking];
304}
305
307 NSString* bundleId = [FlutterDartProject defaultBundleIdentifier];
308 id mockAppBundle = OCMClassMock([NSBundle class]);
309 OCMStub([mockAppBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES");
310 OCMStub([mockAppBundle bundleWithIdentifier:bundleId]).andReturn(mockAppBundle);
311
312 // Since FLTEnableImpeller is set to false in the main bundle, this is also
313 // testing that setting FLTEnableImpeller in the app bundle takes
314 // precedence over setting it in the root bundle.
315
317 // Check settings.enable_impeller value is same as the value defined in Info.plist.
318 XCTAssertEqual(settings.enable_impeller, YES);
319
320 [mockAppBundle stopMocking];
321}
322
324 NSBundle* mainBundle = [NSBundle mainBundle];
325 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"];
326 XCTAssertNotNil(enableTraceSystrace);
327 XCTAssertEqual(enableTraceSystrace.boolValue, NO);
329 XCTAssertEqual(settings.trace_systrace, NO);
330}
331
333 NSBundle* mainBundle = [NSBundle mainBundle];
334 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartProfiling"];
335 XCTAssertNotNil(enableTraceSystrace);
336 XCTAssertEqual(enableTraceSystrace.boolValue, NO);
338 XCTAssertEqual(settings.trace_systrace, NO);
339}
340
342 XCTAssertFalse([FlutterDartProject allowsArbitraryLoads:[[NSDictionary alloc] init]]);
343 XCTAssertEqualObjects(@"", [FlutterDartProject domainNetworkPolicy:[[NSDictionary alloc] init]]);
344}
345
347 XCTAssertFalse([FlutterDartProject allowsArbitraryLoads:@{@"NSAllowsArbitraryLoads" : @false}]);
348 XCTAssertTrue([FlutterDartProject allowsArbitraryLoads:@{@"NSAllowsArbitraryLoads" : @true}]);
349}
350
352 NSDictionary* domainInfoOne = @{
353 @"NSIncludesSubdomains" : @false,
354 @"NSExceptionAllowsInsecureHTTPLoads" : @true,
355 @"NSExceptionMinimumTLSVersion" : @"4.0"
356 };
357 NSDictionary* domainInfoTwo = @{
358 @"NSIncludesSubdomains" : @true,
359 @"NSExceptionAllowsInsecureHTTPLoads" : @false,
360 @"NSExceptionMinimumTLSVersion" : @"4.0"
361 };
362 NSDictionary* domainInfoThree = @{
363 @"NSIncludesSubdomains" : @false,
364 @"NSExceptionAllowsInsecureHTTPLoads" : @true,
365 @"NSExceptionMinimumTLSVersion" : @"4.0"
366 };
367 NSDictionary* exceptionDomains = @{
368 @"domain.name" : domainInfoOne,
369 @"sub.domain.name" : domainInfoTwo,
370 @"sub.two.domain.name" : domainInfoThree
371 };
372 NSDictionary* appTransportSecurity = @{@"NSExceptionDomains" : exceptionDomains};
373 XCTAssertEqualObjects(@"[[\"domain.name\",false,true],[\"sub.domain.name\",true,false],"
374 @"[\"sub.two.domain.name\",false,true]]",
375 [FlutterDartProject domainNetworkPolicy:appTransportSecurity]);
376}
377
379 NSDictionary* domainInfoOne = @{@"NSExceptionMinimumTLSVersion" : @"4.0"};
380 NSDictionary* domainInfoTwo = @{
381 @"NSIncludesSubdomains" : @true,
382 };
383 NSDictionary* domainInfoThree = @{};
384 NSDictionary* exceptionDomains = @{
385 @"domain.name" : domainInfoOne,
386 @"sub.domain.name" : domainInfoTwo,
387 @"sub.two.domain.name" : domainInfoThree
388 };
389 NSDictionary* appTransportSecurity = @{@"NSExceptionDomains" : exceptionDomains};
390 XCTAssertEqualObjects(@"[[\"domain.name\",false,false],[\"sub.domain.name\",true,false],"
391 @"[\"sub.two.domain.name\",false,false]]",
392 [FlutterDartProject domainNetworkPolicy:appTransportSecurity]);
393}
394
395@end
static bool invalid(const SkISize &size)
NSString * FLTAssetsPathFromBundle(NSBundle *bundle)
NSBundle * FLTGetApplicationBundle()
NS_ASSUME_NONNULL_BEGIN const NSString * kDefaultAssetPath
NSBundle * FLTFrameworkBundleInternal(NSString *flutterFrameworkBundleID, NSURL *searchURL)
NSString * FLTAssetPath(NSBundle *bundle)
static void round(SkPoint *p)
void testEnableImpellerSettingIsCorrectlyOverriddenByCommandLine()
void testFLTFrameworkBundleInternalWhenBundleIsNotPresent()
void testFLTGetApplicationBundleWhenCurrentTargetIsExtension()
void testFLTGetApplicationBundleWhenCurrentTargetIsNotExtension()
void testDisableImpellerSettingIsCorrectlyOverriddenByCommandLine()
NSString * lookupKeyForAsset:fromBundle:(NSString *asset,[fromBundle] nullable NSBundle *bundle)
NSString * defaultBundleIdentifier()
const flutter::Settings & settings()
NSString * lookupKeyForAsset:fromPackage:(NSString *asset,[fromPackage] NSString *package)
NSString * lookupKeyForAsset:fromPackage:fromBundle:(NSString *asset,[fromPackage] NSString *package,[fromBundle] nullable NSBundle *bundle)
NSString * lookupKeyForAsset:(NSString *asset)
flutter::Settings FLTDefaultSettingsForBundle(NSBundle *bundle, NSProcessInfo *processInfoOrNil)
static bool init()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
constexpr double kMegaByteSizeInBytes
Definition: constants.h:9
const Scalar scale
int64_t old_gen_heap_size
Definition: settings.h:344
size_t resource_cache_max_bytes_threshold
Definition: settings.h:347