// 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 'dart:convert';
import 'dart:io' as io;

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/version_check_command.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:mockito/mockito.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';

import 'common/plugin_command_test.mocks.dart';
import 'mocks.dart';
import 'util.dart';

void testAllowedVersion(
  String mainVersion,
  String headVersion, {
  bool allowed = true,
  NextVersionType? nextVersionType,
}) {
  final Version main = Version.parse(mainVersion);
  final Version head = Version.parse(headVersion);
  final Map<Version, NextVersionType> allowedVersions =
      getAllowedNextVersions(main, newVersion: head);
  if (allowed) {
    expect(allowedVersions, contains(head));
    if (nextVersionType != null) {
      expect(allowedVersions[head], equals(nextVersionType));
    }
  } else {
    expect(allowedVersions, isNot(contains(head)));
  }
}

String _generateFakeDependabotPRDescription(String package) {
  return '''
Bumps [$package](https://github.com/foo/$package) from 1.0.0 to 2.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/foo/$package">$package's releases</a>.</em></p>
<blockquote>
...
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>...</li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=$package&package-manager=gradle&previous-version=1.0.0&new-version=2.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
''';
}

String _generateFakeDependabotCommitMessage(String package) {
  return '''
Bumps [$package](https://github.com/foo/$package) from 1.0.0 to 2.0.0.
- [Release notes](https://github.com/foo/$package/releases)
- [Commits](foo/$package@v4.3.1...v4.6.1)

---
updated-dependencies:
- dependency-name: $package
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
''';
}

class MockProcessResult extends Mock implements io.ProcessResult {}

