Skip to content

Commit cde1ace

Browse files
Merge pull request #974 from Workiva/fix-fragment-type-check-assert
FED-3585 Fix fragment type check assert
2 parents 93b7031 + 6c960a1 commit cde1ace

2 files changed

Lines changed: 57 additions & 4 deletions

File tree

lib/src/component_declaration/component_type_checking.dart

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,6 @@ bool isTypeAlias(dynamic type) {
172172
/// Returns the [ComponentTypeMeta] associated with the component type [type] in [setComponentTypeMeta],
173173
/// or `const ComponentTypeMeta.none()` if there is no associated meta.
174174
ComponentTypeMeta getComponentTypeMeta(Object type) {
175-
assert(isPotentiallyValidComponentType(type),
176-
'`type` should be a valid component type (and not null or a type alias).');
177-
178175
if (type is! String) {
179176
return getProperty(type, _componentTypeMetaKey) as ComponentTypeMeta? ??
180177
const ComponentTypeMeta.none();
@@ -307,7 +304,16 @@ Object? getComponentTypeFromAlias(Object? typeAlias) {
307304
/// * [Function] factory (Dart components)
308305
/// * [ReactClass] component type (JS composite component classes, JS function component functions, Dart component JS classes)
309306
bool isPotentiallyValidComponentType(dynamic type) {
310-
return type is Function || type is ReactClass || type is String;
307+
return type is Function ||
308+
// In DDC, `type is ReactClass` is true for JS symbols (such as for Fragment ReactElements),
309+
// but in dart2js it is false.
310+
// Since isPotentiallyValidComponentType is only used in aliasing code now, this isn't a big deal since
311+
// people aren't likely aliasing Fragment, but we should make this behavior consistent.
312+
// TODO handle that case in dart2js once our Dart SDK constraint is >=3.0.0, with the following code:
313+
// typeofEquals(type, 'symbol') ||
314+
// TODO also add a test (see TODO in component_type_checking_test.dart)
315+
type is ReactClass ||
316+
type is String;
311317
}
312318

313319
/// Returns an [Iterable] of all component types that are ancestors of [type].

test/over_react/component_declaration/component_type_checking_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,53 @@ main() {
318318
}, tags: 'ddc');
319319
});
320320
});
321+
322+
// Note: due to current behavioral differences of isPotentiallyValidComponentType between dart2js and DDC,
323+
// these regression tests only fail in dart2js with --enable-asserts, which we don't want to run our tests with.
324+
group('type checking and related utilities work as expected, without throwing, for', () {
325+
group('types of built-in and DOM components', () {
326+
final componentsByDescription = <String, ReactElement Function()>{
327+
// Edge-case: the `type` of Fragment is a JS Symbol
328+
'Fragment': () => Fragment()(''),
329+
'StrictMode': () => StrictMode()(),
330+
'div': () => Dom.div()(),
331+
};
332+
333+
componentsByDescription.forEach((description, factory) {
334+
group('- $description -', () {
335+
late ReactElement element;
336+
late Object type;
337+
338+
setUp(() {
339+
element = factory();
340+
final maybeType = element.type as Object?;
341+
expect(maybeType, isNotNull, reason: 'test setup check; element should have a type');
342+
type = maybeType!;
343+
});
344+
345+
// TODO uncomment once isPotentiallyValidComponentType is fixed for JS Symbols (see TODO in isPotentiallyValidComponentType), and update "Note:" comment above
346+
// test('isPotentiallyValidComponentType', () {
347+
// expect(isPotentiallyValidComponentType(type), isTrue);
348+
// });
349+
350+
test('getComponentTypeMeta', () {
351+
expect(getComponentTypeMeta(type), isA<ComponentTypeMeta>()
352+
.having((m) => m.isWrapper, 'isWrapper', false)
353+
.having((m) => m.isHoc, 'isHoc', false)
354+
.having((m) => m.parentType, 'parentType', isNull));
355+
});
356+
357+
test('getProps()', () {
358+
expect(getProps(element), isA<Map>());
359+
});
360+
361+
test('getProps(traverseWrappers: true)', () {
362+
expect(getProps(element, traverseWrappers: true), isA<Map>());
363+
});
364+
});
365+
});
366+
});
367+
});
321368
}
322369

323370
testComponentTypeChecking({

0 commit comments

Comments
 (0)