From 7a0c6683cb732bb9c07e93cabc751e84c0a8b291 Mon Sep 17 00:00:00 2001 From: Daco Harkes Date: Tue, 20 Feb 2024 11:02:15 +0100 Subject: [PATCH] Increase test coverage --- .../lib/src/api/build_config.dart | 4 + .../lib/src/model/build_config.dart | 24 ++-- .../lib/src/model/build_output.dart | 4 +- .../lib/src/model/c_code_asset.dart | 5 - pkgs/native_assets_cli/pubspec.yaml | 1 + .../test/api/build_config_test.dart | 6 + .../test/api/build_test.dart | 71 ++++++++++++ .../test/model/build_config_test.dart | 23 +++- .../test/model/build_output_test.dart | 107 ++++++++++++++++++ .../test/model/target_test.dart | 10 ++ 10 files changed, 235 insertions(+), 20 deletions(-) create mode 100644 pkgs/native_assets_cli/test/api/build_test.dart diff --git a/pkgs/native_assets_cli/lib/src/api/build_config.dart b/pkgs/native_assets_cli/lib/src/api/build_config.dart index a87e1091f..dc2900ef6 100644 --- a/pkgs/native_assets_cli/lib/src/api/build_config.dart +++ b/pkgs/native_assets_cli/lib/src/api/build_config.dart @@ -127,6 +127,7 @@ abstract final class BuildConfig { CCompilerConfig? cCompiler, required LinkModePreference linkModePreference, Map>? dependencyMetadata, + Iterable? supportedAssetTypes, }) => BuildConfigImpl( outDir: outDir, @@ -145,6 +146,7 @@ abstract final class BuildConfig { entry.key: Metadata(entry.value.cast()) } : {}, + supportedAssetTypes: supportedAssetTypes, ); factory BuildConfig.dryRun({ @@ -153,6 +155,7 @@ abstract final class BuildConfig { required Uri packageRoot, required OS targetOs, required LinkModePreference linkModePreference, + Iterable? supportedAssetTypes, }) => BuildConfigImpl.dryRun( outDir: outDir, @@ -160,6 +163,7 @@ abstract final class BuildConfig { packageRoot: packageRoot, targetOs: targetOs as OSImpl, linkModePreference: linkModePreference as LinkModePreferenceImpl, + supportedAssetTypes: supportedAssetTypes, ); factory BuildConfig.fromConfig(Config config) => diff --git a/pkgs/native_assets_cli/lib/src/model/build_config.dart b/pkgs/native_assets_cli/lib/src/model/build_config.dart index 7e7b16dcd..ec05c3896 100644 --- a/pkgs/native_assets_cli/lib/src/model/build_config.dart +++ b/pkgs/native_assets_cli/lib/src/model/build_config.dart @@ -149,11 +149,8 @@ final class BuildConfigImpl implements BuildConfig { .._linkModePreference = linkModePreference .._dependencyMetadata = dependencyMetadata .._dryRun = false - .._supportedAssetTypes = [ - ...?supportedAssetTypes, - // Backwards compatibility. - if (supportedAssetTypes == null) CCodeAsset.type, - ]; + .._supportedAssetTypes = + _supportedAssetTypesBackwardsCompatibility(supportedAssetTypes); final parsedConfigFile = nonValidated.toYaml(); final config = Config(fileParsed: parsedConfigFile); return BuildConfigImpl.fromConfig(config); @@ -177,11 +174,8 @@ final class BuildConfigImpl implements BuildConfig { .._linkModePreference = linkModePreference .._cCompiler = CCompilerConfigImpl() .._dryRun = true - .._supportedAssetTypes = [ - ...?supportedAssetTypes, - // Backwards compatibility. - if (supportedAssetTypes == null) CCodeAsset.type, - ]; + .._supportedAssetTypes = + _supportedAssetTypesBackwardsCompatibility(supportedAssetTypes); final parsedConfigFile = nonValidated.toYaml(); final config = Config(fileParsed: parsedConfigFile); return BuildConfigImpl.fromConfig(config); @@ -227,7 +221,7 @@ final class BuildConfigImpl implements BuildConfig { entry.key, json.encode(entry.value.toYaml()), ], - ...?supportedAssetTypes, + ..._supportedAssetTypesBackwardsCompatibility(supportedAssetTypes), ].join('###'); final sha256String = sha256.convert(utf8.encode(input)).toString(); // 256 bit hashes lead to 64 hex character strings. @@ -237,6 +231,14 @@ final class BuildConfigImpl implements BuildConfig { return sha256String.substring(0, nameLength); } + static List _supportedAssetTypesBackwardsCompatibility( + Iterable? supportedAssetTypes, + ) => + [ + ...?supportedAssetTypes, + if (supportedAssetTypes == null) CCodeAsset.type, + ]; + BuildConfigImpl._(); /// The version of [BuildConfigImpl]. diff --git a/pkgs/native_assets_cli/lib/src/model/build_output.dart b/pkgs/native_assets_cli/lib/src/model/build_output.dart index 7a2781d88..bbed6d84f 100644 --- a/pkgs/native_assets_cli/lib/src/model/build_output.dart +++ b/pkgs/native_assets_cli/lib/src/model/build_output.dart @@ -79,9 +79,7 @@ class BuildOutputImpl implements BuildOutput { case null: // Backwards compatibility with v1.0.0. assets.add(CCodeAssetImpl.fromYaml(yamlMap)); default: - throw FormatException( - "Unexpected asset type '$type' in YAML.", - ); + // Do nothing, some other launcher might define it's own asset types. } } diff --git a/pkgs/native_assets_cli/lib/src/model/c_code_asset.dart b/pkgs/native_assets_cli/lib/src/model/c_code_asset.dart index f1d67fef5..832df5f5f 100644 --- a/pkgs/native_assets_cli/lib/src/model/c_code_asset.dart +++ b/pkgs/native_assets_cli/lib/src/model/c_code_asset.dart @@ -204,11 +204,6 @@ final class CCodeAssetImpl implements CCodeAsset { ]; } - static List listFromYamlList(YamlList yamlList) => [ - for (final yamlElement in yamlList) - CCodeAssetImpl.fromYaml(as(yamlElement)), - ]; - CCodeAssetImpl copyWith({ LinkModeImpl? linkMode, String? id, diff --git a/pkgs/native_assets_cli/pubspec.yaml b/pkgs/native_assets_cli/pubspec.yaml index 84c0c00d5..399757824 100644 --- a/pkgs/native_assets_cli/pubspec.yaml +++ b/pkgs/native_assets_cli/pubspec.yaml @@ -26,4 +26,5 @@ dependencies: dev_dependencies: dart_flutter_team_lints: ^2.1.1 + file_testing: ^3.0.0 test: ^1.21.0 diff --git a/pkgs/native_assets_cli/test/api/build_config_test.dart b/pkgs/native_assets_cli/test/api/build_config_test.dart index c9b8d66a6..71dc4cc71 100644 --- a/pkgs/native_assets_cli/test/api/build_config_test.dart +++ b/pkgs/native_assets_cli/test/api/build_config_test.dart @@ -61,6 +61,7 @@ void main() async { ), buildMode: BuildMode.release, linkModePreference: LinkModePreference.preferStatic, + supportedAssetTypes: [CCodeAsset.type], ); final config2 = BuildConfig( @@ -72,6 +73,7 @@ void main() async { targetAndroidNdkApi: 30, buildMode: BuildMode.release, linkModePreference: LinkModePreference.preferStatic, + supportedAssetTypes: [CCodeAsset.type], ); expect(config1, equals(config1)); @@ -89,6 +91,7 @@ void main() async { true); expect(config1.cCompiler != config2.cCompiler, true); expect(config1.linkModePreference, config2.linkModePreference); + expect(config1.supportedAssetTypes, config2.supportedAssetTypes); }); test('BuildConfig fromConfig', () { @@ -127,6 +130,7 @@ void main() async { packageRoot: packageRootUri, targetOs: OS.android, linkModePreference: LinkModePreference.preferStatic, + supportedAssetTypes: [CCodeAsset.type], ); final config = Config(fileParsed: { @@ -186,6 +190,8 @@ void main() async { expect(buildConfig1, equals(buildConfig1)); expect(buildConfig1 == buildConfig2, false); expect(buildConfig1.hashCode == buildConfig2.hashCode, false); + + expect(buildConfig1.metadatum('bar', 'key'), 'value'); }); test('BuildConfig fromArgs', () async { diff --git a/pkgs/native_assets_cli/test/api/build_test.dart b/pkgs/native_assets_cli/test/api/build_test.dart new file mode 100644 index 000000000..448e86169 --- /dev/null +++ b/pkgs/native_assets_cli/test/api/build_test.dart @@ -0,0 +1,71 @@ +// Copyright (c) 2023, 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. + +import 'dart:io'; + +import 'package:file_testing/file_testing.dart'; +import 'package:native_assets_cli/native_assets_cli.dart'; +import 'package:native_assets_cli/src/api/build_config.dart'; +import 'package:native_assets_cli/src/api/build_output.dart'; +import 'package:test/test.dart'; + +void main() async { + late Uri tempUri; + late Uri outDirUri; + late String packageName; + late Uri packageRootUri; + late Uri fakeClang; + late Uri fakeLd; + late Uri fakeAr; + late Uri fakeCl; + late Uri fakeVcVars; + late Uri buildConfigUri; + + setUp(() async { + tempUri = (await Directory.systemTemp.createTemp()).uri; + outDirUri = tempUri.resolve('out1/'); + await Directory.fromUri(outDirUri).create(); + packageName = 'my_package'; + packageRootUri = tempUri.resolve('$packageName/'); + await Directory.fromUri(packageRootUri).create(); + fakeClang = tempUri.resolve('fake_clang'); + await File.fromUri(fakeClang).create(); + fakeLd = tempUri.resolve('fake_ld'); + await File.fromUri(fakeLd).create(); + fakeAr = tempUri.resolve('fake_ar'); + await File.fromUri(fakeAr).create(); + fakeCl = tempUri.resolve('cl.exe'); + await File.fromUri(fakeCl).create(); + fakeVcVars = tempUri.resolve('vcvarsall.bat'); + await File.fromUri(fakeVcVars).create(); + + final config1 = BuildConfig( + outDir: outDirUri, + packageName: packageName, + packageRoot: tempUri, + targetArchitecture: Architecture.arm64, + targetOs: OS.iOS, + targetIOSSdk: IOSSdk.iPhoneOs, + cCompiler: CCompilerConfig( + cc: fakeClang, + ld: fakeLd, + ar: fakeAr, + ), + buildMode: BuildMode.release, + linkModePreference: LinkModePreference.preferDynamic, + ); + final configYaml = (config1 as BuildConfigImpl).toYamlString(); + buildConfigUri = tempUri.resolve('build_config.yaml'); + await File.fromUri(buildConfigUri).writeAsString(configYaml); + }); + + test('build method', () async { + await build(['--config', buildConfigUri.toFilePath()], + (config, output) async { + output.addDependency(packageRootUri.resolve('foo')); + }); + final buildOutputUri = outDirUri.resolve(BuildOutputImpl.fileName); + expect(File.fromUri(buildOutputUri), exists); + }); +} diff --git a/pkgs/native_assets_cli/test/model/build_config_test.dart b/pkgs/native_assets_cli/test/model/build_config_test.dart index 8af79b784..fd47f567d 100644 --- a/pkgs/native_assets_cli/test/model/build_config_test.dart +++ b/pkgs/native_assets_cli/test/model/build_config_test.dart @@ -538,10 +538,11 @@ version: 1.0.0'''; targetOs: OSImpl.linux, buildMode: BuildModeImpl.release, linkModePreference: LinkModePreferenceImpl.dynamic, + supportedAssetTypes: [CCodeAsset.type], ); // Using the checksum for a build folder should be stable. - expect(name1, 'e8da644fa538c7b63e61feb102974b93'); + expect(name1, '4dec7292cfab417c27529307d949773f'); // Build folder different due to metadata. final name2 = BuildConfigImpl.checksum( @@ -616,6 +617,26 @@ version: 1.0.0'''; ); }); + test('BuildConfig dry_run access invalid args', () { + final outDir = outDirUri; + final config = Config(fileParsed: { + 'link_mode_preference': 'prefer-static', + 'out_dir': outDir.toFilePath(), + 'package_name': packageName, + 'package_root': tempUri.toFilePath(), + 'target_os': 'android', + 'dry_run': true, + 'version': BuildConfigImpl.latestVersion.toString(), + }); + final buildConfig = BuildConfigImpl.fromConfig(config); + expect( + () => buildConfig.targetAndroidNdkApi, + throwsA(predicate( + (e) => e is StateError && e.message.contains('In Flutter projects'), + )), + ); + }); + test('BuildConfig dry_run target arch', () { final outDir = outDirUri; final config = Config(fileParsed: { diff --git a/pkgs/native_assets_cli/test/model/build_output_test.dart b/pkgs/native_assets_cli/test/model/build_output_test.dart index 530d89da1..dc60ddcc7 100644 --- a/pkgs/native_assets_cli/test/model/build_output_test.dart +++ b/pkgs/native_assets_cli/test/model/build_output_test.dart @@ -38,6 +38,20 @@ void main() { architecture: ArchitectureImpl.x64, linkMode: LinkModeImpl.dynamic, ), + CCodeAssetImpl( + id: 'foo3', + dynamicLoading: LookupInProcessImpl(), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), + CCodeAssetImpl( + id: 'foo4', + dynamicLoading: LookupInExecutableImpl(), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), ], dependencies: Dependencies([ Uri.file('path/to/file.ext'), @@ -61,6 +75,16 @@ assets: path_type: system uri: path/to/libfoo2.so target: android_x64 + - id: foo3 + link_mode: dynamic + path: + path_type: process + target: android_x64 + - id: foo4 + link_mode: dynamic + path: + path_type: executable + target: android_x64 dependencies: - path/to/file.ext metadata: @@ -85,6 +109,20 @@ assets: link_mode: dynamic os: android type: c_code + - architecture: x64 + dynamic_loading: + type: process + id: foo3 + link_mode: dynamic + os: android + type: c_code + - architecture: x64 + dynamic_loading: + type: executable + id: foo4 + link_mode: dynamic + os: android + type: c_code dependencies: - path/to/file.ext metadata: @@ -224,4 +262,73 @@ version: ${BuildOutputImpl.latestVersion}'''), returnsNormally, ); }); + + test('BuildOutput setters', () { + final buildOutput = BuildOutputImpl( + timestamp: DateTime.parse('2022-11-10 13:25:01.000'), + assets: [ + CCodeAssetImpl( + id: 'foo', + file: Uri(path: 'path/to/libfoo.so'), + dynamicLoading: BundledDylibImpl(), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), + CCodeAssetImpl( + id: 'foo2', + dynamicLoading: SystemDylibImpl(Uri(path: 'path/to/libfoo2.so')), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), + ], + dependencies: Dependencies([ + Uri.file('path/to/file.ext'), + Uri.file('path/to/file2.ext'), + ]), + metadata: const Metadata({ + 'key': 'value', + 'key2': 'value2', + }), + ); + + final buildOutput2 = BuildOutputImpl( + timestamp: DateTime.parse('2022-11-10 13:25:01.000'), + ); + buildOutput2.addAsset( + CCodeAssetImpl( + id: 'foo', + file: Uri(path: 'path/to/libfoo.so'), + dynamicLoading: BundledDylibImpl(), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), + ); + buildOutput2.addAssets([ + CCodeAssetImpl( + id: 'foo2', + dynamicLoading: SystemDylibImpl(Uri(path: 'path/to/libfoo2.so')), + os: OSImpl.android, + architecture: ArchitectureImpl.x64, + linkMode: LinkModeImpl.dynamic, + ), + ]); + buildOutput2.addDependency( + Uri.file('path/to/file.ext'), + ); + buildOutput2.addDependencies([ + Uri.file('path/to/file2.ext'), + ]); + buildOutput2.addMetadata({ + 'key': 'value', + }); + buildOutput2.addMetadatum('key2', 'value2'); + + expect(buildOutput2, equals(buildOutput)); + expect( + buildOutput2.dependenciesModel, equals(buildOutput.dependenciesModel)); + expect(buildOutput2.metadataModel, equals(buildOutput.metadataModel)); + }); } diff --git a/pkgs/native_assets_cli/test/model/target_test.dart b/pkgs/native_assets_cli/test/model/target_test.dart index 4672c4454..fc928ee45 100644 --- a/pkgs/native_assets_cli/test/model/target_test.dart +++ b/pkgs/native_assets_cli/test/model/target_test.dart @@ -75,4 +75,14 @@ void main() { )), ); }); + + test('OS.architectures', () { + expect(OSImpl.android.architectures, [ + ArchitectureImpl.arm, + ArchitectureImpl.arm64, + ArchitectureImpl.ia32, + ArchitectureImpl.x64, + ArchitectureImpl.riscv64, + ]); + }); }