Skip to content

Commit

Permalink
Rewrite <Cache> element tests to not use cache()
Browse files Browse the repository at this point in the history
Because we haven't decided on the client caching semantics of cache(),
we're going to remove the behavior for now and add it back later. So
we need to rewrite these client tests to not depend on cache(). This
essentially reverts the test suite back to what it was before facebook#25506.

There were also some tests in the ReactUse-test module that depended
on cache() too, which I've also updated.
  • Loading branch information
acdlite committed Jan 16, 2024
1 parent 256f19a commit d855463
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 115 deletions.
174 changes: 80 additions & 94 deletions packages/react-reconciler/src/__tests__/ReactCacheElement-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ let React;
let ReactNoop;
let Cache;
let getCacheSignal;
let getCacheForType;
let Scheduler;
let assertLog;
let act;
Expand All @@ -10,13 +11,11 @@ let Activity;
let useCacheRefresh;
let startTransition;
let useState;
let cache;

let getTextCache;
let textCaches;
let seededCache;

describe('ReactCache', () => {
describe('ReactCacheElement', () => {
beforeEach(() => {
jest.resetModules();

Expand All @@ -26,9 +25,9 @@ describe('ReactCache', () => {
Scheduler = require('scheduler');
act = require('internal-test-utils').act;
Suspense = React.Suspense;
cache = React.cache;
Activity = React.unstable_Activity;
getCacheSignal = React.unstable_getCacheSignal;
getCacheForType = React.unstable_getCacheForType;
useCacheRefresh = React.unstable_useCacheRefresh;
startTransition = React.startTransition;
useState = React.useState;
Expand All @@ -38,59 +37,57 @@ describe('ReactCache', () => {

textCaches = [];
seededCache = null;
});

if (gate(flags => flags.enableCache)) {
getTextCache = cache(() => {
if (seededCache !== null) {
// Trick to seed a cache before it exists.
// TODO: Need a built-in API to seed data before the initial render (i.e.
// not a refresh because nothing has mounted yet).
const textCache = seededCache;
seededCache = null;
return textCache;
}

const data = new Map();
const version = textCaches.length + 1;
const textCache = {
version,
data,
resolve(text) {
const record = data.get(text);
if (record === undefined) {
const newRecord = {
status: 'resolved',
value: text,
cleanupScheduled: false,
};
data.set(text, newRecord);
} else if (record.status === 'pending') {
record.value.resolve();
}
},
reject(text, error) {
const record = data.get(text);
if (record === undefined) {
const newRecord = {
status: 'rejected',
value: error,
cleanupScheduled: false,
};
data.set(text, newRecord);
} else if (record.status === 'pending') {
record.value.reject();
}
},
};
textCaches.push(textCache);
return textCache;
});
function createTextCache() {
if (seededCache !== null) {
// Trick to seed a cache before it exists.
// TODO: Need a built-in API to seed data before the initial render (i.e.
// not a refresh because nothing has mounted yet).
const textCache = seededCache;
seededCache = null;
return textCache;
}
});

const data = new Map();
const version = textCaches.length + 1;
const textCache = {
version,
data,
resolve(text) {
const record = data.get(text);
if (record === undefined) {
const newRecord = {
status: 'resolved',
value: text,
cleanupScheduled: false,
};
data.set(text, newRecord);
} else if (record.status === 'pending') {
record.value.resolve();
}
},
reject(text, error) {
const record = data.get(text);
if (record === undefined) {
const newRecord = {
status: 'rejected',
value: error,
cleanupScheduled: false,
};
data.set(text, newRecord);
} else if (record.status === 'pending') {
record.value.reject();
}
},
};
textCaches.push(textCache);
return textCache;
}

function readText(text) {
const signal = getCacheSignal ? getCacheSignal() : null;
const textCache = getTextCache();
const textCache = getCacheForType(createTextCache);
const record = textCache.data.get(text);
if (record !== undefined) {
if (!record.cleanupScheduled) {
Expand Down Expand Up @@ -167,7 +164,7 @@ describe('ReactCache', () => {

function seedNextTextCache(text) {
if (seededCache === null) {
seededCache = getTextCache();
seededCache = createTextCache();
}
seededCache.resolve(text);
}
Expand All @@ -182,7 +179,7 @@ describe('ReactCache', () => {
}
}

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('render Cache component', async () => {
const root = ReactNoop.createRoot();
await act(() => {
Expand All @@ -191,7 +188,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Hi');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('mount new data', async () => {
const root = ReactNoop.createRoot();
await act(() => {
Expand Down Expand Up @@ -247,7 +244,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('multiple new Cache boundaries in the same mount share the same, fresh root cache', async () => {
function App() {
return (
Expand Down Expand Up @@ -290,7 +287,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('multiple new Cache boundaries in the same update share the same, fresh cache', async () => {
function App({showMore}) {
return showMore ? (
Expand Down Expand Up @@ -342,7 +339,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test(
'nested cache boundaries share the same cache as the root during ' +
'the initial render',
Expand Down Expand Up @@ -382,7 +379,7 @@ describe('ReactCache', () => {
},
);

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('new content inside an existing Cache boundary should re-use already cached data', async () => {
function App({showMore}) {
return (
Expand Down Expand Up @@ -426,7 +423,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('a new Cache boundary uses fresh cache', async () => {
// The only difference from the previous test is that the "Show More"
// content is wrapped in a nested <Cache /> boundary
Expand Down Expand Up @@ -484,7 +481,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('inner/outer cache boundaries uses the same cache instance on initial render', async () => {
const root = ReactNoop.createRoot();

Expand Down Expand Up @@ -566,7 +563,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('inner/ outer cache boundaries added in the same update use the same cache instance', async () => {
const root = ReactNoop.createRoot();

Expand Down Expand Up @@ -655,7 +652,6 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCache
test('refresh a cache boundary', async () => {
let refresh;
function App() {
Expand Down Expand Up @@ -705,7 +701,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('refresh the root cache', async () => {
let refresh;
function App() {
Expand Down Expand Up @@ -753,7 +749,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('refresh the root cache without a transition', async () => {
let refresh;
function App() {
Expand Down Expand Up @@ -808,20 +804,11 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('refresh a cache with seed data', async () => {
let refreshWithSeed;
let refresh;
function App() {
const refresh = useCacheRefresh();
const [seed, setSeed] = useState({fn: null});
if (seed.fn) {
seed.fn();
seed.fn = null;
}
refreshWithSeed = fn => {
setSeed({fn});
refresh();
};
refresh = useCacheRefresh();
return <AsyncText showVersion={true} text="A" />;
}

Expand Down Expand Up @@ -851,12 +838,11 @@ describe('ReactCache', () => {
// server mutation.
// TODO: Seeding multiple typed textCaches. Should work by calling `refresh`
// multiple times with different key/value pairs
startTransition(() =>
refreshWithSeed(() => {
const textCache = getTextCache();
textCache.resolve('A');
}),
);
startTransition(() => {
const textCache = createTextCache();
textCache.resolve('A');
startTransition(() => refresh(createTextCache, textCache));
});
});
// The root should re-render without a cache miss.
// The cache is not cleared up yet, since it's still reference by the root
Expand All @@ -871,7 +857,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('refreshing a parent cache also refreshes its children', async () => {
let refreshShell;
function RefreshShell() {
Expand Down Expand Up @@ -946,7 +932,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test(
'refreshing a cache boundary does not refresh the other boundaries ' +
'that mounted at the same time (i.e. the ones that share the same cache)',
Expand Down Expand Up @@ -1027,7 +1013,7 @@ describe('ReactCache', () => {
},
);

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test(
'mount a new Cache boundary in a sibling while simultaneously ' +
'resolving a Suspense boundary',
Expand Down Expand Up @@ -1096,7 +1082,7 @@ describe('ReactCache', () => {
},
);

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('cache pool is cleared once transitions that depend on it commit their shell', async () => {
function Child({text}) {
return (
Expand Down Expand Up @@ -1189,7 +1175,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('cache pool is not cleared by arbitrary commits', async () => {
function App() {
return (
Expand Down Expand Up @@ -1268,7 +1254,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('cache boundary uses a fresh cache when its key changes', async () => {
const root = ReactNoop.createRoot();
seedNextTextCache('A');
Expand Down Expand Up @@ -1307,7 +1293,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('overlapping transitions after an initial mount use the same fresh cache', async () => {
const root = ReactNoop.createRoot();
await act(() => {
Expand Down Expand Up @@ -1375,7 +1361,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('overlapping updates after an initial mount use the same fresh cache', async () => {
const root = ReactNoop.createRoot();
await act(() => {
Expand Down Expand Up @@ -1438,7 +1424,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test('cleans up cache only used in an aborted transition', async () => {
const root = ReactNoop.createRoot();
seedNextTextCache('A');
Expand Down Expand Up @@ -1493,7 +1479,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test.skip('if a root cache refresh never commits its fresh cache is released', async () => {
const root = ReactNoop.createRoot();
let refresh;
Expand Down Expand Up @@ -1535,7 +1521,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('Bye!');
});

// @gate enableCacheElement && enableCache
// @gate enableCacheElement
test.skip('if a cache boundary refresh never commits its fresh cache is released', async () => {
const root = ReactNoop.createRoot();
let refresh;
Expand Down
Loading

0 comments on commit d855463

Please sign in to comment.