Skip to content

Commit ede7fc6

Browse files
authored
Add more CMake unit tests (#106076)
Currently CMake is tested entirely through `build_linux_test.dart`. However, CMake is also used for Windows builds. This adds additional "generic" tests: 1. Parsing CMake files 2. Generating CMake config files. In the future, this will be used to test that generated CMake config files contain the expected version information, which will be used to flow version information to Windows executables. Part of flutter/flutter#73652.
1 parent d3bc2bb commit ede7fc6

File tree

2 files changed

+158
-18
lines changed

2 files changed

+158
-18
lines changed

packages/flutter_tools/lib/src/cmake.dart

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'base/file_system.dart';
65
import 'cmake_project.dart';
76

87
/// Extracts the `BINARY_NAME` from a project's CMake file.
@@ -22,23 +21,6 @@ String? getCmakeExecutableName(CmakeBasedProject project) {
2221
return null;
2322
}
2423

25-
/// Extracts the `PACKAGE_GUID` from a project's CMake file.
26-
///
27-
/// Returns `null` if it cannot be found.
28-
String? getCmakePackageGuid(File cmakeFile) {
29-
if (!cmakeFile.existsSync()) {
30-
return null;
31-
}
32-
final RegExp nameSetPattern = RegExp(r'^\s*set\(PACKAGE_GUID\s*"(.*)"\s*\)\s*$');
33-
for (final String line in cmakeFile.readAsLinesSync()) {
34-
final RegExpMatch? match = nameSetPattern.firstMatch(line);
35-
if (match != null) {
36-
return match.group(1);
37-
}
38-
}
39-
return null;
40-
}
41-
4224
String _escapeBackslashes(String s) {
4325
return s.replaceAll(r'\', r'\\');
4426
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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+
5+
// @dart = 2.8
6+
7+
import 'package:file/memory.dart';
8+
import 'package:file_testing/file_testing.dart';
9+
import 'package:flutter_tools/src/base/file_system.dart';
10+
import 'package:flutter_tools/src/cmake.dart';
11+
import 'package:flutter_tools/src/project.dart';
12+
13+
import '../src/common.dart';
14+
import '../src/context.dart';
15+
16+
const String _kTestFlutterRoot = '/flutter';
17+
const String _kTestWindowsFlutterRoot = r'C:\flutter';
18+
19+
void main() {
20+
FileSystem fileSystem;
21+
22+
ProcessManager processManager;
23+
24+
setUp(() {
25+
fileSystem = MemoryFileSystem.test();
26+
});
27+
28+
testUsingContext('parses executable name from cmake file', () async {
29+
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
30+
final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project);
31+
32+
cmakeProject.cmakeFile
33+
..createSync(recursive: true)
34+
..writeAsStringSync('set(BINARY_NAME "hello")');
35+
36+
final String name = getCmakeExecutableName(cmakeProject);
37+
38+
expect(name, 'hello');
39+
}, overrides: <Type, Generator>{
40+
FileSystem: () => fileSystem,
41+
ProcessManager: () => processManager,
42+
});
43+
44+
testUsingContext('defaults executable name to null if cmake config does not exist', () async {
45+
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
46+
final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project);
47+
48+
final String name = getCmakeExecutableName(cmakeProject);
49+
50+
expect(name, isNull);
51+
}, overrides: <Type, Generator>{
52+
FileSystem: () => fileSystem,
53+
ProcessManager: () => processManager,
54+
});
55+
56+
testUsingContext('generates config', () async {
57+
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
58+
final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project);
59+
final Map<String, String> environment = <String, String>{};
60+
61+
writeGeneratedCmakeConfig(
62+
_kTestFlutterRoot,
63+
cmakeProject,
64+
environment,
65+
);
66+
67+
final File cmakeConfig = cmakeProject.generatedCmakeConfigFile;
68+
69+
expect(cmakeConfig, exists);
70+
71+
final List<String> configLines = cmakeConfig.readAsLinesSync();
72+
73+
expect(configLines, containsAll(<String>[
74+
r'# Generated code do not commit.',
75+
r'file(TO_CMAKE_PATH "/flutter" FLUTTER_ROOT)',
76+
r'file(TO_CMAKE_PATH "/" PROJECT_DIR)',
77+
78+
r'# Environment variables to pass to tool_backend.sh',
79+
r'list(APPEND FLUTTER_TOOL_ENVIRONMENT',
80+
r' "FLUTTER_ROOT=/flutter"',
81+
r' "PROJECT_DIR=/"',
82+
r')',
83+
]));
84+
}, overrides: <Type, Generator>{
85+
FileSystem: () => fileSystem,
86+
ProcessManager: () => processManager,
87+
});
88+
89+
testUsingContext('config escapes backslashes', () async {
90+
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
91+
92+
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
93+
final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project);
94+
95+
final Map<String, String> environment = <String, String>{
96+
'TEST': r'hello\world',
97+
};
98+
99+
writeGeneratedCmakeConfig(
100+
_kTestWindowsFlutterRoot,
101+
cmakeProject,
102+
environment,
103+
);
104+
105+
final File cmakeConfig = cmakeProject.generatedCmakeConfigFile;
106+
107+
expect(cmakeConfig, exists);
108+
109+
final List<String> configLines = cmakeConfig.readAsLinesSync();
110+
111+
expect(configLines, containsAll(<String>[
112+
r'# Generated code do not commit.',
113+
r'file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)',
114+
r'file(TO_CMAKE_PATH "C:\\" PROJECT_DIR)',
115+
116+
r'# Environment variables to pass to tool_backend.sh',
117+
r'list(APPEND FLUTTER_TOOL_ENVIRONMENT',
118+
r' "FLUTTER_ROOT=C:\\flutter"',
119+
r' "PROJECT_DIR=C:\\"',
120+
r' "TEST=hello\\world"',
121+
r')',
122+
]));
123+
}, overrides: <Type, Generator>{
124+
FileSystem: () => fileSystem,
125+
ProcessManager: () => processManager,
126+
});
127+
}
128+
129+
class _FakeProject implements CmakeBasedProject {
130+
_FakeProject.fromFlutter(this._parent);
131+
132+
final FlutterProject _parent;
133+
134+
@override
135+
bool existsSync() => _editableDirectory.existsSync();
136+
137+
@override
138+
File get cmakeFile => _editableDirectory.childFile('CMakeLists.txt');
139+
140+
@override
141+
File get managedCmakeFile => _managedDirectory.childFile('CMakeLists.txt');
142+
143+
@override
144+
File get generatedCmakeConfigFile => _ephemeralDirectory.childFile('generated_config.cmake');
145+
146+
@override
147+
File get generatedPluginCmakeFile => _managedDirectory.childFile('generated_plugins.cmake');
148+
149+
@override
150+
Directory get pluginSymlinkDirectory => _ephemeralDirectory.childDirectory('.plugin_symlinks');
151+
152+
@override
153+
FlutterProject get parent => _parent;
154+
155+
Directory get _editableDirectory => parent.directory.childDirectory('test');
156+
Directory get _managedDirectory => _editableDirectory.childDirectory('flutter');
157+
Directory get _ephemeralDirectory => _managedDirectory.childDirectory('ephemeral');
158+
}

0 commit comments

Comments
 (0)