blob: aa867313d856a2f5d64c9dd8b770fe583b32ec52 [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@Timeout(Duration(seconds: 120))
import 'dart:convert';
import 'dart:io';
import 'package:test/test.dart';
void main() {
Uri? tempDirUri;
final projectName = 'test_project';
setUp(() async {
tempDirUri = (await Directory.current.createTemp('.temp_test_')).uri;
});
tearDown(() async {
final dir = Directory(tempDirUri!.toFilePath());
if (await dir.exists()) {
await dir.delete(recursive: true);
}
});
test('Run Flutter', () async {
final projectDirUri = tempDirUri!.resolve('$projectName/');
final libDirUri = projectDirUri.resolve('lib/');
final bindingsGeneratedUri =
libDirUri.resolve('${projectName}_bindings_generated.dart');
final bindingsGeneratedCopyUri =
libDirUri.resolve('${projectName}_bindings_generated_copy.dart');
await runProcess(
executable: 'flutter',
arguments: [
'create',
'--template=plugin_ffi',
projectName,
],
workingDirectory: tempDirUri,
);
await copyFile(
source: bindingsGeneratedUri,
target: bindingsGeneratedCopyUri,
);
await runProcess(
executable: 'flutter',
arguments: [
'pub',
'run',
'ffigen',
'--config',
'ffigen.yaml',
],
workingDirectory: projectDirUri,
);
final originalBindings = await readFileAsString(bindingsGeneratedCopyUri);
final regeneratedBindings = await readFileAsString(bindingsGeneratedUri);
expect(originalBindings, regeneratedBindings);
});
}
Future<String> readFileAsString(Uri uri) async {
final contents = await File(uri.toFilePath()).readAsString();
return contents.replaceAll('\r', '');
}
Future<void> runProcess({
required List<String> arguments,
required String executable,
Uri? workingDirectory,
Map<String, String>? environment,
bool throwOnFailure = true,
}) async {
// Excluding [workingDirectory].
final String commandString = [
if (workingDirectory != null) '(cd ${workingDirectory.path};',
...?environment?.entries.map((entry) => '${entry.key}=${entry.value}'),
executable,
...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
if (workingDirectory != null) ')',
].join(' ');
final workingDirectoryString = workingDirectory?.toFilePath();
print('Running `$commandString`.');
final process = await Process.start(executable, arguments,
runInShell: true,
includeParentEnvironment: true,
workingDirectory: workingDirectoryString,
environment: environment)
.then((process) {
process.stdout.transform(utf8.decoder).forEach((s) => print(' $s'));
process.stderr.transform(utf8.decoder).forEach((s) => print(' $s'));
return process;
});
final exitCode = await process.exitCode;
if (exitCode != 0) {
final message = 'Command `$commandString` failed with exit code $exitCode.';
print(message);
if (throwOnFailure) {
throw Exception(message);
}
}
print('Command `$commandString` done.');
}
Future<void> copyFile({
required Uri source,
required Uri target,
}) async {
final file = File.fromUri(source);
if (!await file.exists()) {
final message = "File not in expected location: '${source.toFilePath()}'.";
print(message);
throw Exception(message);
}
print('Copying ${source.toFilePath()} to ${target.toFilePath()}.');
await file.copy(target.toFilePath());
}