mirror of
https://github.com/flutter/packages.git
synced 2025-05-25 16:58:01 +08:00

- Updates dependencies to null-safe versions - Migrates common.dart (which doesn't depend on anything) - Migrates common_tests.dart and its one dependency, utils.dart - Adds build_runner for Mockito mock generation - Adds a new utility methods for getting arguments that handle both the casting and the removal of nullability to address a common problematic pattern while migrating code. - Converts all files, not just the migrated ones, to those new helpers. Migrating common.dart and utils.dart should unblock a command-by-command migration to null safety. Reverts the separate of podspect lints into a step that doesn't do a Flutter upgrade (https://github.com/flutter/plugins/pull/3700) because without that step we had a version of Dart too old to run null-safe tooling. First step of https://github.com/flutter/flutter/issues/81912
816 lines
27 KiB
Dart
816 lines
27 KiB
Dart
// 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.
|
|
|
|
// @dart=2.9
|
|
|
|
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, throwOnError: anyNamed('throwOnError')))
|
|
.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);
|
|
});
|
|
});
|
|
}
|