| // Copyright (c) 2026, 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 'package:analyzer/file_system/file_system.dart'; | |
| // ignore: implementation_imports | |
| import 'package:analyzer/src/dart/analysis/experiments.dart'; | |
| // ignore: implementation_imports | |
| import 'package:analyzer/src/util/file_paths.dart' as file_paths; | |
| import 'package:analyzer_testing/mock_packages/mock_packages.dart'; | |
| import 'package:analyzer_testing/package_config_file_builder.dart'; | |
| import 'package:analyzer_testing/utilities/extensions/resource_provider.dart'; | |
| /// A mixin adding functionality to write `.dart_tool/package_config.json` | |
| /// files along with mock packages to a [ResourceProvider]. | |
| mixin ConfigurationFilesMixin on MockPackagesMixin { | |
| /// Adds the 'fixnum' package as a dependency to the package-under-test. | |
| bool get addFixnumPackageDep => false; | |
| /// Adds the 'flutter_localizations' package as a dependency to the | |
| /// package-under-test. | |
| bool get addFlutterLocalizationsPackageDep => false; | |
| /// Adds the 'flutter' package as a dependency to the package-under-test. | |
| bool get addFlutterPackageDep => false; | |
| /// Adds the 'flutter_test' package as a dependency to the | |
| /// package-under-test. | |
| bool get addFlutterTestPackageDep => false; | |
| /// Adds the 'meta' package as a dependency to the package-under-test. | |
| bool get addMetaPackageDep => false; | |
| /// Adds the 'test_reflective_loader' package as a dependency to the | |
| /// package-under-test. | |
| bool get addTestReflectiveLoaderPackageDep => false; | |
| /// Adds the 'vector_math' package as a dependency to the | |
| /// package-under-test. | |
| bool get addVectorMathPackageDep => false; | |
| String get dartSdkPath => resourceProvider.convertPath('/sdk'); | |
| /// The Dart language version of the test package being used for testing. | |
| String? get testPackageLanguageVersion => _latestLanguageVersion; | |
| /// The path to the test package being used for testing. | |
| String get testPackageRootPath; | |
| String get _latestLanguageVersion => | |
| '${ExperimentStatus.currentVersion.major}.' | |
| '${ExperimentStatus.currentVersion.minor}'; | |
| /// Writes a package_config.json for the package at [projectFolderPath]. If | |
| /// [packageName] is not supplied, the last segment of [projectFolderPath] is | |
| /// used. | |
| void writePackageConfig2( | |
| String projectFolderPath, { | |
| // The name of this package. If not provided, the last segment of the path | |
| // will be used. | |
| String? packageName, | |
| PackageConfigFileBuilder? config, | |
| String? languageVersion, | |
| }) { | |
| projectFolderPath = resourceProvider.convertPath(projectFolderPath); | |
| if (config == null) { | |
| config = PackageConfigFileBuilder(); | |
| } else { | |
| config = config.copy(); | |
| } | |
| // Add this package to its own config. | |
| var effectivePackageName = | |
| packageName ?? pathContext.basename(projectFolderPath); | |
| if (!config.hasPackage(effectivePackageName)) { | |
| config.add( | |
| name: effectivePackageName, | |
| rootFolder: resourceProvider.getFolder(projectFolderPath), | |
| languageVersion: languageVersion ?? testPackageLanguageVersion, | |
| ); | |
| } | |
| if (addFixnumPackageDep) { | |
| if (!config.hasPackage('fixnum')) { | |
| var fixnumPath = addFixnum().parent.path; | |
| config.add( | |
| name: 'fixnum', | |
| rootFolder: resourceProvider.getFolder(fixnumPath), | |
| ); | |
| } | |
| } | |
| // flutter_test also depends on meta for @isTestGroup / @isTest | |
| if (addMetaPackageDep || | |
| addFlutterPackageDep || | |
| addFlutterTestPackageDep || | |
| addMetaPackageDep) { | |
| if (!config.hasPackage('meta')) { | |
| var libFolder = addMeta(); | |
| config.add(name: 'meta', rootFolder: libFolder.parent); | |
| } | |
| } | |
| if (addFlutterPackageDep) { | |
| if (!config.hasPackage('sky_engine')) { | |
| var skyEnginePath = addSkyEngine(sdkPath: dartSdkPath).parent.path; | |
| config.add( | |
| name: 'sky_engine', | |
| rootFolder: resourceProvider.getFolder(skyEnginePath), | |
| ); | |
| } | |
| if (!config.hasPackage('flutter')) { | |
| var flutterLibFolder = addFlutter(); | |
| config.add(name: 'flutter', rootFolder: flutterLibFolder.parent); | |
| } | |
| } | |
| if (addFlutterLocalizationsPackageDep) { | |
| if (!config.hasPackage('flutter_localizations')) { | |
| var libFolder = addFlutterLocalizations(); | |
| config.add(name: 'flutter_localizations', rootFolder: libFolder.parent); | |
| } | |
| } | |
| if (addFlutterTestPackageDep) { | |
| if (!config.hasPackage('flutter_test')) { | |
| var flutterTestRootPath = resourceProvider.convertPath( | |
| '$packagesRootPath/flutter_test', | |
| ); | |
| var flutterTestRoot = resourceProvider.getFolder(flutterTestRootPath); | |
| var libFolder = flutterTestRoot.getFolder('lib')..create(); | |
| libFolder.getFile('flutter_test.dart').writeAsStringSync(r''' | |
| import 'package:meta/meta.dart'; | |
| @isTest | |
| void test(Object description, dynamic Function() body) {} | |
| @isTestGroup | |
| void group(Object description, void Function() body) {} | |
| void main() { | |
| // Because this file is called 'flutter_test.dart' and is inside the 'test' | |
| // folder, it will be considered a test suite. To avoid it failing the bots | |
| // with "Invoked Dart programs must have a 'main' function defined", provide | |
| // an empty main function. | |
| } | |
| '''); | |
| config.add(name: 'flutter_test', rootFolder: flutterTestRoot); | |
| } | |
| } | |
| if (addTestReflectiveLoaderPackageDep) { | |
| if (!config.hasPackage('test_reflective_loader')) { | |
| var testReflectiveLoaderPath = addTestReflectiveLoader().parent.path; | |
| config.add( | |
| name: 'test_reflective_loader', | |
| rootFolder: resourceProvider.getFolder(testReflectiveLoaderPath), | |
| ); | |
| } | |
| } | |
| if (addVectorMathPackageDep) { | |
| if (!config.hasPackage('vector_math')) { | |
| var libFolder = addVectorMath(); | |
| config.add(name: 'vector_math', rootFolder: libFolder.parent); | |
| } | |
| } | |
| var content = config.toContent(); | |
| var projectFolder = resourceProvider.getFolder(projectFolderPath); | |
| var dartToolFolder = projectFolder.getFolder(file_paths.dotDartTool) | |
| ..create(); | |
| dartToolFolder | |
| .getFile(file_paths.packageConfigJson) | |
| .writeAsStringSync(content); | |
| } | |
| /// Writes a package_config.json for the package under test (considered | |
| /// 'package:test') that lives in [testPackageRootPath]. | |
| void writeTestPackageConfig2({ | |
| PackageConfigFileBuilder? config, | |
| String? languageVersion, | |
| }) { | |
| writePackageConfig2( | |
| testPackageRootPath, | |
| config: config, | |
| languageVersion: languageVersion, | |
| packageName: 'test', | |
| ); | |
| } | |
| } |