Skip to content

Commit 7d41296

Browse files
authored
Add some basic NNBD tests and fix a type parameter rendering bug (#2227)
* nnbd opt out test * Add new tests and fix minor bugs * Remove superfluous method
1 parent 47f7ab5 commit 7d41296

File tree

6 files changed

+83
-9
lines changed

6 files changed

+83
-9
lines changed

lib/src/element_type.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ class TypeParameterElementType extends DefinedElementType {
235235
TypeParameterType get type => super.type;
236236

237237
@override
238-
String get linkedName => name;
238+
String get linkedName => '${name}${nullabilitySuffix}';
239239

240240
@override
241-
String get nameWithGenerics => name;
241+
String get nameWithGenerics => '${name}${nullabilitySuffix}';
242242

243243
@override
244244
DartType get _bound => type.bound;

lib/src/model/getter_setter_combo.dart

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ mixin GetterSetterCombo on ModelElement {
185185
if (hasGetter) {
186186
return getter.linkedReturnType;
187187
} else {
188+
// TODO(jcollins-g): this results in the wrong span class for the return
189+
// type.
188190
return setter.linkedParamsNoMetadataOrNames;
189191
}
190192
}

lib/src/render/element_type_renderer.dart

-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class ParameterizedElementTypeRendererHtml
7979
'</span>, <span class="type-parameter">');
8080
buf.write('</span>&gt;');
8181
}
82-
buf.write(elementType.nullabilitySuffix);
8382
return wrapNullability(elementType, buf.toString());
8483
}
8584
}

test/model_special_cases_test.dart

