Skip to content

Commit 34561d6

Browse files
authored
Migrate some linkedName tests for types to be unit tests. (#4007)
Moving test cases out of the end2end tests consolidates them, and makes them faster.
1 parent 026aa2a commit 34561d6

File tree

6 files changed

+229
-131
lines changed

6 files changed

+229
-131
lines changed

test/dartdoc_test_base.dart

+3-4
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ abstract class DartdocTestBase {
3636

3737
String get linkPrefix => '$placeholder$libraryName';
3838

39-
String get dartAsyncUrlPrefix =>
40-
'https://api.dart.dev/stable/3.2.0/dart-async';
41-
42-
String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.2.0';
39+
String get dartAsyncUrlPrefix => '$dartSdkUrlPrefix/dart-async';
4340

4441
String get dartCoreUrlPrefix => '$dartSdkUrlPrefix/dart-core';
4542

43+
String get dartSdkUrlPrefix => 'https://api.dart.dev/stable/3.2.0';
44+
4645
String get sdkConstraint => '>=3.7.0 <4.0.0';
4746

4847
/// A mapping of pub dependency names to the paths.

test/end2end/model_test.dart

+1-103
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ void main() async {
18901890
});
18911891

18921892
test('correctly finds all the classes', () {
1893-
expect(classes, hasLength(37));
1893+
expect(classes, hasLength(34));
18941894
});
18951895

18961896
test('abstract', () {
@@ -3085,108 +3085,6 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
30853085
});
30863086
});
30873087

