Skip to content

Commit

Permalink
Add more CMake unit tests (#106076)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
loic-sharma authored Jun 16, 2022
1 parent d3bc2bb commit ede7fc6
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 18 deletions.
18 changes: 0 additions & 18 deletions packages/flutter_tools/lib/src/cmake.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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'\\');
}
Expand Down
158 changes: 158 additions & 0 deletions packages/flutter_tools/test/general.shard/cmake_test.dart
Original file line number Diff line number Diff line change
@@ -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: <Type, Generator>{
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: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
});

testUsingContext('generates config', () async {
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
final CmakeBasedProject cmakeProject = _FakeProject.fromFlutter(project);
final Map<String, String> environment = <String, String>{};

writeGeneratedCmakeConfig(
_kTestFlutterRoot,
cmakeProject,
environment,
);

final File cmakeConfig = cmakeProject.generatedCmakeConfigFile;

expect(cmakeConfig, exists);

final List<String> configLines = cmakeConfig.readAsLinesSync();

expect(configLines, containsAll(<String>[
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: <Type, Generator>{
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<String, String> environment = <String, String>{
'TEST': r'hello\world',
};

writeGeneratedCmakeConfig(
_kTestWindowsFlutterRoot,
cmakeProject,
environment,
);

final File cmakeConfig = cmakeProject.generatedCmakeConfigFile;

expect(cmakeConfig, exists);

final List<String> configLines = cmakeConfig.readAsLinesSync();

expect(configLines, containsAll(<String>[
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: <Type, Generator>{
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');
}

0 comments on commit ede7fc6

Please sign in to comment.