// Copyright 2013 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/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/pubspec_check_command.dart';
import 'package:test/test.dart';

import 'mocks.dart';
import 'util.dart';

/// Returns the top section of a pubspec.yaml for a package named [name].
///
/// By default it will create a header that includes all of the expected
/// values, elements can be changed via arguments to create incorrect
/// entries.
///
/// If [includeRepository] is true, by default the path in the link will
/// be "packages/[name]"; a different "packages"-relative path can be
/// provided with [repositoryPackagesDirRelativePath].
String _headerSection(
  String name, {
  String repository = 'flutter/packages',
  bool includeRepository = true,
  String repositoryBranch = 'main',
  String? repositoryPackagesDirRelativePath,
  bool includeHomepage = false,
  bool includeIssueTracker = true,
  bool publishable = true,
  String? description,
}) {
  final String repositoryPath = repositoryPackagesDirRelativePath ?? name;
  final List<String> repoLinkPathComponents = <String>[
    repository,
    'tree',
    repositoryBranch,
    'packages',
    repositoryPath,
  ];
  final String repoLink =
      'https://github.com/${repoLinkPathComponents.join('/')}';
  final String issueTrackerLink = 'https://github.com/flutter/flutter/issues?'
      'q=is%3Aissue+is%3Aopen+label%3A%22p%3A+$name%22';
  description ??= 'A test package for validating that the pubspec.yaml '
      'follows repo best practices.';
  return '''
name: $name
description: $description
${includeRepository ? 'repository: $repoLink' : ''}
${includeHomepage ? 'homepage: $repoLink' : ''}
${includeIssueTracker ? 'issue_tracker: $issueTrackerLink' : ''}
version: 1.0.0
${publishable ? '' : "publish_to: 'none'"}
''';
}

String _environmentSection({
  String dartConstraint = '>=2.17.0 <4.0.0',
  String? flutterConstraint = '>=3.0.0',
}) {
  return <String>[
    'environment:',
    '  sdk: "$dartConstraint"',
    if (flutterConstraint != null) '  flutter: "$flutterConstraint"',
    '',
  ].join('\n');
}

String _flutterSection({
  bool isPlugin = false,
  String? implementedPackage,
  Map<String, Map<String, String>> pluginPlatformDetails =
      const <String, Map<String, String>>{},
}) {
  String pluginEntry = '''
  plugin:
${implementedPackage == null ? '' : '    implements: $implementedPackage'}
    platforms:
''';

  for (final MapEntry<String, Map<String, String>> platform
      in pluginPlatformDetails.entries) {
    pluginEntry += '''
      ${platform.key}:
''';
    for (final MapEntry<String, String> detail in platform.value.entries) {
      pluginEntry += '''
        ${detail.key}: ${detail.value}
''';
    }
  }

  return '''
flutter:
${isPlugin ? pluginEntry : ''}
''';
}

String _dependenciesSection(
    [List<String> extraDependencies = const <String>[]]) {
  return '''
dependencies:
  flutter:
    sdk: flutter
${extraDependencies.map((String dep) => '  $dep').join('\n')}
''';
}

String _devDependenciesSection(
    [List<String> extraDependencies = const <String>[]]) {
  return '''
dev_dependencies:
  flutter_test:
    sdk: flutter
${extraDependencies.map((String dep) => '  $dep').join('\n')}
''';
}

String _topicsSection([List<String> topics = const <String>['a-topic']]) {
  return '''
topics:
${topics.map((String topic) => '  - $topic').join('\n')}
''';
}

String _falseSecretsSection() {
  return '''
false_secrets:
  - /lib/main.dart
''';
}

