// 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 explanation',
        () async {
      createFakePlugin('plugin_platform_interface', packagesDir,
          version: '2.0.0');
      processRunner.mockProcessesForExecutable['git-show'] = <io.Process>[
        MockProcess(stdout: 'version: 1.0.0'),
      ];
      final File changeDescriptionFile =
          fileSystem.file('change_description.txt');
      changeDescriptionFile.writeAsStringSync('''
Some general PR description

## Breaking change justification

This is necessary because of X, Y, and Z

## Another section''');
      final List<String> output = await runCapturingPrint(runner, <String>[
        'version-check',
        '--base-sha=main',
        '--change-description-file=${changeDescriptionFile.path}'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Allowing breaking change to plugin_platform_interface '
              'due to "## Breaking change justification" in the change '
              'description.'),
          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('throws if a nonexistent change description file is specified',
        () 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',
        '--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'),
        ]),
      );
      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 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/lib/plugin.dart
packages/plugin/CHANGELOG.md
packages/plugin/pubspec.yaml
'''),
        ];

        final File changeDescriptionFile =
            fileSystem.file('change_description.txt');
        changeDescriptionFile.writeAsStringSync('''
Some general PR description

No version change: Code change is only to implementation comments.
''');
        final List<String> output =
            await _runWithMissingChangeDetection(<String>[
          '--change-description-file=${changeDescriptionFile.path}'
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Ignoring lack of version change due to '
                '"No version change:" in the change description.'),
          ]),
        );
      });

      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 File changeDescriptionFile =
            fileSystem.file('change_description.txt');
        changeDescriptionFile.writeAsStringSync('''
Some general PR description

No CHANGELOG change: Code change is only to implementation comments.
''');
        final List<String> output =
            await _runWithMissingChangeDetection(<String>[
          '--change-description-file=${changeDescriptionFile.path}'
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('Ignoring lack of CHANGELOG update due to '
                '"No CHANGELOG change:" in the change description.'),
          ]),
        );
      });

      group('dependabot', () {
        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'),
            ]),
          );
        });

        // Tests workaround for
        // https://github.com/cirruslabs/cirrus-ci-docs/issues/1029.
        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);
    });
  });
}
