Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/src/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class VeryGoodCommandRunner extends CommandRunner<int> {
final Analytics _analytics;
final PubUpdater _pubUpdater;

@override
void printUsage() => _logger.info(usage);

@override
Future<int> run(Iterable<String> args) async {
try {
Expand Down Expand Up @@ -140,7 +143,9 @@ class VeryGoodCommandRunner extends CommandRunner<int> {
} else {
exitCode = await super.runCommand(topLevelResults);
}
await _checkForUpdates();
if (topLevelResults.command?.name != UpdateCommand.commandName) {
await _checkForUpdates();
}
return exitCode;
}

Expand Down
5 changes: 4 additions & 1 deletion lib/src/commands/update.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ class UpdateCommand extends Command<int> {
@override
String get description => 'Update Very Good CLI.';

/// The [name] of the command. But static.
static const String commandName = 'update';

@override
String get name => 'update';
String get name => commandName;

@override
Future<int> run() async {
Expand Down
85 changes: 49 additions & 36 deletions test/src/command_runner_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// ignore_for_file: no_adjacent_strings_in_list
import 'dart:async';
import 'dart:io';

import 'package:args/command_runner.dart';
import 'package:mason/mason.dart' hide packageVersion;
Expand All @@ -16,6 +17,10 @@ class MockLogger extends Mock implements Logger {}

class MockPubUpdater extends Mock implements PubUpdater {}

class MockProgress extends Mock implements Progress {}

class FakeProcessResult extends Fake implements ProcessResult {}

const expectedUsage = [
'🦄 A Very Good Command-Line Interface\n'
'\n'
Expand Down Expand Up @@ -53,26 +58,12 @@ Run ${lightCyan.wrap('very_good update')} to update''';

void main() {
group('VeryGoodCommandRunner', () {
late List<String> printLogs;
late Analytics analytics;
late PubUpdater pubUpdater;
late Logger logger;
late VeryGoodCommandRunner commandRunner;

void Function() overridePrint(void Function() fn) {
return () {
final spec = ZoneSpecification(
print: (_, __, ___, String msg) {
printLogs.add(msg);
},
);
return Zone.current.fork(specification: spec).run<void>(fn);
};
}

setUp(() {
printLogs = [];

analytics = MockAnalytics();
pubUpdater = MockPubUpdater();

Expand Down Expand Up @@ -108,6 +99,36 @@ void main() {
verify(() => logger.info(updatePrompt)).called(1);
});

test(
'doesnt show update message when using the update command',
() async {
when(
() => pubUpdater.getLatestVersion(any()),
).thenAnswer((_) async => latestVersion);
when(
() => pubUpdater.update(packageName: packageName),
).thenAnswer((_) => Future.value(FakeProcessResult()));
when(
() => pubUpdater.isUpToDate(
packageName: any(named: 'packageName'),
currentVersion: any(named: 'currentVersion'),
),
).thenAnswer((_) => Future.value(true));

final progress = MockProgress();
final progressLogs = <String>[];
when(() => progress.complete(any())).thenAnswer((_) {
final message = _.positionalArguments.elementAt(0) as String?;
if (message != null) progressLogs.add(message);
});
when(() => logger.progress(any())).thenReturn(progress);

final result = await commandRunner.run(['update']);
expect(result, equals(ExitCode.success.code));
verifyNever(() => logger.info(updatePrompt));
},
);

test('handles pub update errors gracefully', () async {
when(
() => pubUpdater.getLatestVersion(any()),
Expand Down Expand Up @@ -164,30 +185,22 @@ void main() {
verify(() => logger.info('exception usage')).called(1);
});

test(
'handles no command',
overridePrint(() async {
final result = await commandRunner.run([]);
expect(printLogs, equals(expectedUsage));
expect(result, equals(ExitCode.success.code));
}),
);
test('handles no command', () async {
final result = await commandRunner.run([]);
verify(() => logger.info(expectedUsage.join())).called(1);
expect(result, equals(ExitCode.success.code));
});

group('--help', () {
test(
'outputs usage',
overridePrint(() async {
final result = await commandRunner.run(['--help']);
expect(printLogs, equals(expectedUsage));
expect(result, equals(ExitCode.success.code));

printLogs.clear();

final resultAbbr = await commandRunner.run(['-h']);
expect(printLogs, equals(expectedUsage));
expect(resultAbbr, equals(ExitCode.success.code));
}),
);
test('outputs usage', () async {
final result = await commandRunner.run(['--help']);
verify(() => logger.info(expectedUsage.join())).called(1);
expect(result, equals(ExitCode.success.code));

final resultAbbr = await commandRunner.run(['-h']);
verify(() => logger.info(expectedUsage.join())).called(1);
expect(resultAbbr, equals(ExitCode.success.code));
});
});

group('--analytics', () {
Expand Down