void main() {
  group('test pubspec_check_command', () {
    late CommandRunner<void> runner;
    late RecordingProcessRunner processRunner;
    late FileSystem fileSystem;
    late MockPlatform mockPlatform;
    late Directory packagesDir;

    setUp(() {
      fileSystem = MemoryFileSystem();
      mockPlatform = MockPlatform();
      packagesDir = fileSystem.currentDirectory.childDirectory('packages');
      createPackagesDirectory(parentDir: packagesDir.parent);
      processRunner = RecordingProcessRunner();
      final PubspecCheckCommand command = PubspecCheckCommand(
        packagesDir,
        processRunner: processRunner,
        platform: mockPlatform,
      );

      runner = CommandRunner<void>(
          'pubspec_check_command', 'Test for pubspec_check_command');
      runner.addCommand(command);
    });

    test('passes for a plugin following conventions', () async {
      final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
${_falseSecretsSection()}
''');

      plugin.getExamples().first.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_example',
        publishable: false,
        includeRepository: false,
        includeIssueTracker: false,
      )}
${_environmentSection()}
${_dependenciesSection()}
${_flutterSection()}
''');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin...'),
          contains('Running for plugin/example...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('passes for a Flutter package following conventions', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection()}
${_devDependenciesSection()}
${_flutterSection()}
${_topicsSection()}
${_falseSecretsSection()}
''');

      package.getExamples().first.pubspecFile.writeAsStringSync('''
${_headerSection(
        'a_package',
        publishable: false,
        includeRepository: false,
        includeIssueTracker: false,
      )}
${_environmentSection()}
${_dependenciesSection()}
${_flutterSection()}
''');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for a_package...'),
          contains('Running for a_package/example...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('passes for a minimal package following conventions', () async {
      final RepositoryPackage package =
          createFakePackage('package', packagesDir, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('package')}
${_environmentSection()}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for package...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('fails when homepage is included', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', includeHomepage: true)}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Found a "homepage" entry; only "repository" should be used.'),
        ]),
      );
    });

    test('fails when repository is missing', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', includeRepository: false)}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Missing "repository"'),
        ]),
      );
    });

    test('fails when homepage is given instead of repository', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', includeHomepage: true, includeRepository: false)}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Found a "homepage" entry; only "repository" should be used.'),
        ]),
      );
    });

    test('fails when repository package name is incorrect', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', repositoryPackagesDirRelativePath: 'different_plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('The "repository" link should end with the package path.'),
        ]),
      );
    });

    test('fails when repository uses master instead of main', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', repositoryBranch: 'master')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('The "repository" link should start with the repository\'s '
              'main tree: "https://github.com/flutter/packages/tree/main"'),
        ]),
      );
    });

    test('fails when repository is not flutter/packages', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', repository: 'flutter/plugins')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('The "repository" link should start with the repository\'s '
              'main tree: "https://github.com/flutter/packages/tree/main"'),
        ]),
      );
    });

    test('fails when issue tracker is missing', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', includeIssueTracker: false)}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('A package should have an "issue_tracker" link'),
        ]),
      );
    });

    test('fails when description is too short', () async {
      final RepositoryPackage plugin = createFakePlugin(
          'a_plugin', packagesDir.childDirectory('a_plugin'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', description: 'Too short')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('"description" is too short. pub.dev recommends package '
              'descriptions of 60-180 characters.'),
        ]),
      );
    });

    test(
        'allows short descriptions for non-app-facing parts of federated plugins',
        () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', description: 'Too short')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('"description" is too short. pub.dev recommends package '
              'descriptions of 60-180 characters.'),
        ]),
      );
    });

    test('fails when description is too long', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      const String description = 'This description is too long. It just goes '
          'on and on and on and on and on. pub.dev will down-score it because '
          'there is just too much here. Someone shoul really cut this down to just '
          'the core description so that search results are more useful and the '
          'package does not lose pub points.';
      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin', description: description)}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('"description" is too long. pub.dev recommends package '
              'descriptions of 60-180 characters.'),
        ]),
      );
    });

    test('fails when topics section is missing', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('A published package should include "topics".'),
        ]),
      );
    });

    test('fails when topics section is empty', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection(<String>[])}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('A published package should include "topics".'),
        ]),
      );
    });

    test('fails when federated plugin topics do not include plugin name',
        () async {
      final RepositoryPackage plugin = createFakePlugin(
          'some_plugin_ios', packagesDir.childDirectory('some_plugin'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'A federated plugin package should include its plugin name as a topic. '
              'Add "some-plugin" to the "topics" section.'),
        ]),
      );
    });

    test('fails when environment section is out of order', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_environmentSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
        ]),
      );
    });

    test('fails when flutter section is out of order', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_flutterSection(isPlugin: true)}
${_environmentSection()}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
        ]),
      );
    });

    test('fails when dependencies section is out of order', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_devDependenciesSection()}
${_dependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
        ]),
      );
    });

    test('fails when dev_dependencies section is out of order', () async {
      final RepositoryPackage plugin = createFakePlugin('plugin', packagesDir);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_devDependenciesSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
        ]),
      );
    });

    test('fails when false_secrets section is out of order', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_falseSecretsSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
        ]),
      );
    });

    test('fails when an implemenation package is missing "implements"',
        () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin_a_foo')}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Missing "implements: plugin_a" in "plugin" section.'),
        ]),
      );
    });

    test('fails when an implemenation package has the wrong "implements"',
        () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin_a_foo')}
${_environmentSection()}
${_flutterSection(isPlugin: true, implementedPackage: 'plugin_a_foo')}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Expecetd "implements: plugin_a"; '
              'found "implements: plugin_a_foo".'),
        ]),
      );
    });

    test('passes for a correct implemenation package', () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_a_foo',
        repositoryPackagesDirRelativePath: 'plugin_a/plugin_a_foo',
      )}
${_environmentSection()}
${_flutterSection(isPlugin: true, implementedPackage: 'plugin_a')}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection(<String>['plugin-a'])}
''');

      final List<String> output =
          await runCapturingPrint(runner, <String>['pubspec-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin_a_foo...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('fails when a "default_package" looks incorrect', () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_a',
        repositoryPackagesDirRelativePath: 'plugin_a/plugin_a',
      )}
${_environmentSection()}
${_flutterSection(
        isPlugin: true,
        pluginPlatformDetails: <String, Map<String, String>>{
          'android': <String, String>{'default_package': 'plugin_b_android'}
        },
      )}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              '"plugin_b_android" is not an expected implementation name for "plugin_a"'),
        ]),
      );
    });

    test(
        'fails when a "default_package" does not have a corresponding dependency',
        () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_a',
        repositoryPackagesDirRelativePath: 'plugin_a/plugin_a',
      )}
