| // 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<void> runner; |
| |
| setUp(() { |
| fileSystem = MemoryFileSystem( |
| style: platform.isWindows |
| ? FileSystemStyle.windows |
| : FileSystemStyle.posix); |
| packagesDir = createPackagesDirectory(fileSystem: fileSystem); |
| runner = CommandRunner<void>('', '') |
| ..addCommand(UpdateExcerptsCommand( |
| packagesDir, |
| platform: platform, |
| processRunner: RecordingProcessRunner(), |
| gitDir: MockGitDir(), |
| )); |
| }); |
| |
| Future<void> 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<String> output = await runCapturingPrint( |
| runner, |
| <String>[ |
| '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: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```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: |
| |
| <?code-excerpt "main.dart (UnknownSection)"?> |
| ```dart |
| A B C |
| ``` |
| '''); |
| package.directory.childFile('main.dart').writeAsStringSync(''' |
| FAIL |
| // #docregion SomeSection |
| A B C |
| // #enddocregion SomeSection |
| FAIL |
| '''); |
| |
| Error? commandError; |
| final List<String> output = await runCapturingPrint( |
| runner, <String>['update-excerpts'], errorHandler: (Error e) { |
| commandError = e; |
| }); |
| |
| expect(commandError, isA<ToolExit>()); |
| expect( |
| output, |
| containsAllInOrder(<Matcher>[ |
| contains('Injecting excerpts failed:'), |
| contains( |
| 'main.dart: did not find a "// #docregion UnknownSection" pragma'), |
| ]), |
| ); |
| }); |
| |
| test('updates files', () async { |
| await testInjection( |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| X Y Z |
| ``` |
| ''', |
| ''' |
| FAIL |
| // #docregion SomeSection |
| A B C |
| // #enddocregion SomeSection |
| FAIL |
| ''', |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```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: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| X Y Z |
| ``` |
| '''); |
| package.directory.childFile('main.dart').writeAsStringSync(''' |
| FAIL |
| // #docregion SomeSection |
| A B C |
| // #enddocregion SomeSection |
| FAIL |
| '''); |
| |
| Error? commandError; |
| final List<String> output = await runCapturingPrint( |
| runner, <String>['update-excerpts', '--fail-on-change'], |
| errorHandler: (Error e) { |
| commandError = e; |
| }); |
| |
| expect(commandError, isA<ToolExit>()); |
| 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: |
| |
| <?code-excerpt "main.dart (aa)"?> |
| ```dart |
| A |
| ``` |
| <?code-excerpt "main.dart (bb)"?> |
| ```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: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| ``` |
| ''', |
| ''' |
| // #docregion SomeSection |
| A |
| // #enddocregion SomeSection |
| // #docregion SomeSection |
| B |
| // #enddocregion SomeSection |
| ''', |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| A |
| // ··· |
| B |
| ``` |
| ''', |
| ); |
| }); |
| |
| test('does not unindent blocks if plaster will not unindent', () async { |
| await testInjection( |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| ``` |
| ''', |
| ''' |
| // #docregion SomeSection |
| A |
| // #enddocregion SomeSection |
| // #docregion SomeSection |
| B |
| // #enddocregion SomeSection |
| ''', |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| A |
| // ··· |
| B |
| ``` |
| ''', |
| ); |
| }); |
| |
| test('unindents blocks', () async { |
| await testInjection( |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| ``` |
| ''', |
| ''' |
| // #docregion SomeSection |
| A |
| // #enddocregion SomeSection |
| // #docregion SomeSection |
| B |
| // #enddocregion SomeSection |
| ''', |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| A |
| // ··· |
| B |
| ``` |
| ''', |
| ); |
| }); |
| |
| test('unindents blocks and plaster', () async { |
| await testInjection( |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| ``` |
| ''', |
| ''' |
| // #docregion SomeSection |
| A |
| // #enddocregion SomeSection |
| // #docregion SomeSection |
| B |
| // #enddocregion SomeSection |
| ''', |
| ''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| A |
| // ··· |
| B |
| ``` |
| ''', |
| ); |
| }); |
| |
| test('relative path bases', () async { |
| final RepositoryPackage package = |
| createFakePackage('a_package', packagesDir); |
| package.readmeFile.writeAsStringSync(''' |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt "test/test/main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt path-base="test"?> |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt "../main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt path-base="/packages/a_package"?> |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```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, <String>['update-excerpts']); |
| expect(package.readmeFile.readAsStringSync(), ''' |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| X |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```dart |
| Y |
| ``` |
| <?code-excerpt "test/test/main.dart (a)"?> |
| ```dart |
| Z |
| ``` |
| <?code-excerpt path-base="test"?> |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| Y |
| ``` |
| <?code-excerpt "../main.dart (a)"?> |
| ```dart |
| X |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```dart |
| Z |
| ``` |
| <?code-excerpt path-base="/packages/a_package"?> |
| <?code-excerpt "main.dart (a)"?> |
| ```dart |
| X |
| ``` |
| <?code-excerpt "test/main.dart (a)"?> |
| ```dart |
| Y |
| ``` |
| '''); |
| }); |
| |
| test('logs snippets checked', () async { |
| final RepositoryPackage package = |
| createFakePackage('a_package', packagesDir); |
| package.readmeFile.writeAsStringSync(''' |
| Example: |
| |
| <?code-excerpt "main.dart (SomeSection)"?> |
| ```dart |
| A B C |
| ``` |
| '''); |
| package.directory.childFile('main.dart').writeAsStringSync(''' |
| FAIL |
| // #docregion SomeSection |
| A B C |
| // #enddocregion SomeSection |
| FAIL |
| '''); |
| |
| final List<String> output = |
| await runCapturingPrint(runner, <String>['update-excerpts']); |
| |
| expect( |
| output, |
| containsAllInOrder(<Matcher>[ |
| contains('Checked 1 snippet(s) in README.md.'), |
| ]), |
| ); |
| }); |
| } |
| |
| void main() { |
| runAllTests(MockPlatform()); |
| runAllTests(MockPlatform(isWindows: true)); |
| } |