From 966f97acdcbab2ada689528cffdba60ce3d2779a Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 15 Aug 2023 21:56:25 -0700 Subject: [PATCH] ListMetricAggregator UTs - cached measurement adjustment after layout changes (#38936) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38936 Unit tests that validate we continue to return correct measurement results through the lifetime of the list when cells are unmounted, or layout of the list shifts. Changelog: [Internal] Reviewed By: lenaic Differential Revision: D47978632 fbshipit-source-id: b700fafb699e8820de6825f0ead1ef02c6d8f168 --- .../__tests__/ListMetricsAggregator-test.js | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/packages/virtualized-lists/Lists/__tests__/ListMetricsAggregator-test.js b/packages/virtualized-lists/Lists/__tests__/ListMetricsAggregator-test.js index d36930d9b01..ef253fb9463 100644 --- a/packages/virtualized-lists/Lists/__tests__/ListMetricsAggregator-test.js +++ b/packages/virtualized-lists/Lists/__tests__/ListMetricsAggregator-test.js @@ -712,4 +712,186 @@ describe('ListMetricsAggregator', () => { offset: 30, }); }); + + it('resolves metrics of unmounted cell after list shift when using bottom-up layout propagation', () => { + const listMetrics = new ListMetricsAggregator(); + const orientation = {horizontal: true, rtl: true}; + const props: CellMetricProps = { + data: [1, 2, 3, 4, 5], + getItemCount: () => nullthrows(props.data).length, + getItem: (i: number) => nullthrows(props.data)[i], + }; + + listMetrics.notifyCellLayout({ + cellIndex: 0, + cellKey: '0', + orientation, + layout: { + height: 5, + width: 10, + x: 90, + y: 0, + }, + }); + + listMetrics.notifyCellLayout({ + cellIndex: 1, + cellKey: '1', + orientation, + layout: { + height: 5, + width: 20, + x: 70, + y: 0, + }, + }); + + listMetrics.notifyListContentLayout({ + layout: {width: 100, height: 5}, + orientation, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: true, + }); + + listMetrics.notifyCellLayout({ + cellIndex: 2, + cellKey: '2', + orientation, + layout: { + height: 5, + width: 20, + x: 50, + y: 0, + }, + }); + + listMetrics.notifyListContentLayout({ + layout: {width: 120, height: 5}, + orientation, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: true, + }); + + listMetrics.notifyCellUnmounted('1'); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: false, + }); + + listMetrics.notifyListContentLayout({ + layout: {width: 100, height: 5}, + orientation, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: false, + }); + }); + + it('resolves metrics of unmounted cell after list shift when using top-down layout propagation', () => { + const listMetrics = new ListMetricsAggregator(); + const orientation = {horizontal: true, rtl: true}; + const props: CellMetricProps = { + data: [1, 2, 3, 4, 5], + getItemCount: () => nullthrows(props.data).length, + getItem: (i: number) => nullthrows(props.data)[i], + }; + + listMetrics.notifyListContentLayout({ + layout: {width: 100, height: 5}, + orientation, + }); + + listMetrics.notifyCellLayout({ + cellIndex: 0, + cellKey: '0', + orientation, + layout: { + height: 5, + width: 10, + x: 90, + y: 0, + }, + }); + + listMetrics.notifyCellLayout({ + cellIndex: 1, + cellKey: '1', + orientation, + layout: { + height: 5, + width: 20, + x: 70, + y: 0, + }, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: true, + }); + + listMetrics.notifyListContentLayout({ + layout: {width: 120, height: 5}, + orientation, + }); + + listMetrics.notifyCellLayout({ + cellIndex: 2, + cellKey: '2', + orientation, + layout: { + height: 5, + width: 20, + x: 50, + y: 0, + }, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: true, + }); + + listMetrics.notifyListContentLayout({ + layout: {width: 100, height: 5}, + orientation, + }); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: true, + }); + + listMetrics.notifyCellUnmounted('1'); + + expect(listMetrics.getCellMetrics(1, props)).toEqual({ + index: 1, + length: 20, + offset: 10, + isMounted: false, + }); + }); });