${_environmentSection()}
${_flutterSection(
        isPlugin: true,
        pluginPlatformDetails: <String, Map<String, String>>{
          'android': <String, String>{'default_package': 'plugin_a_android'}
        },
      )}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('The following default_packages are missing corresponding '
              'dependencies:\n  plugin_a_android'),
        ]),
      );
    });

    test('passes for an app-facing package without "implements"', () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_a',
        repositoryPackagesDirRelativePath: 'plugin_a/plugin_a',
      )}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection(<String>['plugin-a'])}
''');

      final List<String> output =
          await runCapturingPrint(runner, <String>['pubspec-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin_a/plugin_a...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('passes for a platform interface package without "implements"',
        () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a_platform_interface', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin_a_platform_interface',
        repositoryPackagesDirRelativePath:
            'plugin_a/plugin_a_platform_interface',
      )}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_topicsSection(<String>['plugin-a'])}
''');

      final List<String> output =
          await runCapturingPrint(runner, <String>['pubspec-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin_a_platform_interface...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('validates some properties even for unpublished packages', () async {
      final RepositoryPackage plugin = createFakePlugin(
          'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
          examples: <String>[]);

      // Environment section is in the wrong location.
      // Missing 'implements'.
      plugin.pubspecFile.writeAsStringSync('''
${_headerSection('plugin_a_foo', publishable: false)}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
${_environmentSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['pubspec-check'], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains(
              'Major sections should follow standard repository ordering:'),
          contains('Missing "implements: plugin_a" in "plugin" section.'),
        ]),
      );
    });

    test('ignores some checks for unpublished packages', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, examples: <String>[]);

      // Missing metadata that is only useful for published packages, such as
      // repository and issue tracker.
      plugin.pubspecFile.writeAsStringSync('''
${_headerSection(
        'plugin',
        publishable: false,
        includeRepository: false,
        includeIssueTracker: false,
      )}
${_environmentSection()}
${_flutterSection(isPlugin: true)}
${_dependenciesSection()}
${_devDependenciesSection()}
''');

      final List<String> output =
          await runCapturingPrint(runner, <String>['pubspec-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('fails when a Flutter package has a too-low minimum Flutter version',
        () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(flutterConstraint: '>=2.10.0')}
${_dependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
        '--min-min-flutter-version',
        '3.0.0'
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Minimum allowed Flutter version 2.10.0 is less than 3.0.0'),
        ]),
      );
    });

    test(
        'passes when a Flutter package requires exactly the minimum Flutter version',
        () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(flutterConstraint: '>=3.3.0', dartConstraint: '>=2.18.0 <4.0.0')}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output = await runCapturingPrint(runner,
          <String>['pubspec-check', '--min-min-flutter-version', '3.3.0']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for a_package...'),
          contains('No issues found!'),
        ]),
      );
    });

    test(
        'passes when a Flutter package requires a higher minimum Flutter version',
        () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(flutterConstraint: '>=3.7.0', dartConstraint: '>=2.19.0 <4.0.0')}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output = await runCapturingPrint(runner,
          <String>['pubspec-check', '--min-min-flutter-version', '3.3.0']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for a_package...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('fails when a non-Flutter package has a too-low minimum Dart version',
        () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(dartConstraint: '>=2.14.0 <4.0.0', flutterConstraint: null)}
${_dependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
        '--min-min-flutter-version',
        '3.0.0'
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Minimum allowed Dart version 2.14.0 is less than 2.17.0'),
        ]),
      );
    });

    test(
        'passes when a non-Flutter package requires exactly the minimum Dart version',
        () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(dartConstraint: '>=2.18.0 <4.0.0', flutterConstraint: null)}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output = await runCapturingPrint(runner,
          <String>['pubspec-check', '--min-min-flutter-version', '3.3.0']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for a_package...'),
          contains('No issues found!'),
        ]),
      );
    });

    test(
        'passes when a non-Flutter package requires a higher minimum Dart version',
        () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(dartConstraint: '>=2.18.0 <4.0.0', flutterConstraint: null)}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output = await runCapturingPrint(runner,
          <String>['pubspec-check', '--min-min-flutter-version', '3.0.0']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for a_package...'),
          contains('No issues found!'),
        ]),
      );
    });

    test('fails when a Flutter->Dart SDK version mapping is missing', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
        '--min-min-flutter-version',
        '2.0.0'
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Dart SDK version for Fluter SDK version 2.0.0 is unknown'),
        ]),
      );
    });

    test(
        'fails when a Flutter package has a too-low minimum Dart version for '
        'the corresponding minimum Flutter version', () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          isFlutter: true, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection(flutterConstraint: '>=3.3.0', dartConstraint: '>=2.16.0 <4.0.0')}
${_dependenciesSection()}
${_topicsSection()}
''');

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'pubspec-check',
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('The minimum Dart version is 2.16.0, but the '
              'minimum Flutter version of 3.3.0 shipped with '
              'Dart 2.18.0. Please use consistent lower SDK '
              'bounds'),
        ]),
      );
    });

    group('dependency check', () {
      test('passes for local dependencies', () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir);
        final RepositoryPackage dependencyPackage =
            createFakePackage('local_dependency', packagesDir);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['local_dependency: ^1.0.0'])}