+64-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ void main() {
4242
group('Experiments', () {
4343
Library lateFinalWithoutInitializer,
4444
nnbdClassMemberDeclarations,
45-
optOutOfNnbd;
45+
optOutOfNnbd,
46+
nullableElements;
4647
Class b;
4748

4849
setUpAll(() async {
@@ -55,6 +56,9 @@ void main() {
5556
optOutOfNnbd = (await utils.testPackageGraphExperiments)
5657
.libraries
5758
.firstWhere((lib) => lib.name == 'opt_out_of_nnbd');
59+
nullableElements = (await utils.testPackageGraphExperiments)
60+
.libraries
61+
.firstWhere((lib) => lib.name == 'nullable_elements');
5862
b = nnbdClassMemberDeclarations.allClasses
5963
.firstWhere((c) => c.name == 'B');
6064
});
@@ -142,6 +146,65 @@ void main() {
142146
expect(initializeMe.isLate, isTrue);
143147
expect(initializeMe.features, contains('late'));
144148
});
149+
150+
test('Opt out of NNBD', () {
151+
var notOptedIn = optOutOfNnbd.publicProperties
152+
.firstWhere((v) => v.name == 'notOptedIn');
153+
expect(notOptedIn.isNNBD, isFalse);
154+
expect(notOptedIn.modelType.nullabilitySuffix, isEmpty);
155+
});
156+
157+
test('complex nullable elements are detected and rendered correctly', () {
158+
var complexNullableMembers = nullableElements.allClasses
159+
.firstWhere((c) => c.name == 'ComplexNullableMembers');
160+
var aComplexType = complexNullableMembers.allFields
161+
.firstWhere((f) => f.name == 'aComplexType');
162+
var aComplexSetterOnlyType = complexNullableMembers.allFields
163+
.firstWhere((f) => f.name == 'aComplexSetterOnlyType');
164+
expect(complexNullableMembers.isNNBD, isTrue);
165+
expect(
166+
complexNullableMembers.nameWithGenerics,
167+
equals(
168+
'ComplexNullableMembers&lt;<wbr><span class=\"type-parameter\">T extends String?</span>&gt;'));
169+
expect(
170+
aComplexType.linkedReturnType,
171+
equals(
172+
'Map<span class="signature">&lt;<wbr><span class="type-parameter">T?</span>, <span class="type-parameter">String?</span>&gt;</span>'));
173+
expect(aComplexSetterOnlyType.linkedReturnType, equals(
174+
// TODO(jcollins-g): fix wrong span class for setter-only return type (#2226)
175+
'<span class="parameter" id="aComplexSetterOnlyType=-param-value"><span class="type-annotation">List<span class="signature">&lt;<wbr><span class="type-parameter">Map<span class="signature">&lt;<wbr><span class="type-parameter">T?</span>, <span class="type-parameter">String?</span>&gt;</span>?</span>&gt;</span></span></span><wbr>'));
176+
});
177+
178+
test('simple nullable elements are detected and rendered correctly', () {
179+
var nullableMembers = nullableElements.allClasses
180+
.firstWhere((c) => c.name == 'NullableMembers');
181+
var initialized =
182+
nullableMembers.allFields.firstWhere((f) => f.name == 'initialized');
183+
var nullableField = nullableMembers.allFields
184+
.firstWhere((f) => f.name == 'nullableField');
185+
var methodWithNullables = nullableMembers.publicInstanceMethods
186+
.firstWhere((f) => f.name == 'methodWithNullables');
187+
var operatorStar = nullableMembers.publicInstanceOperators
188+
.firstWhere((f) => f.name == 'operator *');
189+
expect(nullableMembers.isNNBD, isTrue);
190+
expect(
191+
nullableField.linkedReturnType,
192+
equals(
193+
'Iterable<span class=\"signature\">&lt;<wbr><span class=\"type-parameter\">BigInt</span>&gt;</span>?'));
194+
expect(
195+
methodWithNullables.linkedParams,
196+
equals(
197+
'<span class="parameter" id="methodWithNullables-param-foo"><span class="type-annotation">String?</span> <span class="parameter-name">foo</span></span><wbr>'));
198+
expect(methodWithNullables.linkedReturnType, equals('int?'));
199+
expect(
200+
initialized.linkedReturnType,
201+
equals(
202+
'Map<span class="signature">&lt;<wbr><span class="type-parameter">String</span>, <span class="type-parameter">Map</span>&gt;</span>?'));
203+
expect(
204+
operatorStar.linkedParams,
205+
equals(
206+
'<span class="parameter" id="*-param-nullableOther"><span class="type-annotation"><a href="%%__HTMLBASE_dartdoc_internal__%%nullable_elements/NullableMembers-class.html">NullableMembers</a>?</span> <span class="parameter-name">nullableOther</span></span><wbr>'));
207+
});
145208
},
146209
skip: (!_nnbdExperimentAllowed.allows(_platformVersion) &&
147210
!_platformVersionString.contains('edge')));

testing/test_package_experiments/lib/nnbd_class_member_declarations.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ abstract class B {
1616
}
1717

1818
/// Test nullable parameters, factories, members
19-
abstract class C {
20-
factory C.factory1(int? param, {Object? param2}) => null;
19+
class C {
20+
C() {}
21+
22+
factory C.factory1(int? param, {Object? param2}) => C();
2123

2224
int? testField;
2325

24-
List<int?> get testFieldNullableParameter;
26+
List<int?> get testFieldNullableParameter => [];
2527

26-
List<Map<String, num?>>? method1();
28+
List<Map<String, num?>>? method1() => null;
2729
}

testing/test_package_experiments/lib/nullable_elements.dart

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ String? get nullableGetter => null;
1111
String? _nullableSetter;
1212

1313
void set nullableSetter(String? value) {
14-
_nullableSetter = value;
14+
_nullableSetter = _nullableSetter ??= value;
1515
}
1616

1717
void some(int? nullable, String? parameters) {}
@@ -27,4 +27,12 @@ class NullableMembers {
2727
operator *(NullableMembers? nullableOther) => this;
2828

2929
int? methodWithNullables(String? foo) => foo?.length;
30+
}
31+
32+
class ComplexNullableMembers<T extends String?> {
33+
Map<T?, String?> aComplexType = <T?, String?>{null: null};
34+
35+
void set aComplexSetterOnlyType(List<Map<T?, String?>?> value) => null;
36+
37+
X? aMethod<X extends T?>(X? f) => null;
3038
}

0 commit comments

Comments
 (0)