From e174bff63bc5355361fcd42578983c1338db6956 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Thu, 20 Feb 2025 14:10:34 -0800 Subject: [PATCH] Migrate some linkedName tests for types to be unit tests. --- test/dartdoc_test_base.dart | 7 +- test/end2end/model_test.dart | 104 +----------- test/parameters_test.dart | 1 - test/types_test.dart | 225 ++++++++++++++++++++++++++ testing/test_package/lib/example.dart | 20 --- testing/test_package/lib/fake.dart | 3 - 6 files changed, 229 insertions(+), 131 deletions(-) create mode 100644 test/types_test.dart 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();