void main() {
  const String indentation = '  ';
  group('VersionCheckCommand', () {
    late FileSystem fileSystem;
    late MockPlatform mockPlatform;
    late Directory packagesDir;
    late CommandRunner<void> runner;
    late RecordingProcessRunner processRunner;
    late MockGitDir gitDir;
    // Ignored if mockHttpResponse is set.
    int mockHttpStatus;
    Map<String, dynamic>? mockHttpResponse;

    setUp(() {
      fileSystem = MemoryFileSystem();
      mockPlatform = MockPlatform();
      packagesDir = createPackagesDirectory(fileSystem: fileSystem);

      gitDir = MockGitDir();
      when(gitDir.path).thenReturn(packagesDir.parent.path);
      when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError')))
          .thenAnswer((Invocation invocation) {
        final List<String> arguments =
            invocation.positionalArguments[0]! as List<String>;
        // Route git calls through the process runner, to make mock output
        // consistent with other processes. Attach the first argument to the
        // command to make targeting the mock results easier.
        final String gitCommand = arguments.removeAt(0);
        return processRunner.run('git-$gitCommand', arguments);
      });

      // Default to simulating the plugin never having been published.
      mockHttpStatus = 404;
      mockHttpResponse = null;
      final MockClient mockClient = MockClient((http.Request request) async {
        return http.Response(json.encode(mockHttpResponse),
            mockHttpResponse == null ? mockHttpStatus : 200);
      });

      processRunner = RecordingProcessRunner();
      final VersionCheckCommand command = VersionCheckCommand(packagesDir,
          processRunner: processRunner,
          platform: mockPlatform,
          gitDir: gitDir,
          httpClient: mockClient);

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

    test('allows valid version', () async {
      createFakePlugin('plugin', packagesDir, version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
          contains('1.0.0 -> 2.0.0'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show', <String>['main:packages/plugin/pubspec.yaml'], null)
          ]));
    });

    test('denies invalid version', () async {
      createFakePlugin('plugin', packagesDir, version: '0.2.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 0.0.1'),
      ];
      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main'],
          errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Incorrectly updated version.'),
          ]));
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show', <String>['main:packages/plugin/pubspec.yaml'], null)
          ]));
    });

    test('uses merge-base without explicit base-sha', () async {
      createFakePlugin('plugin', packagesDir, version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-merge-base'] = <io.Process>[
        MockProcess(stdout: 'abc123'),
        MockProcess(stdout: 'abc123'),
      ];
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final List<String> output =
          await runCapturingPrint(runner, <String>['version-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
          contains('1.0.0 -> 2.0.0'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall('git-merge-base',
                <String>['--fork-point', 'FETCH_HEAD', 'HEAD'], null),
            ProcessCall('git-show',
                <String>['abc123:packages/plugin/pubspec.yaml'], null),
          ]));
    });

    test('allows valid version for new package.', () async {
      createFakePlugin('plugin', packagesDir, version: '1.0.0');
      final List<String> output =
          await runCapturingPrint(runner, <String>['version-check']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
          contains('Unable to find previous version at git base.'),
        ]),
      );
    });

    test('allows likely reverts.', () async {
      createFakePlugin('plugin', packagesDir, version: '0.6.1');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 0.6.2'),
      ];
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('New version is lower than previous version. '
              'This is assumed to be a revert.'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show', <String>['main:packages/plugin/pubspec.yaml'], null)
          ]));
    });

    test('denies lower version that could not be a simple revert', () async {
      createFakePlugin('plugin', packagesDir, version: '0.5.1');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 0.6.2'),
      ];

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

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Incorrectly updated version.'),
          ]));
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show', <String>['main:packages/plugin/pubspec.yaml'], null)
          ]));
    });

    test('allows minor changes to platform interfaces', () async {
      createFakePlugin('plugin_platform_interface', packagesDir,
          version: '1.1.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
          contains('1.0.0 -> 1.1.0'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show',
                <String>[
                  'main:packages/plugin_platform_interface/pubspec.yaml'
                ],
                null)
          ]));
    });

    test('disallows breaking changes to platform interfaces by default',
        () async {
      createFakePlugin('plugin_platform_interface', packagesDir,
          version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main'],
          errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                '  Breaking changes to platform interfaces are not allowed '
                'without explicit justification.\n'
                '  See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages '
                'for more information.'),
          ]));
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show',
                <String>[
                  'main:packages/plugin_platform_interface/pubspec.yaml'
                ],
                null)
          ]));
    });

    test('allows breaking changes to platform interfaces with override label',
        () async {
      createFakePlugin('plugin_platform_interface', packagesDir,
          version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];

      final List<String> output = await runCapturingPrint(runner, <String>[
        'version-check',
        '--base-sha=main',
        '--pr-labels=some label,override: allow breaking change,another-label'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Allowing breaking change to plugin_platform_interface '
              'due to the "override: allow breaking change" label.'),
          contains('Ran for 1 package(s) (1 with warnings)'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show',
                <String>[
                  'main:packages/plugin_platform_interface/pubspec.yaml'
                ],
                null)
          ]));
    });

    test('allows breaking changes to platform interfaces with bypass flag',
        () async {
      createFakePlugin('plugin_platform_interface', packagesDir,
          version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final List<String> output = await runCapturingPrint(runner, <String>[
        'version-check',
        '--base-sha=main',
        '--ignore-platform-interface-breaks'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Allowing breaking change to plugin_platform_interface due '
              'to --ignore-platform-interface-breaks'),
          contains('Ran for 1 package(s) (1 with warnings)'),
        ]),
      );
      expect(
          processRunner.recordedCalls,
          containsAllInOrder(const <ProcessCall>[
            ProcessCall(
                'git-show',
                <String>[
                  'main:packages/plugin_platform_interface/pubspec.yaml'
                ],
                null)
          ]));
    });

    test('Allow empty lines in front of the first version in CHANGELOG',
        () async {
      const String version = '1.0.1';
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: version);
      const String changelog = '''

## $version
* Some changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
        ]),
      );
    });

    test('Throws if versions in changelog and pubspec do not match', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.1');
      const String changelog = '''
## 1.0.2
* Some changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      Error? commandError;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Versions in CHANGELOG.md and pubspec.yaml do not match.'),
        ]),
      );
    });

    test('Success if CHANGELOG and pubspec versions match', () async {
      const String version = '1.0.1';
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: version);

      const String changelog = '''
## $version
* Some changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
        ]),
      );
    });

    test(
        'Fail if pubspec version only matches an older version listed in CHANGELOG',
        () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.0');

      const String changelog = '''
## 1.0.1
* Some changes.
## 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      bool hasError = false;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Versions in CHANGELOG.md and pubspec.yaml do not match.'),
        ]),
      );
    });

    test('Allow NEXT as a placeholder for gathering CHANGELOG entries',
        () async {
      const String version = '1.0.0';
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: version);

      const String changelog = '''
## NEXT
* Some changes that won't be published until the next time there's a release.
## $version
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];

      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Running for plugin'),
          contains('Found NEXT; validating next version in the CHANGELOG.'),
        ]),
      );
    });

    test('Fail if NEXT appears after a version', () async {
      const String version = '1.0.1';
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: version);

      const String changelog = '''
## $version
* Some changes.
## NEXT
* Some changes that should have been folded in 1.0.1.
## 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      bool hasError = false;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('When bumping the version for release, the NEXT section '
              "should be incorporated into the new version's release notes.")
        ]),
      );
    });

    test('Fail if NEXT is left in the CHANGELOG when adding a version bump',
        () async {
      const String version = '1.0.1';
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: version);

      const String changelog = '''
## NEXT
* Some changes that should have been folded in 1.0.1.
## $version
* Some changes.
## 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);

      bool hasError = false;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('When bumping the version for release, the NEXT section '
              "should be incorporated into the new version's release notes."),
          contains('plugin:\n'
              '    CHANGELOG.md failed validation.'),
        ]),
      );
    });

    test('fails if the version increases without replacing NEXT', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.1');

      const String changelog = '''
## NEXT
* Some changes that should be listed as part of 1.0.1.
## 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);

      bool hasError = false;
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('When bumping the version for release, the NEXT section '
              "should be incorporated into the new version's release notes.")
        ]),
      );
    });

    test('allows NEXT for a revert', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.0');

      const String changelog = '''
## NEXT
* Some changes that should be listed as part of 1.0.1.
## 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      plugin.changelogFile.writeAsStringSync(changelog);
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.1'),
      ];

      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main']);
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('New version is lower than previous version. '
              'This is assumed to be a revert.'),
        ]),
      );
    });

    test(
        'fails gracefully if the version headers are not found due to using the wrong style',
        () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.0');

      const String changelog = '''
## NEXT
* Some changes for a later release.
# 1.0.0
* Some other changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];

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

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Unable to find a version in CHANGELOG.md'),
          contains('The current version should be on a line starting with '
              '"## ", either on the first non-empty line or after a "## NEXT" '
              'section.'),
        ]),
      );
    });

    test('fails gracefully if the version is unparseable', () async {
      final RepositoryPackage plugin =
          createFakePlugin('plugin', packagesDir, version: '1.0.0');

      const String changelog = '''
## Alpha
* Some changes.
''';
      plugin.changelogFile.writeAsStringSync(changelog);
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];

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

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('"Alpha" could not be parsed as a version.'),
        ]),
      );
    });

    group('missing change detection', () {
      Future<List<String>> _runWithMissingChangeDetection(
          List<String> extraArgs,
          {void Function(Error error)? errorHandler}) async {
        return runCapturingPrint(
            runner,
            <String>[
              'version-check',
              '--base-sha=main',
              '--check-for-missing-changes',
              ...extraArgs,
            ],
            errorHandler: errorHandler);
      }

      test('passes for unchanged packages', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: ''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
          ]),
        );
      });

      test(
          'fails if a version change is missing from a change that does not '
          'pass the exemption check', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/lib/plugin.dart
'''),
        ];

        Error? commandError;
        final List<String> output = await _runWithMissingChangeDetection(
            <String>[], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('No version change found'),
            contains('plugin:\n'
                '    Missing version change'),
          ]),
        );
      });

      test('passes version change requirement when version changes', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.1');

        const String changelog = '''
## 1.0.1
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/lib/plugin.dart
packages/plugin/CHANGELOG.md
packages/plugin/pubspec.yaml
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
          ]),
        );
      });

      test('version change check ignores files outside the package', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin_a/lib/plugin.dart
tool/plugin/lib/plugin.dart
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
          ]),
        );
      });

      test('allows missing version change for exempt changes', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/example/android/lint-baseline.xml
packages/plugin/example/android/src/androidTest/foo/bar/FooTest.java
packages/plugin/example/ios/RunnerTests/Foo.m
packages/plugin/example/ios/RunnerUITests/info.plist
packages/plugin/CHANGELOG.md
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
          ]),
        );
      });

      test('allows missing version change with override label', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/lib/plugin.dart
packages/plugin/CHANGELOG.md
packages/plugin/pubspec.yaml
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[
          '--pr-labels=some label,override: no versioning needed,another-label'
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Ignoring lack of version change due to the '
                '"override: no versioning needed" label.'),
          ]),
        );
      });

      test('fails if a CHANGELOG change is missing', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/example/lib/foo.dart
'''),
        ];

        Error? commandError;
        final List<String> output = await _runWithMissingChangeDetection(
            <String>[], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('No CHANGELOG change found'),
            contains('plugin:\n'
                '    Missing CHANGELOG change'),
          ]),
        );
      });

      test('passes CHANGELOG check when the CHANGELOG is changed', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/example/lib/foo.dart
packages/plugin/CHANGELOG.md
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
          ]),
        );
      });

      test('fails CHANGELOG check if only another package CHANGELOG chages',
          () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/example/lib/foo.dart
packages/another_plugin/CHANGELOG.md
'''),
        ];

        Error? commandError;
        final List<String> output = await _runWithMissingChangeDetection(
            <String>[], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('No CHANGELOG change found'),
          ]),
        );
      });

      test('allows missing CHANGELOG change with justification', () async {
        final RepositoryPackage plugin =
            createFakePlugin('plugin', packagesDir, version: '1.0.0');

        const String changelog = '''
## 1.0.0
* Some changes.
''';
        plugin.changelogFile.writeAsStringSync(changelog);
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
          MockProcess(stdout: '''
packages/plugin/example/lib/foo.dart
'''),
        ];

        final List<String> output =
            await _runWithMissingChangeDetection(<String>[
          '--pr-labels=some label,override: no changelog needed,another-label'
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Ignoring lack of CHANGELOG update due to the '
                '"override: no changelog needed" label.'),
          ]),
        );
      });

      group('dependabot', () {
        test('throws if a nonexistent change description file is specified',
            () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          Error? commandError;
          final List<String> output = await _runWithMissingChangeDetection(
              <String>['--change-description-file=a_missing_file.txt'],
              errorHandler: (Error e) {
            commandError = e;
          });

          expect(commandError, isA<ToolExit>());
          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('No such file: a_missing_file.txt'),
            ]),
          );
        });

        test('allows missing version and CHANGELOG change for mockito',
            () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          final File changeDescriptionFile =
              fileSystem.file('change_description.txt');
          changeDescriptionFile.writeAsStringSync(
              _generateFakeDependabotPRDescription('mockito-core'));

          final List<String> output =
              await _runWithMissingChangeDetection(<String>[
            '--change-description-file=${changeDescriptionFile.path}'
          ]);

          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Ignoring lack of version change for Dependabot '
                  'change to a known internal dependency.'),
              contains('Ignoring lack of CHANGELOG update for Dependabot '
                  'change to a known internal dependency.'),
            ]),
          );
        });

        test('allows missing version and CHANGELOG change for robolectric',
            () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          final File changeDescriptionFile =
              fileSystem.file('change_description.txt');
          changeDescriptionFile.writeAsStringSync(
              _generateFakeDependabotPRDescription('robolectric'));

          final List<String> output =
              await _runWithMissingChangeDetection(<String>[
            '--change-description-file=${changeDescriptionFile.path}'
          ]);

          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Ignoring lack of version change for Dependabot '
                  'change to a known internal dependency.'),
              contains('Ignoring lack of CHANGELOG update for Dependabot '
                  'change to a known internal dependency.'),
            ]),
          );
        });

        test('allows missing version and CHANGELOG change for junit', () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          final File changeDescriptionFile =
              fileSystem.file('change_description.txt');
          changeDescriptionFile
              .writeAsStringSync(_generateFakeDependabotPRDescription('junit'));

          final List<String> output =
              await _runWithMissingChangeDetection(<String>[
            '--change-description-file=${changeDescriptionFile.path}'
          ]);

          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Ignoring lack of version change for Dependabot '
                  'change to a known internal dependency.'),
              contains('Ignoring lack of CHANGELOG update for Dependabot '
                  'change to a known internal dependency.'),
            ]),
          );
        });

        test('fails for dependencies that are not explicitly allowed',
            () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          final File changeDescriptionFile =
              fileSystem.file('change_description.txt');
          changeDescriptionFile.writeAsStringSync(
              _generateFakeDependabotPRDescription('somethingelse'));

          Error? commandError;
          final List<String> output =
              await _runWithMissingChangeDetection(<String>[
            '--change-description-file=${changeDescriptionFile.path}'
          ], errorHandler: (Error e) {
            commandError = e;
          });

          expect(commandError, isA<ToolExit>());
          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('No version change found'),
              contains('plugin:\n'
                  '    Missing version change'),
            ]),
          );
        });

        test('allow list works for commit messages', () async {
          final RepositoryPackage plugin =
              createFakePlugin('plugin', packagesDir, version: '1.0.0');

          const String changelog = '''
## 1.0.0
* Some changes.
''';
          plugin.changelogFile.writeAsStringSync(changelog);
          processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
            MockProcess(stdout: 'version: 1.0.0'),
          ];
          processRunner.mockProcessesForExecutable['git-diff'] = <io.Process>[
            MockProcess(stdout: '''
packages/plugin/android/build.gradle
'''),
          ];

          final File changeDescriptionFile =
              fileSystem.file('change_description.txt');
          changeDescriptionFile.writeAsStringSync(
              _generateFakeDependabotCommitMessage('mockito-core'));

          final List<String> output =
              await _runWithMissingChangeDetection(<String>[
            '--change-description-file=${changeDescriptionFile.path}'
          ]);

          expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Ignoring lack of version change for Dependabot '
                  'change to a known internal dependency.'),
              contains('Ignoring lack of CHANGELOG update for Dependabot '
                  'change to a known internal dependency.'),
            ]),
          );
        });
      });
    });

    test('allows valid against pub', () async {
      mockHttpResponse = <String, dynamic>{
        'name': 'some_package',
        'versions': <String>[
          '0.0.1',
          '0.0.2',
          '1.0.0',
        ],
      };

      createFakePlugin('plugin', packagesDir, version: '2.0.0');
      final List<String> output = await runCapturingPrint(runner,
          <String>['version-check', '--base-sha=main', '--against-pub']);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('plugin: Current largest version on pub: 1.0.0'),
        ]),
      );
    });

    test('denies invalid against pub', () async {
      mockHttpResponse = <String, dynamic>{
        'name': 'some_package',
        'versions': <String>[
          '0.0.1',
          '0.0.2',
        ],
      };

      createFakePlugin('plugin', packagesDir, version: '2.0.0');

      bool hasError = false;
      final List<String> result = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        result,
        containsAllInOrder(<Matcher>[
          contains('''
${indentation}Incorrectly updated version.
${indentation}HEAD: 2.0.0, pub: 0.0.2.
${indentation}Allowed versions: {1.0.0: NextVersionType.BREAKING_MAJOR, 0.1.0: NextVersionType.MINOR, 0.0.3: NextVersionType.PATCH}''')
        ]),
      );
    });

    test(
        'throw and print error message if http request failed when checking against pub',
        () async {
      mockHttpStatus = 400;

      createFakePlugin('plugin', packagesDir, version: '2.0.0');
      bool hasError = false;
      final List<String> result = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=main', '--against-pub'],
          errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        result,
        containsAllInOrder(<Matcher>[
          contains('''
${indentation}Error fetching version on pub for plugin.
${indentation}HTTP Status 400
${indentation}HTTP response: null
''')
        ]),
      );
    });

    test('when checking against pub, allow any version if http status is 404.',
        () async {
      mockHttpStatus = 404;

      createFakePlugin('plugin', packagesDir, version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final List<String> result = await runCapturingPrint(runner,
          <String>['version-check', '--base-sha=main', '--against-pub']);

      expect(
        result,
        containsAllInOrder(<Matcher>[
          contains('Unable to find previous version on pub server.'),
        ]),
      );
    });

    group('prelease versions', () {
      test(
          'allow an otherwise-valid transition that also adds a pre-release component',
          () async {
        createFakePlugin('plugin', packagesDir, version: '2.0.0-dev');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.0.0'),
        ];
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
            contains('1.0.0 -> 2.0.0-dev'),
          ]),
        );
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      test('allow releasing a pre-release', () async {
        createFakePlugin('plugin', packagesDir, version: '1.2.0');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.2.0-dev'),
        ];
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
            contains('1.2.0-dev -> 1.2.0'),
          ]),
        );
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      // Allow abandoning a pre-release version in favor of a different version
      // change type.
      test(
          'allow an otherwise-valid transition that also removes a pre-release component',
          () async {
        createFakePlugin('plugin', packagesDir, version: '2.0.0');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.2.0-dev'),
        ];
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
            contains('1.2.0-dev -> 2.0.0'),
          ]),
        );
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      test('allow changing only the pre-release version', () async {
        createFakePlugin('plugin', packagesDir, version: '1.2.0-dev.2');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 1.2.0-dev.1'),
        ];
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main']);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Running for plugin'),
            contains('1.2.0-dev.1 -> 1.2.0-dev.2'),
          ]),
        );
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      test('denies invalid version change that also adds a pre-release',
          () async {
        createFakePlugin('plugin', packagesDir, version: '0.2.0-dev');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 0.0.1'),
        ];
        Error? commandError;
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main'],
            errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Incorrectly updated version.'),
            ]));
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      test('denies invalid version change that also removes a pre-release',
          () async {
        createFakePlugin('plugin', packagesDir, version: '0.2.0');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 0.0.1-dev'),
        ];
        Error? commandError;
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main'],
            errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Incorrectly updated version.'),
            ]));
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });

      test('denies invalid version change between pre-releases', () async {
        createFakePlugin('plugin', packagesDir, version: '0.2.0-dev');
        processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
          MockProcess(stdout: 'version: 0.0.1-dev'),
        ];
        Error? commandError;
        final List<String> output = await runCapturingPrint(
            runner, <String>['version-check', '--base-sha=main'],
            errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
            output,
            containsAllInOrder(<Matcher>[
              contains('Incorrectly updated version.'),
            ]));
        expect(
            processRunner.recordedCalls,
            containsAllInOrder(const <ProcessCall>[
              ProcessCall('git-show',
                  <String>['main:packages/plugin/pubspec.yaml'], null)
            ]));
      });
    });
  });

  group('Pre 1.0', () {
    test('nextVersion allows patch version', () {
      testAllowedVersion('0.12.0', '0.12.0+1',
          nextVersionType: NextVersionType.PATCH);
      testAllowedVersion('0.12.0+4', '0.12.0+5',
          nextVersionType: NextVersionType.PATCH);
    });

    test('nextVersion does not allow jumping patch', () {
      testAllowedVersion('0.12.0', '0.12.0+2', allowed: false);
      testAllowedVersion('0.12.0+2', '0.12.0+4', allowed: false);
    });

    test('nextVersion does not allow going back', () {
      testAllowedVersion('0.12.0', '0.11.0', allowed: false);
      testAllowedVersion('0.12.0+2', '0.12.0+1', allowed: false);
      testAllowedVersion('0.12.0+1', '0.12.0', allowed: false);
    });

    test('nextVersion allows minor version', () {
      testAllowedVersion('0.12.0', '0.12.1',
          nextVersionType: NextVersionType.MINOR);
      testAllowedVersion('0.12.0+4', '0.12.1',
          nextVersionType: NextVersionType.MINOR);
    });

    test('nextVersion does not allow jumping minor', () {
      testAllowedVersion('0.12.0', '0.12.2', allowed: false);
      testAllowedVersion('0.12.0+2', '0.12.3', allowed: false);
    });
  });

  group('Releasing 1.0', () {
    test('nextVersion allows releasing 1.0', () {
      testAllowedVersion('0.12.0', '1.0.0',
          nextVersionType: NextVersionType.BREAKING_MAJOR);
      testAllowedVersion('0.12.0+4', '1.0.0',
          nextVersionType: NextVersionType.BREAKING_MAJOR);
    });

    test('nextVersion does not allow jumping major', () {
      testAllowedVersion('0.12.0', '2.0.0', allowed: false);
      testAllowedVersion('0.12.0+4', '2.0.0', allowed: false);
    });

    test('nextVersion does not allow un-releasing', () {
      testAllowedVersion('1.0.0', '0.12.0+4', allowed: false);
      testAllowedVersion('1.0.0', '0.12.0', allowed: false);
    });
  });

  group('Post 1.0', () {
    test('nextVersion allows patch jumps', () {
      testAllowedVersion('1.0.1', '1.0.2',
          nextVersionType: NextVersionType.PATCH);
      testAllowedVersion('1.0.0', '1.0.1',
          nextVersionType: NextVersionType.PATCH);
    });

    test('nextVersion does not allow build jumps', () {
      testAllowedVersion('1.0.1', '1.0.1+1', allowed: false);
      testAllowedVersion('1.0.0+5', '1.0.0+6', allowed: false);
    });

    test('nextVersion does not allow skipping patches', () {
      testAllowedVersion('1.0.1', '1.0.3', allowed: false);
      testAllowedVersion('1.0.0', '1.0.6', allowed: false);
    });

    test('nextVersion allows minor version jumps', () {
      testAllowedVersion('1.0.1', '1.1.0',
          nextVersionType: NextVersionType.MINOR);
      testAllowedVersion('1.0.0', '1.1.0',
          nextVersionType: NextVersionType.MINOR);
    });

    test('nextVersion does not allow skipping minor versions', () {
      testAllowedVersion('1.0.1', '1.2.0', allowed: false);
      testAllowedVersion('1.1.0', '1.3.0', allowed: false);
    });

    test('nextVersion allows breaking changes', () {
      testAllowedVersion('1.0.1', '2.0.0',
          nextVersionType: NextVersionType.BREAKING_MAJOR);
      testAllowedVersion('1.0.0', '2.0.0',
          nextVersionType: NextVersionType.BREAKING_MAJOR);
    });

    test('nextVersion does not allow skipping major versions', () {
      testAllowedVersion('1.0.1', '3.0.0', allowed: false);
      testAllowedVersion('1.1.0', '2.3.0', allowed: false);
    });
  });
}