${_topicsSection()}
''');
        dependencyPackage.pubspecFile.writeAsStringSync('''
${_headerSection('local_dependency')}
${_environmentSection()}
${_dependenciesSection()}
${_topicsSection()}
''');

        final List<String> output =
            await runCapturingPrint(runner, <String>['pubspec-check']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for a_package...'),
            contains('No issues found!'),
          ]),
        );
      });

      test('fails when an unexpected dependency is found', () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir, examples: <String>[]);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['bad_dependency: ^1.0.0'])}
${_topicsSection()}
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'pubspec-check',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'The following unexpected non-local dependencies were found:\n'
                '  bad_dependency\n'
                'Please see https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#Dependencies '
                'for more information and next steps.'),
          ]),
        );
      });

      test('fails when an unexpected dev dependency is found', () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir, examples: <String>[]);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection()}
${_devDependenciesSection(<String>['bad_dependency: ^1.0.0'])}
${_topicsSection()}
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'pubspec-check',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'The following unexpected non-local dependencies were found:\n'
                '  bad_dependency\n'
                'Please see https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#Dependencies '
                'for more information and next steps.'),
          ]),
        );
      });

      test('passes when a dependency is on the allow list', () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['allowed: ^1.0.0'])}
${_topicsSection()}
''');

        final List<String> output = await runCapturingPrint(runner,
            <String>['pubspec-check', '--allow-dependencies', 'allowed']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for a_package...'),
            contains('No issues found!'),
          ]),
        );
      });

      test('passes when a pinned dependency is on the pinned allow list',
          () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['allow_pinned: 1.0.0'])}
