// 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. import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/signals.dart'; import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/commands/attach.dart'; import 'package:flutter_tools/src/commands/build.dart'; import 'package:flutter_tools/src/commands/build_aar.dart'; import 'package:flutter_tools/src/commands/build_apk.dart'; import 'package:flutter_tools/src/commands/build_appbundle.dart'; import 'package:flutter_tools/src/commands/build_ios.dart'; import 'package:flutter_tools/src/commands/build_ios_framework.dart'; import 'package:flutter_tools/src/commands/build_linux.dart'; import 'package:flutter_tools/src/commands/build_macos.dart'; import 'package:flutter_tools/src/commands/build_web.dart'; import 'package:flutter_tools/src/commands/build_windows.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:test/fake.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fakes.dart'; import '../../src/test_build_system.dart'; class FakeTerminal extends Fake implements AnsiTerminal { FakeTerminal({this.stdinHasTerminal = true}); @override final bool stdinHasTerminal; } class FakeProcessInfo extends Fake implements ProcessInfo { @override int maxRss = 0; } void main() { testUsingContext('All build commands support null safety options', () { final FileSystem fileSystem = MemoryFileSystem.test(); final Platform platform = FakePlatform(); final BufferLogger logger = BufferLogger.test(); final List<FlutterCommand> commands = <FlutterCommand>[ BuildWindowsCommand(logger: BufferLogger.test()), BuildLinuxCommand(logger: BufferLogger.test(), operatingSystemUtils: FakeOperatingSystemUtils()), BuildMacosCommand(logger: BufferLogger.test(), verboseHelp: false), BuildWebCommand(fileSystem: fileSystem, logger: BufferLogger.test(), verboseHelp: false), BuildApkCommand(logger: BufferLogger.test()), BuildIOSCommand(logger: BufferLogger.test(), verboseHelp: false), BuildIOSArchiveCommand(logger: BufferLogger.test(), verboseHelp: false), BuildAppBundleCommand(logger: BufferLogger.test()), BuildAarCommand( logger: BufferLogger.test(), androidSdk: FakeAndroidSdk(), fileSystem: fileSystem, verboseHelp: false, ), BuildIOSFrameworkCommand( logger: BufferLogger.test(), verboseHelp: false, buildSystem: FlutterBuildSystem( fileSystem: fileSystem, platform: platform, logger: logger, ), ), AttachCommand( stdio: FakeStdio(), logger: logger, terminal: FakeTerminal(), signals: Signals.test(), platform: platform, processInfo: FakeProcessInfo(), fileSystem: MemoryFileSystem.test(), ), ]; for (final FlutterCommand command in commands) { final ArgResults results = command.argParser.parse(<String>[ '--sound-null-safety', '--enable-experiment=non-nullable', ]); expect(results.wasParsed('sound-null-safety'), true); expect(results.wasParsed('enable-experiment'), true); } }); testUsingContext('BuildSubCommand displays current null safety mode', () async { const BuildInfo unsound = BuildInfo( BuildMode.debug, '', nullSafetyMode: NullSafetyMode.unsound, treeShakeIcons: false, ); final BufferLogger logger = BufferLogger.test(); FakeBuildSubCommand(logger).test(unsound); expect(logger.statusText, contains('Building without sound null safety ⚠️')); }); testUsingContext('Include only supported sub commands', () { final BuildCommand command = BuildCommand( androidSdk: FakeAndroidSdk(), buildSystem: TestBuildSystem.all(BuildResult(success: true)), fileSystem: MemoryFileSystem.test(), logger: BufferLogger.test(), osUtils: FakeOperatingSystemUtils(), ); for (final Command<void> x in command.subcommands.values) { expect((x as BuildSubCommand).supported, isTrue); } }); } class FakeBuildSubCommand extends BuildSubCommand { FakeBuildSubCommand(Logger logger) : super(logger: logger, verboseHelp: false); @override String get description => throw UnimplementedError(); @override String get name => throw UnimplementedError(); void test(BuildInfo buildInfo) { displayNullSafetyMode(buildInfo); } @override Future<FlutterCommandResult> runCommand() { throw UnimplementedError(); } }