From ede7fc67f5bede296aaa217bedb37fd4af18a607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= <737941+loic-sharma@users.noreply.github.com> Date: Thu, 16 Jun 2022 11:48:17 -0700 Subject: [PATCH] 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 https://github.com/flutter/flutter/issues/73652. --- packages/flutter_tools/lib/src/cmake.dart | 18 -- .../test/general.shard/cmake_test.dart | 158 ++++++++++++++++++ 2 files changed, 158 insertions(+), 18 deletions(-) create mode 100644 packages/flutter_tools/test/general.shard/cmake_test.dart diff --git a/packages/flutter_tools/lib/src/cmake.dart b/packages/flutter_tools/lib/src/cmake.dart index 19589d46835d..47b20f8d6aa0 100644 --- a/packages/flutter_tools/lib/src/cmake.dart +++ b/packages/flutter_tools/lib/src/cmake.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'base/file_system.dart'; import 'cmake_project.dart'; /// Extracts the `BINARY_NAME` from a project's CMake file. @@ -22,23 +21,6 @@ String? getCmakeExecutableName(CmakeBasedProject project) { return null; } -/// Extracts the `PACKAGE_GUID` from a project's CMake file. -/// -/// Returns `null` if it cannot be found. -String? getCmakePackageGuid(File cmakeFile) { - if (!cmakeFile.existsSync()) { - return null; - } - final RegExp nameSetPattern = RegExp(r'^\s*set\(PACKAGE_GUID\s*"(.*)"\s*\)\s*$'); - for (final String line in cmakeFile.readAsLinesSync()) { - final RegExpMatch? match = nameSetPattern.firstMatch(line); - if (match != null) { - return match.group(1); - } - } - return null; -} - String _escapeBackslashes(String s) { return s.replaceAll(r'\', r'\\'); } diff --git a/packages/flutter_tools/test/general.shard/cmake_test.dart b/packages/flutter_tools/test/general.shard/cmake_test.dart new file mode 100644 index 000000000000..1ef9bfcefb22 --- /dev/null +++ b/packages/flutter_tools/test/general.shard/cmake_test.dart @@ -0,0 +1,158 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// @dart = 2.8 + +import 'package:file/memory.dart'; +import 'package:file_testing/file_testing.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/cmake.dart'; +import 'package:flutter_tools/src/project.dart'; + +import '../src/common.dart'; +import '../src/context.dart'; + +const String _kTestFlutterRoot = '/flutter'; +const String _kTestWindowsFlutterRoot = r'C:\flutter'; + +void main() { + FileSystem fileSystem; + + ProcessManager processManager; + + setUp(() { + fileSystem = MemoryFileSystem.test(); + }); + + testUsingContext('parses executable name from cmake file', () async { + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project); + + cmakeProject.cmakeFile + ..createSync(recursive: true) + ..writeAsStringSync('set(BINARY_NAME "hello")'); + + final String name = getCmakeExecutableName(cmakeProject); + + expect(name, 'hello'); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + }); + + testUsingContext('defaults executable name to null if cmake config does not exist', () async { + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project); + + final String name = getCmakeExecutableName(cmakeProject); + + expect(name, isNull); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + }); + + testUsingContext('generates config', () async { + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project); + final Map environment = {}; + + writeGeneratedCmakeConfig( + _kTestFlutterRoot, + cmakeProject, + environment, + ); + + final File cmakeConfig = cmakeProject.generatedCmakeConfigFile; + + expect(cmakeConfig, exists); + + final List configLines = cmakeConfig.readAsLinesSync(); + + expect(configLines, containsAll([ + r'# Generated code do not commit.', + r'file(TO_CMAKE_PATH "/flutter" FLUTTER_ROOT)', + r'file(TO_CMAKE_PATH "/" PROJECT_DIR)', + + r'# Environment variables to pass to tool_backend.sh', + r'list(APPEND FLUTTER_TOOL_ENVIRONMENT', + r' "FLUTTER_ROOT=/flutter"', + r' "PROJECT_DIR=/"', + r')', + ])); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + }); + + testUsingContext('config escapes backslashes', () async { + fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); + + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project); + + final Map environment = { + 'TEST': r'hello\world', + }; + + writeGeneratedCmakeConfig( + _kTestWindowsFlutterRoot, + cmakeProject, + environment, + ); + + final File cmakeConfig = cmakeProject.generatedCmakeConfigFile; + + expect(cmakeConfig, exists); + + final List configLines = cmakeConfig.readAsLinesSync(); + + expect(configLines, containsAll([ + r'# Generated code do not commit.', + r'file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)', + r'file(TO_CMAKE_PATH "C:\\" PROJECT_DIR)', + + r'# Environment variables to pass to tool_backend.sh', + r'list(APPEND FLUTTER_TOOL_ENVIRONMENT', + r' "FLUTTER_ROOT=C:\\flutter"', + r' "PROJECT_DIR=C:\\"', + r' "TEST=hello\\world"', + r')', + ])); + }, overrides: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + }); +} + +class _FakeProject implements CmakeBasedProject { + _FakeProject.fromFlutter(this._parent); + + final FlutterProject _parent; + + @override + bool existsSync() => _editableDirectory.existsSync(); + + @override + File get cmakeFile => _editableDirectory.childFile('CMakeLists.txt'); + + @override + File get managedCmakeFile => _managedDirectory.childFile('CMakeLists.txt'); + + @override + File get generatedCmakeConfigFile => _ephemeralDirectory.childFile('generated_config.cmake'); + + @override + File get generatedPluginCmakeFile => _managedDirectory.childFile('generated_plugins.cmake'); + + @override + Directory get pluginSymlinkDirectory => _ephemeralDirectory.childDirectory('.plugin_symlinks'); + + @override + FlutterProject get parent => _parent; + + Directory get _editableDirectory => parent.directory.childDirectory('test'); + Directory get _managedDirectory => _editableDirectory.childDirectory('flutter'); + Directory get _ephemeralDirectory => _managedDirectory.childDirectory('ephemeral'); +}