| // 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 'dart:async'; |
| import 'dart:convert'; |
| |
| import 'package:args/command_runner.dart'; |
| import 'package:file/memory.dart'; |
| import 'package:flutter_tools/src/artifacts.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:flutter_tools/src/base/platform.dart'; |
| import 'package:flutter_tools/src/base/terminal.dart'; |
| import 'package:flutter_tools/src/cache.dart'; |
| import 'package:flutter_tools/src/commands/analyze.dart'; |
| import 'package:flutter_tools/src/commands/ios_analyze.dart'; |
| import 'package:flutter_tools/src/ios/xcodeproj.dart'; |
| import 'package:flutter_tools/src/project.dart'; |
| import 'package:flutter_tools/src/project_validator.dart'; |
| import 'package:test/fake.dart'; |
| |
| import '../../src/common.dart'; |
| import '../../src/context.dart'; |
| import '../../src/test_flutter_command_runner.dart'; |
| |
| void main() { |
| group('ios analyze command', () { |
| late BufferLogger logger; |
| late FileSystem fileSystem; |
| late Platform platform; |
| late FakeProcessManager processManager; |
| late Terminal terminal; |
| late AnalyzeCommand command; |
| late CommandRunner<void> runner; |
| |
| setUpAll(() { |
| Cache.disableLocking(); |
| }); |
| |
| setUp(() { |
| logger = BufferLogger.test(); |
| fileSystem = MemoryFileSystem.test(); |
| platform = FakePlatform(); |
| processManager = FakeProcessManager.empty(); |
| terminal = Terminal.test(); |
| command = AnalyzeCommand( |
| artifacts: Artifacts.test(), |
| fileSystem: fileSystem, |
| logger: logger, |
| platform: platform, |
| processManager: processManager, |
| terminal: terminal, |
| allProjectValidators: <ProjectValidator>[], |
| suppressAnalytics: true, |
| ); |
| runner = createTestCommandRunner(command); |
| |
| // Setup repo roots |
| const String homePath = '/home/user/flutter'; |
| Cache.flutterRoot = homePath; |
| for (final String dir in <String>['dev', 'examples', 'packages']) { |
| fileSystem.directory(homePath).childDirectory(dir).createSync(recursive: true); |
| } |
| }); |
| |
| testWithoutContext('can output json file', () async { |
| final MockIosProject ios = MockIosProject(); |
| final MockFlutterProject project = MockFlutterProject(ios); |
| const String expectedConfig = 'someConfig'; |
| const String expectedTarget = 'someTarget'; |
| const String expectedOutputFile = '/someFile'; |
| ios.outputFileLocation = expectedOutputFile; |
| await IOSAnalyze( |
| project: project, |
| option: IOSAnalyzeOption.outputUniversalLinkSettings, |
| configuration: expectedConfig, |
| target: expectedTarget, |
| logger: logger, |
| ).analyze(); |
| expect(logger.statusText, contains(expectedOutputFile)); |
| expect(ios.outputConfiguration, expectedConfig); |
| expect(ios.outputTarget, expectedTarget); |
| }); |
| |
| testWithoutContext('can list build options', () async { |
| final MockIosProject ios = MockIosProject(); |
| final MockFlutterProject project = MockFlutterProject(ios); |
| const List<String> targets = <String>['target1', 'target2']; |
| const List<String> configs = <String>['config1', 'config2']; |
| ios.expectedProjectInfo = XcodeProjectInfo(targets, configs, const <String>[], logger); |
| await IOSAnalyze( |
| project: project, |
| option: IOSAnalyzeOption.listBuildOptions, |
| logger: logger, |
| ).analyze(); |
| final Map<String, Object?> jsonOutput = jsonDecode(logger.statusText) as Map<String, Object?>; |
| expect(jsonOutput['targets'], unorderedEquals(targets)); |
| expect(jsonOutput['configurations'], unorderedEquals(configs)); |
| }); |
| |
| testUsingContext('throws if provide multiple path', () async { |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('someTemp'); |
| final Directory anotherTempDir = fileSystem.systemTempDirectory.createTempSync('another'); |
| await expectLater( |
| runner.run(<String>['analyze', '--ios', '--list-build-options', tempDir.path, anotherTempDir.path]), |
| throwsA( |
| isA<Exception>().having( |
| (Exception e) => e.toString(), |
| 'description', |
| contains('The iOS analyze can process only one directory path'), |
| ), |
| ), |
| ); |
| }); |
| |
| testUsingContext('throws if not enough parameters', () async { |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('someTemp'); |
| await expectLater( |
| runner.run(<String>['analyze', '--ios', '--output-universal-link-settings', tempDir.path]), |
| throwsA( |
| isA<Exception>().having( |
| (Exception e) => e.toString(), |
| 'description', |
| contains('"--configuration" must be provided'), |
| ), |
| ), |
| ); |
| }); |
| }); |
| } |
| |
| class MockFlutterProject extends Fake implements FlutterProject { |
| MockFlutterProject(this.ios); |
| |
| @override |
| final IosProject ios; |
| } |
| |
| class MockIosProject extends Fake implements IosProject { |
| String? outputConfiguration; |
| String? outputTarget; |
| late String outputFileLocation; |
| late XcodeProjectInfo expectedProjectInfo; |
| |
| @override |
| Future<String> outputsUniversalLinkSettings({required String configuration, required String target}) async { |
| outputConfiguration = configuration; |
| outputTarget = target; |
| return outputFileLocation; |
| } |
| @override |
| Future<XcodeProjectInfo> projectInfo() async => expectedProjectInfo; |
| |
| } |