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

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/common.dart';
import 'package:flutter_plugin_tools/src/version_check_command.dart';
import 'package:git/git.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 'util.dart';

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

class MockGitDir extends Mock implements GitDir {}

class MockProcessResult extends Mock implements io.ProcessResult {}

const String _redColorMessagePrefix = '\x1B[31m';
const String _redColorMessagePostfix = '\x1B[0m';

// Some error message was printed in a "Colorized" red message. So `\x1B[31m` and `\x1B[0m` needs to be included.
String _redColorString(String string) {
  return '$_redColorMessagePrefix$string$_redColorMessagePostfix';
}

void main() {
  const String indentation = '  ';
  group('$VersionCheckCommand', () {
    CommandRunner<void> runner;
    RecordingProcessRunner processRunner;
    List<List<String>> gitDirCommands;
    String gitDiffResponse;
    Map<String, String> gitShowResponses;
    MockGitDir gitDir;

    setUp(() {
      gitDirCommands = <List<String>>[];
      gitDiffResponse = '';
      gitShowResponses = <String, String>{};
      gitDir = MockGitDir();
      when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) {
        gitDirCommands.add(invocation.positionalArguments[0] as List<String>);
        final MockProcessResult mockProcessResult = MockProcessResult();
        if (invocation.positionalArguments[0][0] == 'diff') {
          when<String>(mockProcessResult.stdout as String)
              .thenReturn(gitDiffResponse);
        } else if (invocation.positionalArguments[0][0] == 'show') {
          final String response =
              gitShowResponses[invocation.positionalArguments[0][1]];
          if (response == null) {
            throw const io.ProcessException('git', <String>['show']);
          }
          when<String>(mockProcessResult.stdout as String).thenReturn(response);
        } else if (invocation.positionalArguments[0][0] == 'merge-base') {
          when<String>(mockProcessResult.stdout as String).thenReturn('abc123');
        }
        return Future<io.ProcessResult>.value(mockProcessResult);
      });
      initializeFakePackages();
      processRunner = RecordingProcessRunner();
      final VersionCheckCommand command = VersionCheckCommand(
          mockPackagesDir, mockFileSystem,
          processRunner: processRunner, gitDir: gitDir);

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

    tearDown(() {
      cleanupPackages();
    });

    test('allows valid version', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);

      expect(
        output,
        containsAllInOrder(<String>[
          'No version check errors found!',
        ]),
      );
      expect(gitDirCommands.length, equals(3));
      expect(
          gitDirCommands,
          containsAll(<Matcher>[
            equals(<String>['diff', '--name-only', 'master', 'HEAD']),
            equals(<String>['show', 'master:packages/plugin/pubspec.yaml']),
            equals(<String>['show', 'HEAD:packages/plugin/pubspec.yaml']),
          ]));
    });

    test('denies invalid version', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 0.0.1',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 0.2.0',
      };
      final Future<List<String>> result = runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);

      await expectLater(
        result,
        throwsA(const TypeMatcher<ToolExit>()),
      );
      expect(gitDirCommands.length, equals(3));
      expect(
          gitDirCommands,
          containsAll(<Matcher>[
            equals(<String>['diff', '--name-only', 'master', 'HEAD']),
            equals(<String>['show', 'master:packages/plugin/pubspec.yaml']),
            equals(<String>['show', 'HEAD:packages/plugin/pubspec.yaml']),
          ]));
    });

    test('allows valid version without explicit base-sha', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'abc123:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };
      final List<String> output =
          await runCapturingPrint(runner, <String>['version-check']);

      expect(
        output,
        containsAllInOrder(<String>[
          'No version check errors found!',
        ]),
      );
    });

    test('allows valid version for new package.', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'HEAD:packages/plugin/pubspec.yaml': 'version: 1.0.0',
      };
      final List<String> output =
          await runCapturingPrint(runner, <String>['version-check']);

      expect(
        output,
        containsAllInOrder(<String>[
          '${indentation}Unable to find pubspec in master. Safe to ignore if the project is new.',
          'No version check errors found!',
        ]),
      );
    });

    test('denies invalid version without explicit base-sha', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'abc123:packages/plugin/pubspec.yaml': 'version: 0.0.1',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 0.2.0',
      };
      final Future<List<String>> result =
          runCapturingPrint(runner, <String>['version-check']);

      await expectLater(
        result,
        throwsA(const TypeMatcher<ToolExit>()),
      );
    });

    test('gracefully handles missing pubspec.yaml', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      mockFileSystem.currentDirectory
          .childDirectory('packages')
          .childDirectory('plugin')
          .childFile('pubspec.yaml')
          .deleteSync();
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);

      expect(
        output,
        orderedEquals(<String>[
          'Determine diff with base sha: master',
          'Checking versions for packages/plugin/pubspec.yaml...',
          '  Deleted; skipping.',
          'No version check errors found!',
        ]),
      );
      expect(gitDirCommands.length, equals(1));
      expect(gitDirCommands.first.join(' '),
          equals('diff --name-only master HEAD'));
    });

    test('allows minor changes to platform interfaces', () async {
      createFakePlugin('plugin_platform_interface',
          includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin_platform_interface/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin_platform_interface/pubspec.yaml':
            'version: 1.0.0',
        'HEAD:packages/plugin_platform_interface/pubspec.yaml':
            'version: 1.1.0',
      };
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);
      expect(
        output,
        containsAllInOrder(<String>[
          'No version check errors found!',
        ]),
      );
      expect(gitDirCommands.length, equals(3));
      expect(
          gitDirCommands,
          containsAll(<Matcher>[
            equals(<String>['diff', '--name-only', 'master', 'HEAD']),
            equals(<String>[
              'show',
              'master:packages/plugin_platform_interface/pubspec.yaml'
            ]),
            equals(<String>[
              'show',
              'HEAD:packages/plugin_platform_interface/pubspec.yaml'
            ]),
          ]));
    });

    test('disallows breaking changes to platform interfaces', () async {
      createFakePlugin('plugin_platform_interface',
          includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin_platform_interface/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin_platform_interface/pubspec.yaml':
            'version: 1.0.0',
        'HEAD:packages/plugin_platform_interface/pubspec.yaml':
            'version: 2.0.0',
      };
      final Future<List<String>> output = runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);
      await expectLater(
        output,
        throwsA(const TypeMatcher<ToolExit>()),
      );
      expect(gitDirCommands.length, equals(3));
      expect(
          gitDirCommands,
          containsAll(<Matcher>[
            equals(<String>['diff', '--name-only', 'master', 'HEAD']),
            equals(<String>[
              'show',
              'master:packages/plugin_platform_interface/pubspec.yaml'
            ]),
            equals(<String>[
              'show',
              'HEAD:packages/plugin_platform_interface/pubspec.yaml'
            ]),
          ]));
    });

    test('Allow empty lines in front of the first version in CHANGELOG',
        () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.1');
      const String changelog = '''



## 1.0.1

* Some changes.
''';
      createFakeCHANGELOG(pluginDirectory, changelog);
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);
      expect(
        output,
        containsAllInOrder(<String>[
          'Checking the first version listed in CHANGELOG.md matches the version in pubspec.yaml for plugin.',
          'plugin passed version check',
          'No version check errors found!'
        ]),
      );
    });

    test('Throws if versions in changelog and pubspec do not match', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.1');
      const String changelog = '''
## 1.0.2

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

      expect(
        output,
        containsAllInOrder(<String>[
          _redColorString('''
versions for plugin in CHANGELOG.md and pubspec.yaml do not match.
The version in pubspec.yaml is 1.0.1.
The first version listed in CHANGELOG.md is 1.0.2.
'''),
        ]),
      );
    });

    test('Success if CHANGELOG and pubspec versions match', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.1');
      const String changelog = '''
## 1.0.1

* Some changes.
''';
      createFakeCHANGELOG(pluginDirectory, changelog);
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);
      expect(
        output,
        containsAllInOrder(<String>[
          'Checking the first version listed in CHANGELOG.md matches the version in pubspec.yaml for plugin.',
          'plugin passed version check',
          'No version check errors found!'
        ]),
      );
    });

    test(
        'Fail if pubspec version only matches an older version listed in CHANGELOG',
        () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.0');
      const String changelog = '''
## 1.0.1

* Some changes.

## 1.0.0

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

      expect(
        output,
        containsAllInOrder(<String>[
          _redColorString(
            '''
versions for plugin in CHANGELOG.md and pubspec.yaml do not match.
The version in pubspec.yaml is 1.0.0.
The first version listed in CHANGELOG.md is 1.0.1.
''',
          )
        ]),
      );
    });

    test('Allow NEXT as a placeholder for gathering CHANGELOG entries',
        () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.0');
      const String changelog = '''
## NEXT

* Some changes that won't be published until the next time there's a release.

## 1.0.0

* Some other changes.
''';
      createFakeCHANGELOG(pluginDirectory, changelog);
      final List<String> output = await runCapturingPrint(
          runner, <String>['version-check', '--base-sha=master']);
      await expectLater(
        output,
        containsAllInOrder(<String>[
          'Found NEXT; validating next version in the CHANGELOG.',
          'plugin passed version check',
          'No version check errors found!',
        ]),
      );
    });

    test('Fail if NEXT is left in the CHANGELOG when adding a version bump',
        () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, version: '1.0.1');
      const String changelog = '''
## 1.0.1

* Some changes.

## NEXT

* Some changes that should have been folded in 1.0.1.

## 1.0.0

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

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

    test('Fail if the version changes without replacing NEXT', () async {
      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);

      final Directory pluginDirectory =
          mockPackagesDir.childDirectory('plugin');

      createFakePubspec(pluginDirectory,
          isFlutter: true, includeVersion: true, 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.
''';
      createFakeCHANGELOG(pluginDirectory, changelog);
      bool hasError = false;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'version-check',
        '--base-sha=master',
        '--against-pub'
      ], errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

      expect(
        output,
        containsAllInOrder(<String>[
          'Found NEXT; validating next version in the CHANGELOG.',
          _redColorString(
            '''
versions for plugin in CHANGELOG.md and pubspec.yaml do not match.
The version in pubspec.yaml is 1.0.1.
The first version listed in CHANGELOG.md is 1.0.0.
''',
          )
        ]),
      );
    });

    test('allows valid against pub', () async {
      const Map<String, dynamic> httpResponse = <String, dynamic>{
        'name': 'some_package',
        'versions': <String>[
          '0.0.1',
          '0.0.2',
          '1.0.0',
        ],
      };
      final MockClient mockClient = MockClient((http.Request request) async {
        return http.Response(json.encode(httpResponse), 200);
      });
      final VersionCheckCommand command = VersionCheckCommand(
          mockPackagesDir, mockFileSystem,
          processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);

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

      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };
      final List<String> output = await runCapturingPrint(runner,
          <String>['version-check', '--base-sha=master', '--against-pub']);

      expect(
        output,
        containsAllInOrder(<String>[
          '${indentation}plugin: Current largest version on pub: 1.0.0',
          'No version check errors found!',
        ]),
      );
    });

    test('denies invalid against pub', () async {
      const Map<String, dynamic> httpResponse = <String, dynamic>{
        'name': 'some_package',
        'versions': <String>[
          '0.0.1',
          '0.0.2',
        ],
      };
      final MockClient mockClient = MockClient((http.Request request) async {
        return http.Response(json.encode(httpResponse), 200);
      });
      final VersionCheckCommand command = VersionCheckCommand(
          mockPackagesDir, mockFileSystem,
          processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);

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

      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };

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

      expect(
        result,
        containsAllInOrder(<String>[
          _redColorString(
            '''
${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 {
      final MockClient mockClient = MockClient((http.Request request) async {
        return http.Response('xx', 400);
      });
      final VersionCheckCommand command = VersionCheckCommand(
          mockPackagesDir, mockFileSystem,
          processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);

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

      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };
      bool hasError = false;
      final List<String> result = await runCapturingPrint(runner, <String>[
        'version-check',
        '--base-sha=master',
        '--against-pub'
      ], errorHandler: (Error e) {
        expect(e, isA<ToolExit>());
        hasError = true;
      });
      expect(hasError, isTrue);

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

    test('when checking against pub, allow any version if http status is 404.',
        () async {
      final MockClient mockClient = MockClient((http.Request request) async {
        return http.Response('xx', 404);
      });
      final VersionCheckCommand command = VersionCheckCommand(
          mockPackagesDir, mockFileSystem,
          processRunner: processRunner, gitDir: gitDir, httpClient: mockClient);

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

      createFakePlugin('plugin', includeChangeLog: true, includeVersion: true);
      gitDiffResponse = 'packages/plugin/pubspec.yaml';
      gitShowResponses = <String, String>{
        'master:packages/plugin/pubspec.yaml': 'version: 1.0.0',
        'HEAD:packages/plugin/pubspec.yaml': 'version: 2.0.0',
      };
      final List<String> result = await runCapturingPrint(runner,
          <String>['version-check', '--base-sha=master', '--against-pub']);

      expect(
        result,
        containsAllInOrder(<String>[
          '${indentation}Unable to find package on pub server. Safe to ignore if the project is new.',
          'No version check errors found!',
        ]),
      );
    });
  });

  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);
    });
  });
}
