| // Copyright 2013 The Flutter Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import 'dart:io'; | |
| import 'package:githooks/src/pre_commit_command.dart'; | |
| import 'package:test/test.dart'; | |
| void main() { | |
| const repoRoot = '/mock/repo/root'; | |
| const toolScript = '$repoRoot/script/tool/bin/flutter_plugin_tools.dart'; | |
| group('pre-commit hook', () { | |
| test('passes when both format and analyze succeed', () async { | |
| final List<List<String>> executedArguments = []; | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| executedArguments.add(arguments); | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult(0, 0, 'packages/a_plugin/lib/a.dart\u0000', ''); | |
| } | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isTrue); | |
| // Verify the exact arguments passed to format and analyze | |
| expect( | |
| executedArguments, | |
| anyElement( | |
| equals(['run', toolScript, 'format', '--run-on-staged-packages', '--fail-on-change']), | |
| ), | |
| ); | |
| expect( | |
| executedArguments, | |
| anyElement(equals(['run', toolScript, 'analyze', '--run-on-staged-packages', '--dart'])), | |
| ); | |
| }); | |
| test('fails when formatting fails', () async { | |
| final List<List<String>> executedArguments = []; | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| executedArguments.add(arguments); | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult(0, 0, 'packages/a_plugin/lib/a.dart\u0000', ''); | |
| } | |
| } | |
| if (arguments.contains('format')) { | |
| return ProcessResult(0, 1, 'bad_file.dart', ''); | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isFalse); | |
| expect( | |
| executedArguments, | |
| anyElement( | |
| equals(['run', toolScript, 'format', '--run-on-staged-packages', '--fail-on-change']), | |
| ), | |
| ); | |
| // Verify that static analysis was skipped because formatting failed | |
| expect(executedArguments.any((args) => args.contains('analyze')), isFalse); | |
| }); | |
| test('fails when analysis fails', () async { | |
| final List<List<String>> executedArguments = []; | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| executedArguments.add(arguments); | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult(0, 0, 'packages/a_plugin/lib/a.dart\u0000', ''); | |
| } | |
| } | |
| if (arguments.contains('analyze')) { | |
| return ProcessResult(0, 1, 'error in file.dart', ''); | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isFalse); | |
| expect( | |
| executedArguments, | |
| anyElement(equals(['run', toolScript, 'analyze', '--run-on-staged-packages', '--dart'])), | |
| ); | |
| }); | |
| test('exits early with success if there are no staged packages', () async { | |
| final List<List<String>> executedArguments = []; | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| executedArguments.add(arguments); | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult( | |
| 0, | |
| 0, | |
| 'script/githooks/test/pre_commit_command_test.dart\u0000', | |
| '', | |
| ); | |
| } | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isTrue); | |
| // Verify that no format or analyze commands were run | |
| expect( | |
| executedArguments.any((args) => args.contains('format') || args.contains('analyze')), | |
| isFalse, | |
| ); | |
| }); | |
| test('exits early with success if there are no staged changes at all', () async { | |
| final List<List<String>> executedArguments = []; | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| executedArguments.add(arguments); | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult(0, 0, '', ''); | |
| } | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isTrue); | |
| // Verify that no format or analyze commands were run | |
| expect( | |
| executedArguments.any((args) => args.contains('format') || args.contains('analyze')), | |
| isFalse, | |
| ); | |
| }); | |
| test('fails when checking staged packages fails', () async { | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| if (executable == 'git') { | |
| if (arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 0, '$repoRoot\n', ''); | |
| } | |
| if (arguments.contains('diff')) { | |
| return ProcessResult(0, 1, '', 'Git diff failed'); | |
| } | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isFalse); | |
| }); | |
| test('fails when git root cannot be found', () async { | |
| final command = PreCommitCommand( | |
| processRunner: | |
| (String executable, List<String> arguments, {String? workingDirectory}) async { | |
| if (executable == 'git' && arguments.contains('rev-parse')) { | |
| return ProcessResult(0, 1, '', 'Not a git repository'); | |
| } | |
| return ProcessResult(0, 0, 'Success', ''); | |
| }, | |
| ); | |
| final bool result = await command.run(); | |
| expect(result, isFalse); | |
| }); | |
| }); | |
| } |