${_topicsSection()}
''');

        final List<String> output = await runCapturingPrint(runner, <String>[
          'pubspec-check',
          '--allow-pinned-dependencies',
          'allow_pinned'
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for a_package...'),
            contains('No issues found!'),
          ]),
        );
      });

      test('fails when an allowed-when-pinned dependency is unpinned',
          () async {
        final RepositoryPackage package =
            createFakePackage('a_package', packagesDir);

        package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['allow_pinned: ^1.0.0'])}
${_topicsSection()}
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'pubspec-check',
          '--allow-pinned-dependencies',
          'allow_pinned'
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'The following unexpected non-local dependencies were found:\n'
                '  allow_pinned\n'
                'Please see https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#Dependencies '
                'for more information and next steps.'),
          ]),
        );
      });
    });
  });

  group('test pubspec_check_command on Windows', () {
    late CommandRunner<void> runner;
    late RecordingProcessRunner processRunner;
    late FileSystem fileSystem;
    late MockPlatform mockPlatform;
    late Directory packagesDir;

    setUp(() {
      fileSystem = MemoryFileSystem(style: FileSystemStyle.windows);
      mockPlatform = MockPlatform(isWindows: true);
      packagesDir = fileSystem.currentDirectory.childDirectory('packages');
      createPackagesDirectory(parentDir: packagesDir.parent);
      processRunner = RecordingProcessRunner();
      final PubspecCheckCommand command = PubspecCheckCommand(
        packagesDir,
        processRunner: processRunner,
        platform: mockPlatform,
      );

      runner = CommandRunner<void>(
          'pubspec_check_command', 'Test for pubspec_check_command');
      runner.addCommand(command);
    });

    test('repository check works', () async {
      final RepositoryPackage package =
          createFakePackage('package', packagesDir, examples: <String>[]);

      package.pubspecFile.writeAsStringSync('''
${_headerSection('package')}
${_environmentSection()}
${_dependenciesSection()}
${_topicsSection()}
''');

      final List<String> output =
          await runCapturingPrint(runner, <String>['pubspec-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for package...'),
          contains('No issues found!'),
        ]),
      );
    });
  });
}
