1// Copyright 2014 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
5import 'package:file/memory.dart';
6import 'package:file_testing/file_testing.dart';
7import 'package:flutter_tools/src/artifacts.dart';
8import 'package:flutter_tools/src/base/file_system.dart';
9import 'package:flutter_tools/src/base/logger.dart';
10import 'package:flutter_tools/src/build_info.dart';
11import 'package:flutter_tools/src/build_system/build_system.dart';
12import 'package:flutter_tools/src/build_system/targets/common.dart';
13import 'package:flutter_tools/src/build_system/targets/windows.dart';
14
15import '../../../src/common.dart';
16import '../../../src/context.dart';
17
18void main() {
19 testWithoutContext(
20 'UnpackWindows copies files to the correct windows/ cache directory',
21 () async {
22 final artifacts = Artifacts.test();
23 final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
24 final environment = Environment.test(
25 fileSystem.currentDirectory,
26 artifacts: artifacts,
27 processManager: FakeProcessManager.any(),
28 fileSystem: fileSystem,
29 logger: BufferLogger.test(),
30 defines: <String, String>{kBuildMode: 'debug'},
31 );
32 environment.buildDir.createSync(recursive: true);
33
34 final String windowsDesktopPath = artifacts.getArtifactPath(
35 Artifact.windowsDesktopPath,
36 platform: TargetPlatform.windows_x64,
37 mode: BuildMode.debug,
38 );
39 final String windowsCppClientWrapper = artifacts.getArtifactPath(
40 Artifact.windowsCppClientWrapper,
41 platform: TargetPlatform.windows_x64,
42 mode: BuildMode.debug,
43 );
44 final String icuData = artifacts.getArtifactPath(
45 Artifact.icuData,
46 platform: TargetPlatform.windows_x64,
47 );
48 final requiredFiles = <String>[
49 '$windowsDesktopPath\\flutter_export.h',
50 '$windowsDesktopPath\\flutter_messenger.h',
51 '$windowsDesktopPath\\flutter_windows.dll',
52 '$windowsDesktopPath\\flutter_windows.dll.exp',
53 '$windowsDesktopPath\\flutter_windows.dll.lib',
54 '$windowsDesktopPath\\flutter_windows.dll.pdb',
55 '$windowsDesktopPath\\flutter_plugin_registrar.h',
56 '$windowsDesktopPath\\flutter_texture_registrar.h',
57 '$windowsDesktopPath\\flutter_windows.h',
58 icuData,
59 '$windowsCppClientWrapper\\foo',
60 r'C:\packages\flutter_tools\lib\src\build_system\targets\windows.dart',
61 ];
62
63 for (final path in requiredFiles) {
64 fileSystem.file(path).createSync(recursive: true);
65 }
66 fileSystem.directory('windows').createSync();
67
68 await const UnpackWindows(TargetPlatform.windows_x64).build(environment);
69
70 // Output files are copied correctly.
71 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_export.h'), exists);
72 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_messenger.h'), exists);
73 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_windows.dll'), exists);
74 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_windows.dll.exp'), exists);
75 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_windows.dll.lib'), exists);
76 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_windows.dll.pdb'), exists);
77 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_export.h'), exists);
78 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_messenger.h'), exists);
79 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_plugin_registrar.h'), exists);
80 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_texture_registrar.h'), exists);
81 expect(fileSystem.file(r'C:\windows\flutter\ephemeral\flutter_windows.h'), exists);
82 expect(fileSystem.file('C:\\windows\\flutter\\ephemeral\\$icuData'), exists);
83 expect(
84 fileSystem.file('C:\\windows\\flutter\\ephemeral\\$windowsCppClientWrapper\\foo'),
85 exists,
86 );
87
88 final File outputDepfile = environment.buildDir.childFile('windows_engine_sources.d');
89
90 // Depfile is created correctly.
91 expect(outputDepfile, exists);
92
93 final List<String> inputPaths = environment.depFileService
94 .parse(outputDepfile)
95 .inputs
96 .map((File file) => file.path)
97 .toList();
98 final List<String> outputPaths = environment.depFileService
99 .parse(outputDepfile)
100 .outputs
101 .map((File file) => file.path)
102 .toList();
103
104 // Depfile has expected sources.
105 expect(
106 inputPaths,
107 unorderedEquals(<String>[
108 '$windowsDesktopPath\\flutter_export.h',
109 '$windowsDesktopPath\\flutter_messenger.h',
110 '$windowsDesktopPath\\flutter_windows.dll',
111 '$windowsDesktopPath\\flutter_windows.dll.exp',
112 '$windowsDesktopPath\\flutter_windows.dll.lib',
113 '$windowsDesktopPath\\flutter_windows.dll.pdb',
114 '$windowsDesktopPath\\flutter_plugin_registrar.h',
115 '$windowsDesktopPath\\flutter_texture_registrar.h',
116 '$windowsDesktopPath\\flutter_windows.h',
117 icuData,
118 '$windowsCppClientWrapper\\foo',
119 ]),
120 );
121 expect(
122 outputPaths,
123 unorderedEquals(<String>[
124 r'C:\windows\flutter\ephemeral\flutter_export.h',
125 r'C:\windows\flutter\ephemeral\flutter_messenger.h',
126 r'C:\windows\flutter\ephemeral\flutter_windows.dll',
127 r'C:\windows\flutter\ephemeral\flutter_windows.dll.exp',
128 r'C:\windows\flutter\ephemeral\flutter_windows.dll.lib',
129 r'C:\windows\flutter\ephemeral\flutter_windows.dll.pdb',
130 r'C:\windows\flutter\ephemeral\flutter_plugin_registrar.h',
131 r'C:\windows\flutter\ephemeral\flutter_texture_registrar.h',
132 r'C:\windows\flutter\ephemeral\flutter_windows.h',
133 'C:\\windows\\flutter\\ephemeral\\$icuData',
134 'C:\\windows\\flutter\\ephemeral\\$windowsCppClientWrapper\\foo',
135 ]),
136 );
137 },
138 );
139
140 // AssetBundleFactory still uses context injection
141 late FileSystem fileSystem;
142
143 setUp(() {
144 fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
145 });
146
147 testUsingContext(
148 'DebugBundleWindowsAssets creates correct bundle structure',
149 () async {
150 final environment = Environment.test(
151 fileSystem.currentDirectory,
152 artifacts: Artifacts.test(),
153 processManager: FakeProcessManager.any(),
154 fileSystem: fileSystem,
155 logger: BufferLogger.test(),
156 defines: <String, String>{kBuildMode: 'debug'},
157 engineVersion: '2',
158 );
159
160 environment.buildDir.childFile('app.dill').createSync(recursive: true);
161 environment.buildDir.childFile('native_assets.json').createSync(recursive: true);
162
163 await const DebugBundleWindowsAssets(TargetPlatform.windows_x64).build(environment);
164
165 // Depfile is created and dill is copied.
166 expect(environment.buildDir.childFile('flutter_assets.d'), exists);
167 expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin'), exists);
168 expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
169 },
170 overrides: <Type, Generator>{
171 FileSystem: () => fileSystem,
172 ProcessManager: () => FakeProcessManager.any(),
173 },
174 );
175
176 testUsingContext(
177 'ProfileBundleWindowsAssets creates correct bundle structure',
178 () async {
179 final environment = Environment.test(
180 fileSystem.currentDirectory,
181 artifacts: Artifacts.test(),
182 processManager: FakeProcessManager.any(),
183 fileSystem: fileSystem,
184 logger: BufferLogger.test(),
185 defines: <String, String>{kBuildMode: 'profile'},
186 );
187
188 environment.buildDir.childFile('app.so').createSync(recursive: true);
189 environment.buildDir.childFile('native_assets.json').createSync(recursive: true);
190
191 await const WindowsAotBundle(AotElfProfile(TargetPlatform.windows_x64)).build(environment);
192 await const ProfileBundleWindowsAssets(TargetPlatform.windows_x64).build(environment);
193
194 // Depfile is created and so is copied.
195 expect(environment.buildDir.childFile('flutter_assets.d'), exists);
196 expect(fileSystem.file(r'C:\windows\app.so'), exists);
197 expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin').existsSync(), false);
198 expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
199 },
200 overrides: <Type, Generator>{
201 FileSystem: () => fileSystem,
202 ProcessManager: () => FakeProcessManager.any(),
203 },
204 );
205
206 testUsingContext(
207 'ReleaseBundleWindowsAssets creates correct bundle structure',
208 () async {
209 final environment = Environment.test(
210 fileSystem.currentDirectory,
211 artifacts: Artifacts.test(),
212 processManager: FakeProcessManager.any(),
213 fileSystem: fileSystem,
214 logger: BufferLogger.test(),
215 defines: <String, String>{kBuildMode: 'release'},
216 );
217
218 environment.buildDir.childFile('app.so').createSync(recursive: true);
219 environment.buildDir.childFile('native_assets.json').createSync(recursive: true);
220
221 await const WindowsAotBundle(AotElfRelease(TargetPlatform.windows_x64)).build(environment);
222 await const ReleaseBundleWindowsAssets(TargetPlatform.windows_x64).build(environment);
223
224 // Depfile is created and so is copied.
225 expect(environment.buildDir.childFile('flutter_assets.d'), exists);
226 expect(fileSystem.file(r'C:\windows\app.so'), exists);
227 expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin').existsSync(), false);
228 expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
229 },
230 overrides: <Type, Generator>{
231 FileSystem: () => fileSystem,
232 ProcessManager: () => FakeProcessManager.any(),
233 },
234 );
235}
236