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');