diff --git a/test/dartdoc_test_base.dart b/test/dartdoc_test_base.dart
index f305778659..238571e893 100644
--- a/test/dartdoc_test_base.dart
+++ b/test/dartdoc_test_base.dart
@@ -36,13 +36,12 @@ abstract class DartdocTestBase {
String get linkPrefix => '$placeholder$libraryName';
- String get dartAsyncUrlPrefix =>
- 'https://api.dart.dev/stable/3.2.0/dart-async';
-
- String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.2.0';
+ String get dartAsyncUrlPrefix => '$dartSdkUrlPrefix/dart-async';
String get dartCoreUrlPrefix => '$dartSdkUrlPrefix/dart-core';
+ String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.2.0';
+
String get sdkConstraint => '>=3.7.0 <4.0.0';
/// A mapping of pub dependency names to the paths.
diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart
index f710aea487..6fb5b8b493 100644
--- a/test/end2end/model_test.dart
+++ b/test/end2end/model_test.dart
@@ -1890,7 +1890,7 @@ void main() async {
});
test('correctly finds all the classes', () {
- expect(classes, hasLength(37));
+ expect(classes, hasLength(34));
});
test('abstract', () {
@@ -3085,108 +3085,6 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
});
});
- group('Type expansion', () {
- late final Class TemplatedInterface, ClassWithUnusualProperties;
-
- setUpAll(() {
- TemplatedInterface = exLibrary.classes.named('TemplatedInterface');
- ClassWithUnusualProperties =
- fakeLibrary.classes.named('ClassWithUnusualProperties');
- });
-
- test('setter that takes a function is correctly displayed', () {
- var explicitSetter = ClassWithUnusualProperties.instanceFields
- .singleWhere((f) => f.name == 'explicitSetter');
- // TODO(jcollins-g): really, these shouldn't be called "parameters" in
- // the span class.
- expect(
- explicitSetter.modelType.linkedName,
- matches(RegExp(
- r'dynamic Function\(int bar, Cool baz, List<int> macTruck\)')));
- });
-
- test('parameterized type from inherited field is correctly displayed', () {
- var aInheritedField = TemplatedInterface.inheritedFields
- .singleWhere((f) => f.name == 'aInheritedField');
- expect(
- aInheritedField.modelType.linkedName,
- 'AnotherParameterizedClass'
- '<List<int>>?');
- });
-
- test(
- 'parameterized type for return value from inherited explicit getter is correctly displayed',
- () {
- Accessor aInheritedGetter = TemplatedInterface.inheritedFields
- .singleWhere((f) => f.name == 'aInheritedGetter')
- .getter!;
- expect(aInheritedGetter.modelType.returnType.linkedName,
- 'AnotherParameterizedClass<List<int>>');
- });
-
- test(
- 'parameterized type for return value from inherited explicit setter is correctly displayed',
- () {
- Accessor aInheritedSetter = TemplatedInterface.inheritedFields
- .singleWhere((f) => f.name == 'aInheritedSetter')
- .setter!;
- expect(aInheritedSetter.parameters.first.modelType.linkedName,
- 'AnotherParameterizedClass<List<int>>');
- expect(aInheritedSetter.enclosingCombo.modelType.linkedName,
- 'AnotherParameterizedClass<List<int>>');
- });
-
- test(
- 'parameterized type for return value from method is correctly displayed',
- () {
- var aMethodInterface = TemplatedInterface.instanceMethods
- .singleWhere((m) => m.name == 'aMethodInterface');
- expect(aMethodInterface.modelType.returnType.linkedName,
- 'AnotherParameterizedClass<List<int>>');
- });
-
- test(
- 'parameterized type for return value from inherited method is correctly displayed',
- () {
- var aInheritedMethod = TemplatedInterface.instanceMethods
- .singleWhere((m) => m.name == 'aInheritedMethod');
- expect(aInheritedMethod.modelType.returnType.linkedName,
- 'AnotherParameterizedClass<List<int>>');
- });
-
- test(
- 'parameterized type for return value containing a parameterized typedef is correctly displayed',
- () {
- var aTypedefReturningMethodInterface = TemplatedInterface.instanceMethods
- .singleWhere((m) => m.name == 'aTypedefReturningMethodInterface');
- expect(aTypedefReturningMethodInterface.modelType.returnType.linkedName,
- 'ParameterizedTypedef<List<String>>');
- });
-
- test(
- 'parameterized type for return value containing a parameterized typedef from inherited method is correctly displayed',
- () {
- var aInheritedTypedefReturningMethod = TemplatedInterface.instanceMethods
- .singleWhere((m) => m.name == 'aInheritedTypedefReturningMethod');
- expect(aInheritedTypedefReturningMethod.modelType.returnType.linkedName,
- 'ParameterizedTypedef<List<int>>');
- });
-
- test('parameterized types for inherited operator is correctly displayed',
- () {
- var aInheritedAdditionOperator = TemplatedInterface.inheritedOperators
- .singleWhere((m) => m.name == 'operator +');
- expect(aInheritedAdditionOperator.modelType.returnType.linkedName,
- 'ParameterizedClass<List<int>>');
- expect(
- ParameterRendererHtml()
- .renderLinkedParams(aInheritedAdditionOperator.parameters),
- 'ParameterizedClass<List<int>> other');
- });
-
- test('', () {});
- });
-
group('Method', () {
late final Class classB,
klass,
diff --git a/test/parameters_test.dart b/test/parameters_test.dart
index d9c3908403..bcf7d4c161 100644
--- a/test/parameters_test.dart
+++ b/test/parameters_test.dart
@@ -66,7 +66,6 @@ void f(int _) {}
void test_formalParameter_generic_method() async {
var library = await bootPackageWithLibrary('''
class C {
- C() {}
int one(int Function(T)? f) {
return 1;
}
diff --git a/test/types_test.dart b/test/types_test.dart
new file mode 100644
index 0000000000..31c963428f
--- /dev/null
+++ b/test/types_test.dart
@@ -0,0 +1,225 @@
+// 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:dartdoc/src/model/model.dart';
+import 'package:dartdoc/src/render/parameter_renderer.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'dartdoc_test_base.dart';
+import 'src/utils.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypesTest);
+ });
+}
+
+@reflectiveTest
+class TypesTest extends DartdocTestBase {
+ @override
+ String get libraryName => 'types';
+
+ void test_setter_functionTypedParameter() async {
+ var library = await bootPackageWithLibrary('''
+class C {
+ set f(p(int a, List b)) {}
+}
+''');
+ var f = library.field('C', 'f');
+ expect(f.modelType.linkedName, matchesCompressed('''
+ dynamic Function
+ \\(
+
+
+ int
+
+ a,
+
+
+
+ List
+ <
+
+ int
+ >
+
+
+ b
+ \\)
+
+ '''));
+ }
+
+ void test_field_substitutedTypes() async {
+ var library = await bootPackageWithLibrary('''
+class C {
+ List? f;
+}
+class D extends C {}
+''');
+ var f = library.field('D', 'f');
+ expect(f.modelType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_getter_substitutedTypes() async {
+ var library = await bootPackageWithLibrary('''
+class C {
+ List get f => [];
+}
+class D extends C {}
+''');
+ var f = library.field('D', 'f').getter!;
+ expect(f.modelType.returnType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_setterParameter_substitutedTypes() async {
+ var library = await bootPackageWithLibrary('''
+class C {
+ set f(List p) {}
+}
+class D extends C {}
+''');
+ var f = library.field('D', 'f').setter!;
+ expect(f.parameters.first.modelType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_methodReturnType() async {
+ var library = await bootPackageWithLibrary('''
+abstract class C {
+ List m();
+}
+''');
+ var m = library.method('C', 'm');
+ expect(m.modelType.returnType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_methodReturnType_substitutedTypes() async {
+ var library = await bootPackageWithLibrary('''
+abstract class C {
+ List m();
+}
+class D extends C {}
+''');
+ var m = library.method('D', 'm');
+ expect(m.modelType.returnType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_methodReturnType_parameterizedTypedef() async {
+ var library = await bootPackageWithLibrary('''
+typedef String TD(T p);
+abstract class C {
+ TD m();
+}
+''');
+ var m = library.method('C', 'm');
+ expect(m.modelType.returnType.linkedName, matchesCompressed('''
+ TD
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_methodReturnType_substitutedTypes_parameterizedTypedef() async {
+ var library = await bootPackageWithLibrary('''
+typedef String TD(T p);
+abstract class C {
+ TD m();
+}
+class D extends C {}
+''');
+ var m = library.method('D', 'm');
+ expect(m.modelType.returnType.linkedName, matchesCompressed('''
+ TD
+ <
+
+ int
+ >
+
+ '''));
+ }
+
+ void test_operatorTypes_substitutedTypes() async {
+ var library = await bootPackageWithLibrary('''
+abstract class C {
+ List operator +(List p);
+}
+class D extends C {}
+''');
+ var plus = library.operator('D', 'operator +');
+ expect(plus.modelType.returnType.linkedName, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ var renderedParameter =
+ ParameterRendererHtml().renderLinkedParams(plus.parameters);
+ expect(renderedParameter, matchesCompressed('''
+ List
+ <
+
+ int
+ >
+
+ '''));
+ }
+}
+
+extension on Library {
+ Field field(String className, String methodName) => classes
+ .firstWhere((c) => c.name == className)
+ .instanceFields
+ .firstWhere((field) => field.name == methodName);
+
+ Method method(String className, String methodName) => classes
+ .firstWhere((clas) => clas.name == className)
+ .instanceMethods
+ .firstWhere((method) => method.name == methodName);
+
+ Operator operator(String className, String methodName) => classes
+ .firstWhere((clas) => clas.name == className)
+ .instanceOperators
+ .firstWhere((method) => method.name == methodName);
+}
diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart
index 051b8d36c9..eda3269e28 100644
--- a/testing/test_package/lib/example.dart
+++ b/testing/test_package/lib/example.dart
@@ -88,26 +88,6 @@ typedef String processMessage(String msg);
typedef String ParameterizedTypedef(T msg, int foo);
-/// Support class to test inheritance + type expansion from implements clause.
-abstract class ParameterizedClass {
- AnotherParameterizedClass aInheritedMethod(int foo);
- ParameterizedTypedef aInheritedTypedefReturningMethod();
- AnotherParameterizedClass? aInheritedField;
- AnotherParameterizedClass get aInheritedGetter;
- ParameterizedClass operator +(ParameterizedClass other);
- set aInheritedSetter(AnotherParameterizedClass thingToSet);
-}
-
-class AnotherParameterizedClass {}
-
-/// Class for testing expansion of type from implements clause.
-abstract class TemplatedInterface implements ParameterizedClass> {
- AnotherParameterizedClass> aMethodInterface(A value);
- ParameterizedTypedef> aTypedefReturningMethodInterface();
- AnotherParameterizedClass>>? aField;
- set aSetter(AnotherParameterizedClass> thingToSet);
-}
-
class TemplatedClass {
int aMethod(X input) {
return 5;
diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart
index e4a9c73767..e42bcc10a0 100644
--- a/testing/test_package/lib/fake.dart
+++ b/testing/test_package/lib/fake.dart
@@ -562,9 +562,6 @@ abstract class ClassWithUnusualProperties extends ImplicitProperties {
return _aFunction;
}
- /// Set to [f], and don't warn about [bar] or [baz].
- set explicitSetter(f(int bar, Cool baz, List macTruck)) {}
-
/// This property has some docs, too.
final Set finalProperty = Set();