Skip to content

Commit

Permalink
Added failing tests for two remaining suspense cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Sep 7, 2018
1 parent 24f4070 commit 6a7a89d
Showing 1 changed file with 155 additions and 0 deletions.
155 changes: 155 additions & 0 deletions packages/react/src/__tests__/ReactProfiler-test.internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,7 @@ describe('Profiler', () => {

loadModules({
enableSchedulerTracking: true,
enableSuspense: true,
});

throwInOnInteractionScheduledWorkCompleted = false;
Expand Down Expand Up @@ -2301,5 +2302,159 @@ describe('Profiler', () => {
onInteractionScheduledWorkCompleted,
).toHaveBeenLastNotifiedOfInteraction(interaction);
});

it('does not prematurely complete for suspended sync renders', async () => {
const SimpleCacheProvider = require('simple-cache-provider');
let cache;
function invalidateCache() {
cache = SimpleCacheProvider.createCache(invalidateCache);
}
invalidateCache();

let resourcePromise;
const TextResource = SimpleCacheProvider.createResource(
([text, ms = 0]) => {
resourcePromise = new Promise((resolve, reject) =>
setTimeout(() => resolve(text), ms),
);
return resourcePromise;
},
([text, ms]) => text,
);

function AsyncText({ms, text}) {
TextResource.read(cache, [text, ms]);
return <span prop={text} />;
}

function Text({text}) {
return text;
}

const interaction = {
id: 0,
name: 'initial render',
timestamp: mockNow(),
};

const onRender = jest.fn();
let renderer;
SchedulerTracking.unstable_track(
interaction.name,
interaction.timestamp,
() => {
renderer = ReactTestRenderer.create(
<React.unstable_Profiler id="app" onRender={onRender}>
<React.Placeholder
delayMs={1000}
fallback={<Text text="loading" />}>
<AsyncText text="loaded" ms={2000} />
</React.Placeholder>
</React.unstable_Profiler>,
);
},
);

expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();

jest.runAllTimers();
await resourcePromise;

expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);
expect(
onInteractionScheduledWorkCompleted,
).toHaveBeenLastNotifiedOfInteraction(interaction);
});

it('does not prematurely complete for suspended renders that have exceeded their deadline', async () => {
function awaitableAdvanceTimers(ms) {
jest.advanceTimersByTime(ms);
// Wait until the end of the current tick
return new Promise(resolve => {
setImmediate(resolve);
});
}

const SimpleCacheProvider = require('simple-cache-provider');
let cache;
function invalidateCache() {
cache = SimpleCacheProvider.createCache(invalidateCache);
}
invalidateCache();

const TextResource = SimpleCacheProvider.createResource(
([text, ms = 0]) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
ReactTestRenderer.unstable_yield(`Promise resolved [${text}]`);
resolve(text);
}, ms);
});
},
([text, ms]) => text,
);

function AsyncText({ms, text}) {
try {
TextResource.read(cache, [text, ms]);
ReactTestRenderer.unstable_yield(`AsyncText [${text}]`);
return <span prop={text} />;
} catch (promise) {
if (typeof promise.then === 'function') {
ReactTestRenderer.unstable_yield(`Suspend! [${text}]`);
} else {
ReactTestRenderer.unstable_yield(`Error! [${text}]`);
}
throw promise;
}
}

function Text({text}) {
ReactTestRenderer.unstable_yield(`Text [${text}]`);
return text;
}

const interaction = {
id: 0,
name: 'initial render',
timestamp: mockNow(),
};

const onRender = jest.fn();
let renderer;
SchedulerTracking.unstable_track(
interaction.name,
interaction.timestamp,
() => {
renderer = ReactTestRenderer.create(
<React.unstable_Profiler id="app" onRender={onRender}>
<React.Placeholder
delayMs={1000}
fallback={<Text text="loading" />}>
<AsyncText text="loaded" ms={2000} />
</React.Placeholder>
</React.unstable_Profiler>,
{
unstable_isAsync: true,
},
);
},
);

advanceTimeBy(1500);
await awaitableAdvanceTimers(1500);

expect(renderer).toFlushAll(['Suspend! [loaded]', 'Text [loading]']);
expect(onInteractionScheduledWorkCompleted).not.toHaveBeenCalled();

advanceTimeBy(2500);
await awaitableAdvanceTimers(2500);

expect(renderer).toFlushAll(['AsyncText [loaded]']);
expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);
expect(
onInteractionScheduledWorkCompleted,
).toHaveBeenLastNotifiedOfInteraction(interaction);
});
});
});

0 comments on commit 6a7a89d

Please sign in to comment.