3088-
group('Type expansion', () {
3089-
late final Class TemplatedInterface, ClassWithUnusualProperties;
3090-
3091-
setUpAll(() {
3092-
TemplatedInterface = exLibrary.classes.named('TemplatedInterface');
3093-
ClassWithUnusualProperties =
3094-
fakeLibrary.classes.named('ClassWithUnusualProperties');
3095-
});
3096-
3097-
test('setter that takes a function is correctly displayed', () {
3098-
var explicitSetter = ClassWithUnusualProperties.instanceFields
3099-
.singleWhere((f) => f.name == 'explicitSetter');
3100-
// TODO(jcollins-g): really, these shouldn't be called "parameters" in
3101-
// the span class.
3102-
expect(
3103-
explicitSetter.modelType.linkedName,
3104-
matches(RegExp(
3105-
r'dynamic Function<span class="signature">\(<span class="parameter" id="(f-)?param-bar"><span class="type-annotation">int</span> <span class="parameter-name">bar</span>, </span><span class="parameter" id="(f-)?param-baz"><span class="type-annotation"><a href="%%__HTMLBASE_dartdoc_internal__%%fake/Cool-class.html">Cool</a></span> <span class="parameter-name">baz</span>, </span><span class="parameter" id="(f-)?param-macTruck"><span class="type-annotation">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span> <span class="parameter-name">macTruck</span></span>\)</span>')));
3106-
});
3107-
3108-
test('parameterized type from inherited field is correctly displayed', () {
3109-
var aInheritedField = TemplatedInterface.inheritedFields
3110-
.singleWhere((f) => f.name == 'aInheritedField');
3111-
expect(
3112-
aInheritedField.modelType.linkedName,
3113-
'<a href="${htmlBasePlaceholder}ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a>'
3114-
'<span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>?');
3115-
});
3116-
3117-
test(
3118-
'parameterized type for return value from inherited explicit getter is correctly displayed',
3119-
() {
3120-
Accessor aInheritedGetter = TemplatedInterface.inheritedFields
3121-
.singleWhere((f) => f.name == 'aInheritedGetter')
3122-
.getter!;
3123-
expect(aInheritedGetter.modelType.returnType.linkedName,
3124-
'<a href="${htmlBasePlaceholder}ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3125-
});
3126-
3127-
test(
3128-
'parameterized type for return value from inherited explicit setter is correctly displayed',
3129-
() {
3130-
Accessor aInheritedSetter = TemplatedInterface.inheritedFields
3131-
.singleWhere((f) => f.name == 'aInheritedSetter')
3132-
.setter!;
3133-
expect(aInheritedSetter.parameters.first.modelType.linkedName,
3134-
'<a href="${htmlBasePlaceholder}ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3135-
expect(aInheritedSetter.enclosingCombo.modelType.linkedName,
3136-
'<a href="%%__HTMLBASE_dartdoc_internal__%%ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3137-
});
3138-
3139-
test(
3140-
'parameterized type for return value from method is correctly displayed',
3141-
() {
3142-
var aMethodInterface = TemplatedInterface.instanceMethods
3143-
.singleWhere((m) => m.name == 'aMethodInterface');
3144-
expect(aMethodInterface.modelType.returnType.linkedName,
3145-
'<a href="${htmlBasePlaceholder}ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3146-
});
3147-
3148-
test(
3149-
'parameterized type for return value from inherited method is correctly displayed',
3150-
() {
3151-
var aInheritedMethod = TemplatedInterface.instanceMethods
3152-
.singleWhere((m) => m.name == 'aInheritedMethod');
3153-
expect(aInheritedMethod.modelType.returnType.linkedName,
3154-
'<a href="${htmlBasePlaceholder}ex/AnotherParameterizedClass-class.html">AnotherParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3155-
});
3156-
3157-
test(
3158-
'parameterized type for return value containing a parameterized typedef is correctly displayed',
3159-
() {
3160-
var aTypedefReturningMethodInterface = TemplatedInterface.instanceMethods
3161-
.singleWhere((m) => m.name == 'aTypedefReturningMethodInterface');
3162-
expect(aTypedefReturningMethodInterface.modelType.returnType.linkedName,
3163-
'<a href="${htmlBasePlaceholder}ex/ParameterizedTypedef.html">ParameterizedTypedef</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">String</span>&gt;</span></span>&gt;</span>');
3164-
});
3165-
3166-
test(
3167-
'parameterized type for return value containing a parameterized typedef from inherited method is correctly displayed',
3168-
() {
3169-
var aInheritedTypedefReturningMethod = TemplatedInterface.instanceMethods
3170-
.singleWhere((m) => m.name == 'aInheritedTypedefReturningMethod');
3171-
expect(aInheritedTypedefReturningMethod.modelType.returnType.linkedName,
3172-
'<a href="${htmlBasePlaceholder}ex/ParameterizedTypedef.html">ParameterizedTypedef</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3173-
});
3174-
3175-
test('parameterized types for inherited operator is correctly displayed',
3176-
() {
3177-
var aInheritedAdditionOperator = TemplatedInterface.inheritedOperators
3178-
.singleWhere((m) => m.name == 'operator +');
3179-
expect(aInheritedAdditionOperator.modelType.returnType.linkedName,
3180-
'<a href="${htmlBasePlaceholder}ex/ParameterizedClass-class.html">ParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span>');
3181-
expect(
3182-
ParameterRendererHtml()
3183-
.renderLinkedParams(aInheritedAdditionOperator.parameters),
3184-
'<span class="parameter" id="+-param-other"><span class="type-annotation"><a href="${htmlBasePlaceholder}ex/ParameterizedClass-class.html">ParameterizedClass</a><span class="signature">&lt;<wbr><span class="type-parameter">List<span class="signature">&lt;<wbr><span class="type-parameter">int</span>&gt;</span></span>&gt;</span></span> <span class="parameter-name">other</span></span>');
3185-
});
3186-
3187-
test('', () {});
3188-
});
3189-
31903088
group('Method', () {
31913089
late final Class classB,
31923090
klass,

test/parameters_test.dart

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ void f(int _) {}
6666
void test_formalParameter_generic_method() async {
6767
var library = await bootPackageWithLibrary('''
6868
class C {
69-
C() {}
7069
int one(int Function<T>(T)? f) {
7170
return 1;
7271
}

test/types_test.dart

+225
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:dartdoc/src/model/model.dart';
6+
import 'package:dartdoc/src/render/parameter_renderer.dart';
7+
import 'package:test/test.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import 'dartdoc_test_base.dart';
11+
import 'src/utils.dart';
12+
13+
void main() {
14+
defineReflectiveSuite(() {
15+
defineReflectiveTests(TypesTest);
16+
});
17+
}
18+
19+
@reflectiveTest
20+
class TypesTest extends DartdocTestBase {
21+
@override
22+
String get libraryName => 'types';
23+
24+
void test_setter_functionTypedParameter() async {
25+
var library = await bootPackageWithLibrary('''
26+
class C {
27+
set f(p(int a, List<int> b)) {}
28+
}
29+
''');
30+
var f = library.field('C', 'f');
31+
expect(f.modelType.linkedName, matchesCompressed('''
32+
dynamic Function
33+
<span class="signature">\\(
34+
<span class="parameter" id="p-param-a">
35+
<span class="type-annotation">
36+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
37+
</span>
38+
<span class="parameter-name">a</span>,
39+
</span>
40+
<span class="parameter" id="p-param-b">
41+
<span class="type-annotation">
42+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
43+
<span class="signature">&lt;<wbr>
44+
<span class="type-parameter">
45+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
46+
</span>&gt;
47+
</span>
48+
</span>
49+
<span class="parameter-name">b</span>
50+
</span>\\)
51+
</span>
52+
'''));
53+
}
54+
55+
void test_field_substitutedTypes() async {
56+
var library = await bootPackageWithLibrary('''
57+
class C<T> {
58+
List<T>? f;
59+
}
60+
class D extends C<int> {}
61+
''');
62+
var f = library.field('D', 'f');
63+
expect(f.modelType.linkedName, matchesCompressed('''
64+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
65+
<span class="signature">&lt;<wbr>
66+
<span class="type-parameter">
67+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
68+
</span>&gt;
69+
</span>
70+
'''));
71+
}
72+
73+
void test_getter_substitutedTypes() async {
74+
var library = await bootPackageWithLibrary('''
75+
class C<T> {
76+
List<T> get f => [];
77+
}
78+
class D extends C<int> {}
79+
''');
80+
var f = library.field('D', 'f').getter!;
81+
expect(f.modelType.returnType.linkedName, matchesCompressed('''
82+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
83+
<span class="signature">&lt;<wbr>
84+
<span class="type-parameter">
85+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
86+
</span>&gt;
87+
</span>
88+
'''));
89+
}
90+
91+
void test_setterParameter_substitutedTypes() async {
92+
var library = await bootPackageWithLibrary('''
93+
class C<T> {
94+
set f(List<T> p) {}
95+
}
96+
class D extends C<int> {}
97+
''');
98+
var f = library.field('D', 'f').setter!;
99+
expect(f.parameters.first.modelType.linkedName, matchesCompressed('''
100+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
101+
<span class="signature">&lt;<wbr>
102+
<span class="type-parameter">
103+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
104+
</span>&gt;
105+
</span>
106+
'''));
107+
}
108+
109+
void test_methodReturnType() async {
110+
var library = await bootPackageWithLibrary('''
111+
abstract class C {
112+
List<int> m();
113+
}
114+
''');
115+
var m = library.method('C', 'm');
116+
expect(m.modelType.returnType.linkedName, matchesCompressed('''
117+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
118+
<span class="signature">&lt;<wbr>
119+
<span class="type-parameter">
120+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
121+
</span>&gt;
122+
</span>
123+
'''));
124+
}
125+
126+
void test_methodReturnType_substitutedTypes() async {
127+
var library = await bootPackageWithLibrary('''
128+
abstract class C<T> {
129+
List<T> m();
130+
}
131+
class D extends C<int> {}
132+
''');
133+
var m = library.method('D', 'm');
134+
expect(m.modelType.returnType.linkedName, matchesCompressed('''
135+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
136+
<span class="signature">&lt;<wbr>
137+
<span class="type-parameter">
138+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
139+
</span>&gt;
140+
</span>
141+
'''));
142+
}
143+
144+
void test_methodReturnType_parameterizedTypedef() async {
145+
var library = await bootPackageWithLibrary('''
146+
typedef String TD<T>(T p);
147+
abstract class C {
148+
TD<int> m();
149+
}
150+
''');
151+
var m = library.method('C', 'm');
152+
expect(m.modelType.returnType.linkedName, matchesCompressed('''
153+
<a href="${htmlBasePlaceholder}types/TD.html">TD</a>
154+
<span class="signature">&lt;<wbr>
155+
<span class="type-parameter">
156+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
157+
</span>&gt;
158+
</span>
159+
'''));
160+
}
161+
162+
void test_methodReturnType_substitutedTypes_parameterizedTypedef() async {
163+
var library = await bootPackageWithLibrary('''
164+
typedef String TD<T>(T p);
165+
abstract class C<T> {
166+
TD<T> m();
167+
}
168+
class D extends C<int> {}
169+
''');
170+
var m = library.method('D', 'm');
171+
expect(m.modelType.returnType.linkedName, matchesCompressed('''
172+
<a href="${htmlBasePlaceholder}types/TD.html">TD</a>
173+
<span class="signature">&lt;<wbr>
174+
<span class="type-parameter">
175+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
176+
</span>&gt;
177+
</span>
178+
'''));
179+
}
180+
181+
void test_operatorTypes_substitutedTypes() async {
182+
var library = await bootPackageWithLibrary('''
183+
abstract class C<T> {
184+
List<T> operator +(List<T> p);
185+
}
186+
class D extends C<int> {}
187+
''');
188+
var plus = library.operator('D', 'operator +');
189+
expect(plus.modelType.returnType.linkedName, matchesCompressed('''
190+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
191+
<span class="signature">&lt;<wbr>
192+
<span class="type-parameter">
193+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
194+
</span>&gt;
195+
</span>
196+
'''));
197+
var renderedParameter =
198+
ParameterRendererHtml().renderLinkedParams(plus.parameters);
199+
expect(renderedParameter, matchesCompressed('''
200+
<a href="$dartCoreUrlPrefix/List-class.html">List</a>
201+
<span class="signature">&lt;<wbr>
202+
<span class="type-parameter">
203+
<a href="$dartCoreUrlPrefix/int-class.html">int</a>
204+
</span>&gt;
205+
</span>
206+
'''));
207+
}
208+
}
209+
210+
extension on Library {
211+
Field field(String className, String methodName) => classes
212+
.firstWhere((c) => c.name == className)
213+
.instanceFields
214+
.firstWhere((field) => field.name == methodName);
215+
216+
Method method(String className, String methodName) => classes
217+
.firstWhere((clas) => clas.name == className)
218+
.instanceMethods
219+
.firstWhere((method) => method.name == methodName);
220+
221+
Operator operator(String className, String methodName) => classes
222+
.firstWhere((clas) => clas.name == className)
223+
.instanceOperators
224+
.firstWhere((method) => method.name == methodName);
225+
}

testing/test_package/lib/example.dart

-20
Original file line numberDiff line numberDiff line change
@@ -88,26 +88,6 @@ typedef String processMessage<T>(String msg);
8888

8989
typedef String ParameterizedTypedef<T>(T msg, int foo);
9090

91-
/// Support class to test inheritance + type expansion from implements clause.
92-
abstract class ParameterizedClass<T> {
93-
AnotherParameterizedClass<T> aInheritedMethod(int foo);
94-
ParameterizedTypedef<T> aInheritedTypedefReturningMethod();
95-
AnotherParameterizedClass<T>? aInheritedField;
96-
AnotherParameterizedClass<T> get aInheritedGetter;
97-
ParameterizedClass<T> operator +(ParameterizedClass<T> other);
98-
set aInheritedSetter(AnotherParameterizedClass<T> thingToSet);
99-
}
100-
101-
class AnotherParameterizedClass<B> {}
102-
103-
/// Class for testing expansion of type from implements clause.
104-
abstract class TemplatedInterface<A> implements ParameterizedClass<List<int>> {
105-
AnotherParameterizedClass<List<int>> aMethodInterface(A value);
106-
ParameterizedTypedef<List<String>> aTypedefReturningMethodInterface();
107-
AnotherParameterizedClass<Stream<List<int>>>? aField;
108-
set aSetter(AnotherParameterizedClass<List<bool>> thingToSet);
109-
}
110-
11191
class TemplatedClass<X> {
11292
int aMethod(X input) {
11393
return 5;

0 commit comments

Comments
 (0)