// 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/update_excerpts_command.dart'; import 'package:test/test.dart'; import 'common/package_command_test.mocks.dart'; import 'mocks.dart'; import 'util.dart'; void runAllTests(MockPlatform platform) { late FileSystem fileSystem; late Directory packagesDir; late CommandRunner runner; setUp(() { fileSystem = MemoryFileSystem( style: platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix); packagesDir = createPackagesDirectory(fileSystem: fileSystem); runner = CommandRunner('', '') ..addCommand(UpdateExcerptsCommand( packagesDir, platform: platform, processRunner: RecordingProcessRunner(), gitDir: MockGitDir(), )); }); Future testInjection(String before, String source, String after, {bool failOnChange = false}) async { final RepositoryPackage package = createFakePackage('a_package', packagesDir); package.readmeFile.writeAsStringSync(before); package.directory.childFile('main.dart').writeAsStringSync(source); Object? errorObject; final List output = await runCapturingPrint( runner, [ 'update-excerpts', if (failOnChange) '--fail-on-change', ], errorHandler: (Object error) { errorObject = error; }, ); if (errorObject != null) { fail('Failed: $errorObject\n\nOutput from excerpt command:\n$output'); } expect(package.readmeFile.readAsStringSync(), after); } test('succeeds when nothing has changed', () async { const String readme = ''' Example: ```dart A B C ``` '''; const String source = ''' FAIL // #docregion SomeSection A B C // #enddocregion SomeSection FAIL '''; await testInjection(readme, source, readme); }); test('fails if example injection fails', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir); package.readmeFile.writeAsStringSync(''' Example: ```dart A B C ``` '''); package.directory.childFile('main.dart').writeAsStringSync(''' FAIL // #docregion SomeSection A B C // #enddocregion SomeSection FAIL '''); Error? commandError; final List output = await runCapturingPrint( runner, ['update-excerpts'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output, containsAllInOrder([ contains('Injecting excerpts failed:'), contains( 'main.dart: did not find a "// #docregion UnknownSection" pragma'), ]), ); }); test('updates files', () async { await testInjection( ''' Example: ```dart X Y Z ``` ''', ''' FAIL // #docregion SomeSection A B C // #enddocregion SomeSection FAIL ''', ''' Example: ```dart A B C ``` ''', ); }); test('fails if READMEs are changed with --fail-on-change', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir); package.readmeFile.writeAsStringSync(''' Example: ```dart X Y Z ``` '''); package.directory.childFile('main.dart').writeAsStringSync(''' FAIL // #docregion SomeSection A B C // #enddocregion SomeSection FAIL '''); Error? commandError; final List output = await runCapturingPrint( runner, ['update-excerpts', '--fail-on-change'], errorHandler: (Error e) { commandError = e; }); expect(commandError, isA()); expect( output.join('\n'), contains('The following files have out of date excerpts:'), ); }); test('does not fail if READMEs are not changed with --fail-on-change', () async { const String readme = ''' Example: ```dart A ``` ```dart B ``` '''; await testInjection( readme, ''' // #docregion aa A // #enddocregion aa // #docregion bb B // #enddocregion bb ''', readme, failOnChange: true, ); }); test('indents the plaster', () async { await testInjection( ''' Example: ```dart ``` ''', ''' // #docregion SomeSection A // #enddocregion SomeSection // #docregion SomeSection B // #enddocregion SomeSection ''', ''' Example: ```dart A // ··· B ``` ''', ); }); test('does not unindent blocks if plaster will not unindent', () async { await testInjection( ''' Example: ```dart ``` ''', ''' // #docregion SomeSection A // #enddocregion SomeSection // #docregion SomeSection B // #enddocregion SomeSection ''', ''' Example: ```dart A // ··· B ``` ''', ); }); test('unindents blocks', () async { await testInjection( ''' Example: ```dart ``` ''', ''' // #docregion SomeSection A // #enddocregion SomeSection // #docregion SomeSection B // #enddocregion SomeSection ''', ''' Example: ```dart A // ··· B ``` ''', ); }); test('unindents blocks and plaster', () async { await testInjection( ''' Example: ```dart ``` ''', ''' // #docregion SomeSection A // #enddocregion SomeSection // #docregion SomeSection B // #enddocregion SomeSection ''', ''' Example: ```dart A // ··· B ``` ''', ); }); test('relative path bases', () async { final RepositoryPackage package = createFakePackage('a_package', packagesDir); package.readmeFile.writeAsStringSync(''' ```dart ``` ```dart ``` ```dart ``` ```dart ``` ```dart ``` ```dart ``` ```dart ``` ```dart ``` '''); package.directory.childFile('main.dart').writeAsStringSync(''' // #docregion a X // #enddocregion a '''); package.directory.childDirectory('test').createSync(); package.directory .childDirectory('test') .childFile('main.dart') .writeAsStringSync(''' // #docregion a Y // #enddocregion a '''); package.directory .childDirectory('test') .childDirectory('test') .createSync(); package.directory .childDirectory('test') .childDirectory('test') .childFile('main.dart') .writeAsStringSync(''' // #docregion a Z // #enddocregion a '''); await runCapturingPrint(runner, ['update-excerpts']); expect(package.readmeFile.readAsStringSync(), ''' ```dart X ``` ```dart Y ``` ```dart Z ``` ```dart Y ``` ```dart X ``` ```dart Z ``` ```dart X ``` ```dart Y ``` '''); }); } void main() { runAllTests(MockPlatform()); runAllTests(MockPlatform(isWindows: true)); }