diff --git a/test/co19/co19_test_base.dart b/test/co19/co19_test_base.dart new file mode 100644 index 0000000000..d875209f8f --- /dev/null +++ b/test/co19/co19_test_base.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. 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:analyzer/file_system/file_system.dart'; +import 'package:dartdoc/src/dartdoc_options.dart'; +import 'package:dartdoc/src/model/model.dart'; +import 'package:test/test.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dartdoc_test_base.dart'; +import '../src/utils.dart' as utils; + +@reflectiveTest +class Co19TestBase extends DartdocTestBase { + @override + String get libraryName => 'co19'; + + late Folder projectRoot; + late PackageGraph packageGraph; + late ModelElement libraryModel; + + void expectNoWarnings() { + expect(packageGraph.packageWarningCounter.countedWarnings, isEmpty); + expect(packageGraph.packageWarningCounter.hasWarnings, isFalse); + } + + Future writePackageWithCommentedLibraries( + List<(String, String)> filesAndComments, { + List additionalArguments = const [], + }) async { + projectRoot = + utils.writePackage('co19', resourceProvider, packageConfigProvider); + projectRoot + .getChildAssumingFile('dartdoc_options.yaml') + .writeAsStringSync(''' + dartdoc: + warnings: + - missing-code-block-language + '''); + + for (var (fileName, comment) in filesAndComments) { + projectRoot + .getChildAssumingFolder('lib') + .getChildAssumingFile(fileName) + .writeAsStringSync('$comment\n' + 'library;'); + } + + var optionSet = DartdocOptionRoot.fromOptionGenerators( + 'dartdoc', [createDartdocOptions], packageMetaProvider); + optionSet.parseArguments([]); + packageGraph = await utils.bootBasicPackage( + projectRoot.path, packageMetaProvider, packageConfigProvider, + additionalArguments: additionalArguments); + libraryModel = packageGraph.defaultPackage.libraries.first; + } + + Future writePackageWithCommentedLibrary( + String comment, { + List additionalArguments = const [], + }) => + writePackageWithCommentedLibraries([('a.dart', comment)], + additionalArguments: additionalArguments); + + void expectDocComment(dynamic matcher) { + expect(libraryModel.documentation, matcher); + } +} diff --git a/test/co19/line_based_doc_comments_test.dart b/test/co19/line_based_doc_comments_test.dart new file mode 100644 index 0000000000..b642d1855e --- /dev/null +++ b/test/co19/line_based_doc_comments_test.dart @@ -0,0 +1,170 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// @assertion A line-based doc comment is a comment that starts with `///`. One +/// or more consecutive lines that begin with `///` form a doc comment block. +/// +/// The block continues even if interrupted by single-line non-doc comments +/// (lines starting with `//`) or by blank lines. The interrupting lines are +/// ignored when extracting documentation text. +/// +/// For each line that begins with `///`, the parser removes the three slashes +/// and all leading whitespace to produce the documentation text. Exception: +/// inside fenced code blocks (` ``` `), whitespace after the leading `///` is +/// preserved to maintain code formatting. +/// @author sgrekhov22@gmail.com +library; + +import 'package:test/test.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'co19_test_base.dart'; + +void main() { + defineReflectiveSuite(() { + defineReflectiveTests(LineBasedDocCommentsTest); + }); +} + +@reflectiveTest +class LineBasedDocCommentsTest extends Co19TestBase { + /// Check that the parser removes the three slashes and all leading + /// whitespace + void test_removesTripleSlashes() async { + await writePackageWithCommentedLibrary(''' +/// Text. +/// More text. +'''); + expectDocComment(equals(''' +Text. +More text.''')); + } + + /// Check empty lines after three slashes are preserved + void test_leavesBlankLines() async { + await writePackageWithCommentedLibrary(''' +/// Text. +/// +/// More text. +'''); + expectDocComment(equals(''' +Text. + +More text.''')); + } + + /// Check that the parser removes the three slashes and all leading + /// whitespace + void test_removesSpaceAfterTripleSlashes() async { + markTestSkipped('Skipping until issue ' + 'https://github.com/dart-lang/dartdoc/issues/4137 is resolved.'); + return; +/* + await writePackageWithCommentedLibrary(''' +/// Text. +/// More text. +'''); + expectDocComment(equals(''' +Text. +More text.''')); +*/ + } + + /// Check that interrupting blank lines and starting with `// ` are ignored. + void test_interruptingLinesIgnored() async { + await writePackageWithCommentedLibrary(''' +/// Text. +// +/// More text. +// Some text +/// And more text. + +/// And more. +'''); + expectDocComment(equals(''' +Text. +More text. +And more text. +And more.''')); + } + + /// Check that the doc comment starts after `///` even there is no trailing + /// whitespace. + void test_noTrailingWhitespace() async { + await writePackageWithCommentedLibrary(''' +//// Text. +/////More text. +///And more. +'''); + expectDocComment(equals(''' +/ Text. +//More text. +And more.''')); + } + + /// Check that inside fenced code blocks (```), whitespace after the leading + /// `///` are preserved + void test_whitespaceInBacktickCodeBlocks() async { + await writePackageWithCommentedLibrary(''' +/// ``` +/// void main() { +/// /// This line prints "Hello, world!" +/// print('Hello, world!'); +/// } +/// ``` +'''); + expectDocComment(equals(''' +``` +void main() { + /// This line prints "Hello, world!" + print('Hello, world!'); +} +```''')); + } + + /// Check that inside fenced code blocks (~~~), whitespace after the leading + /// `///` are preserved + void test_whitespaceInTildesCodeBlocks() async { + await writePackageWithCommentedLibrary(''' +/// ~~~ +/// void main() { +/// /// This line prints "Hello, world!" +/// print('Hello, world!'); +/// } +/// ~~~ +'''); + expectDocComment(equals(''' +~~~ +void main() { + /// This line prints "Hello, world!" + print('Hello, world!'); +} +~~~''')); + } + + /// Check that inside fenced code span (`), whitespace after the leading + /// `///` are removed. + void test_whitespaceInCodeSpan() async { + markTestSkipped('Skipping until issue ' + 'https://github.com/dart-lang/dartdoc/issues/4138 is resolved.'); + return; +/* + await writePackageWithCommentedLibrary(''' +/// ` +/// void main() { +/// /// This line prints "Hello, world!" +/// print('Hello, world!'); +/// } +/// ` +'''); + expectDocComment(equals(''' +` +void main() { +/// This line prints "Hello, world!" +print('Hello, world!'); +} +`''')); +*/ + } +} diff --git a/test/dartdoc_test_base.dart b/test/dartdoc_test_base.dart index be046a1569..5b4c34e0a7 100644 --- a/test/dartdoc_test_base.dart +++ b/test/dartdoc_test_base.dart @@ -40,7 +40,7 @@ abstract class DartdocTestBase { String get dartCoreUrlPrefix => '$dartSdkUrlPrefix/dart-core'; - String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.2.0'; + String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.10.6'; String get sdkConstraint => '>=3.7.0 <4.0.0'; diff --git a/test/element_type_test.dart b/test/element_type_test.dart index 9fccc5960e..68990b8681 100644 --- a/test/element_type_test.dart +++ b/test/element_type_test.dart @@ -18,9 +18,9 @@ void main() async { const linkPrefix = '$placeholder$libraryName'; const intLink = - 'int'; + 'int'; const stringLink = - 'String'; + 'String'; final packageMetaProvider = testPackageMetaProvider; final resourceProvider = diff --git a/test/enums_test.dart b/test/enums_test.dart index 80fb8514c2..d608a2cdfc 100644 --- a/test/enums_test.dart +++ b/test/enums_test.dart @@ -232,7 +232,7 @@ class C {} expect( cClass.documentationAsHtml, '

Reference to ' - 'E.index.

', + 'E.index.

', ); } @@ -243,7 +243,7 @@ class C {} expect(eEnum.instanceFields.map((f) => f.name), contains('index')); expect( eEnum.instanceFields.named('index').linkedName, - 'index', + 'index', ); } diff --git a/test/src/utils.dart b/test/src/utils.dart index 54163b9c90..776c297799 100644 --- a/test/src/utils.dart +++ b/test/src/utils.dart @@ -161,7 +161,7 @@ PackageMetaProvider get testPackageMetaProvider { /// /// Included is a "version" file and an "api_readme.md" file. void writeMockSdkFiles(Folder sdkFolder) { - sdkFolder.getChildAssumingFile('version').writeAsStringSync('3.2.0'); + sdkFolder.getChildAssumingFile('version').writeAsStringSync('3.10.6'); sdkFolder.getChildAssumingFile('api_readme.md').writeAsStringSync( 'Welcome to the [Dart](https://dart.dev/) API reference documentation');