// 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 '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/custom_test_command.dart'; import 'package:test/test.dart'; import 'mocks.dart'; import 'util.dart'; void main() { late FileSystem fileSystem; late MockPlatform mockPlatform; late Directory packagesDir; late RecordingProcessRunner processRunner; late CommandRunner runner; group('posix', () { setUp(() { fileSystem = MemoryFileSystem(); mockPlatform = MockPlatform(); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); final CustomTestCommand analyzeCommand = CustomTestCommand( packagesDir, processRunner: processRunner, platform: mockPlatform, ); runner = CommandRunner( 'custom_test_command', 'Test for custom_test_command'); runner.addCommand(analyzeCommand); }); test('runs both new and legacy when both are present', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); final List output = await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall(package.directory.childFile('run_tests.sh').path, const [], package.path), ProcessCall('dart', const ['run', 'tool/run_tests.dart'], package.path), ])); expect( output, containsAllInOrder([ contains('Ran for 1 package(s)'), ])); }); test('runs when only new is present', () async { final RepositoryPackage package = createFakePackage( 'a_package', packagesDir, extraFiles: ['tool/run_tests.dart']); final List output = await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall('dart', const ['run', 'tool/run_tests.dart'], package.path), ])); expect( output, containsAllInOrder([ contains('Ran for 1 package(s)'), ])); }); test('runs pub get before running Dart test script', () async { final RepositoryPackage package = createFakePackage( 'a_package', packagesDir, extraFiles: ['tool/run_tests.dart']); await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall('dart', const ['pub', 'get'], package.path), ProcessCall('dart', const ['run', 'tool/run_tests.dart'], package.path), ])); }); test('runs when only legacy is present', () async { final RepositoryPackage package = createFakePackage( 'a_package', packagesDir, extraFiles: ['run_tests.sh']); final List output = await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall(package.directory.childFile('run_tests.sh').path, const [], package.path), ])); expect( output, containsAllInOrder([ contains('Ran for 1 package(s)'), ])); }); test('skips when neither is present', () async { createFakePackage('a_package', packagesDir); final List output = await runCapturingPrint(runner, ['custom-test']); expect(processRunner.recordedCalls, isEmpty); expect( output, containsAllInOrder([ contains('Skipped 1 package(s)'), ])); }); test('fails if new fails', () async { createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); processRunner.mockProcessesForExecutable['dart'] = [ FakeProcessInfo(MockProcess(), ['pub', 'get']), FakeProcessInfo(MockProcess(exitCode: 1), ['test']), ]; Error? commandError; final List output = await runCapturingPrint( runner, ['custom-test'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output, containsAllInOrder([ contains('The following packages had errors:'), contains('a_package') ])); }); test('fails if pub get fails', () async { createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); processRunner.mockProcessesForExecutable['dart'] = [ FakeProcessInfo(MockProcess(exitCode: 1), ['pub', 'get']), ]; Error? commandError; final List output = await runCapturingPrint( runner, ['custom-test'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output, containsAllInOrder([ contains('The following packages had errors:'), contains('a_package:\n' ' Unable to get script dependencies') ])); }); test('fails if legacy fails', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); processRunner.mockProcessesForExecutable[ package.directory.childFile('run_tests.sh').path] = [ FakeProcessInfo(MockProcess(exitCode: 1)), ]; Error? commandError; final List output = await runCapturingPrint( runner, ['custom-test'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output, containsAllInOrder([ contains('The following packages had errors:'), contains('a_package') ])); }); }); group('Windows', () { setUp(() { fileSystem = MemoryFileSystem(style: FileSystemStyle.windows); mockPlatform = MockPlatform(isWindows: true); packagesDir = createPackagesDirectory(fileSystem: fileSystem); processRunner = RecordingProcessRunner(); final CustomTestCommand analyzeCommand = CustomTestCommand( packagesDir, processRunner: processRunner, platform: mockPlatform, ); runner = CommandRunner( 'custom_test_command', 'Test for custom_test_command'); runner.addCommand(analyzeCommand); }); test('runs new and skips old when both are present', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); final List output = await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall('dart', const ['run', 'tool/run_tests.dart'], package.path), ])); expect( output, containsAllInOrder([ contains('Ran for 1 package(s)'), ])); }); test('runs when only new is present', () async { final RepositoryPackage package = createFakePackage( 'a_package', packagesDir, extraFiles: ['tool/run_tests.dart']); final List output = await runCapturingPrint(runner, ['custom-test']); expect( processRunner.recordedCalls, containsAll([ ProcessCall('dart', const ['run', 'tool/run_tests.dart'], package.path), ])); expect( output, containsAllInOrder([ contains('Ran for 1 package(s)'), ])); }); test('skips package when only legacy is present', () async { createFakePackage('a_package', packagesDir, extraFiles: ['run_tests.sh']); final List output = await runCapturingPrint(runner, ['custom-test']); expect(processRunner.recordedCalls, isEmpty); expect( output, containsAllInOrder([ contains('run_tests.sh is not supported on Windows'), contains('Skipped 1 package(s)'), ])); }); test('fails if new fails', () async { createFakePackage('a_package', packagesDir, extraFiles: [ 'tool/run_tests.dart', 'run_tests.sh', ]); processRunner.mockProcessesForExecutable['dart'] = [ FakeProcessInfo(MockProcess(), ['pub', 'get']), FakeProcessInfo(MockProcess(exitCode: 1), ['test']), ]; Error? commandError; final List output = await runCapturingPrint( runner, ['custom-test'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output, containsAllInOrder([ contains('The following packages had errors:'), contains('a_package') ])); }); }); }