@testing-library/react
Advanced tools
Comparing version 12.1.0 to 13.0.0-alpha.1
@@ -42,4 +42,5 @@ 'use strict'; | ||
var reactAct = testUtils__namespace.act; | ||
var actSupported = reactAct !== undefined; // act is supported react-dom@16.8.0 | ||
var isomorphicAct = React__namespace.unstable_act; | ||
var domAct = testUtils__namespace.act; | ||
var actSupported = domAct !== undefined; // act is supported react-dom@16.8.0 | ||
// so for versions that don't have act from test utils | ||
@@ -54,3 +55,3 @@ // we do this little polyfill. No warnings, but it's | ||
var act = reactAct || actPolyfill; | ||
var act = isomorphicAct || domAct || actPolyfill; | ||
var youHaveBeenWarned = false; | ||
@@ -87,3 +88,3 @@ var isAsyncActSupported = null; | ||
try { | ||
result = reactAct(function () { | ||
result = domAct(function () { | ||
cbReturn = cb(); | ||
@@ -293,29 +294,73 @@ return cbReturn; | ||
}); | ||
if (React__namespace.startTransition !== undefined) { | ||
dom.configure({ | ||
unstable_advanceTimersWrapper: function unstable_advanceTimersWrapper(cb) { | ||
return act(cb); | ||
}, | ||
asyncWrapper: function asyncWrapper(cb) { | ||
return cb(); | ||
} | ||
}); | ||
} // Ideally we'd just use a WeakMap where containers are keys and roots are values. | ||
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case) | ||
/** | ||
* @type {Set<import('react-dom').Container>} | ||
*/ | ||
var mountedContainers = new Set(); | ||
/** | ||
* @type Array<{container: import('react-dom').Container, root: ReturnType<typeof createConcurrentRoot>}> | ||
*/ | ||
function render(ui, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
container = _ref2.container, | ||
_ref2$baseElement = _ref2.baseElement, | ||
baseElement = _ref2$baseElement === void 0 ? container : _ref2$baseElement, | ||
queries = _ref2.queries, | ||
_ref2$hydrate = _ref2.hydrate, | ||
hydrate = _ref2$hydrate === void 0 ? false : _ref2$hydrate, | ||
WrapperComponent = _ref2.wrapper; | ||
var mountedRootEntries = []; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
function createConcurrentRoot(container, options) { | ||
if (typeof ReactDOM__default['default'].createRoot !== 'function') { | ||
throw new TypeError("Attempted to use concurrent React with `react-dom@" + ReactDOM__default['default'].version + "`. Be sure to use the `next` or `experimental` release channel (https://reactjs.org/docs/release-channels.html).'"); | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
var root = options.hydrate ? ReactDOM__default['default'].hydrateRoot(container) : ReactDOM__default['default'].createRoot(container); | ||
return { | ||
hydrate: function hydrate(element) { | ||
/* istanbul ignore if */ | ||
if (!options.hydrate) { | ||
throw new Error('Attempted to hydrate a non-hydrateable root. This is a bug in `@testing-library/react`.'); | ||
} | ||
root.render(element); | ||
}, | ||
render: function render(element) { | ||
root.render(element); | ||
}, | ||
unmount: function unmount() { | ||
root.unmount(); | ||
} | ||
}; | ||
} | ||
mountedContainers.add(container); | ||
function createLegacyRoot(container) { | ||
return { | ||
hydrate: function hydrate(element) { | ||
ReactDOM__default['default'].hydrate(element, container); | ||
}, | ||
render: function render(element) { | ||
ReactDOM__default['default'].render(element, container); | ||
}, | ||
unmount: function unmount() { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
} | ||
}; | ||
} | ||
function renderRoot(ui, _ref2) { | ||
var baseElement = _ref2.baseElement, | ||
container = _ref2.container, | ||
hydrate = _ref2.hydrate, | ||
queries = _ref2.queries, | ||
root = _ref2.root, | ||
WrapperComponent = _ref2.wrapper; | ||
var wrapUiIfNeeded = function wrapUiIfNeeded(innerElement) { | ||
@@ -327,5 +372,5 @@ return WrapperComponent ? /*#__PURE__*/React__namespace.createElement(WrapperComponent, null, innerElement) : innerElement; | ||
if (hydrate) { | ||
ReactDOM__default['default'].hydrate(wrapUiIfNeeded(ui), container); | ||
root.hydrate(wrapUiIfNeeded(ui), container); | ||
} else { | ||
ReactDOM__default['default'].render(wrapUiIfNeeded(ui), container); | ||
root.render(wrapUiIfNeeded(ui), container); | ||
} | ||
@@ -349,9 +394,10 @@ }); | ||
act(function () { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
root.unmount(); | ||
}); | ||
}, | ||
rerender: function rerender(rerenderUi) { | ||
render(wrapUiIfNeeded(rerenderUi), { | ||
renderRoot(wrapUiIfNeeded(rerenderUi), { | ||
container: container, | ||
baseElement: baseElement | ||
baseElement: baseElement, | ||
root: root | ||
}); // Intentionally do not return anything to avoid unnecessarily complicating the API. | ||
@@ -373,18 +419,71 @@ // folks can use all the same utilities we return in the first place that are bound to the container | ||
function cleanup() { | ||
mountedContainers.forEach(cleanupAtContainer); | ||
} // maybe one day we'll expose this (perhaps even as a utility returned by render). | ||
// but let's wait until someone asks for it. | ||
function render(ui, _temp) { | ||
var _ref3 = _temp === void 0 ? {} : _temp, | ||
container = _ref3.container, | ||
_ref3$baseElement = _ref3.baseElement, | ||
baseElement = _ref3$baseElement === void 0 ? container : _ref3$baseElement, | ||
_ref3$legacyRoot = _ref3.legacyRoot, | ||
legacyRoot = _ref3$legacyRoot === void 0 ? typeof ReactDOM__default['default'].createRoot !== 'function' : _ref3$legacyRoot, | ||
queries = _ref3.queries, | ||
_ref3$hydrate = _ref3.hydrate, | ||
hydrate = _ref3$hydrate === void 0 ? false : _ref3$hydrate, | ||
wrapper = _ref3.wrapper; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
} | ||
function cleanupAtContainer(container) { | ||
act(function () { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
}); | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
var root; // eslint-disable-next-line no-negated-condition -- we want to map the evolution of this over time. The root is created first. Only later is it re-used so we don't want to read the case that happens later first. | ||
if (!mountedContainers.has(container)) { | ||
var createRootImpl = legacyRoot ? createLegacyRoot : createConcurrentRoot; | ||
root = createRootImpl(container, { | ||
hydrate: hydrate | ||
}); | ||
mountedRootEntries.push({ | ||
container: container, | ||
root: root | ||
}); // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
mountedContainers.add(container); | ||
} else { | ||
mountedRootEntries.forEach(function (rootEntry) { | ||
if (rootEntry.container === container) { | ||
root = rootEntry.root; | ||
} | ||
}); | ||
} | ||
mountedContainers.delete(container); | ||
return renderRoot(ui, { | ||
container: container, | ||
baseElement: baseElement, | ||
queries: queries, | ||
hydrate: hydrate, | ||
wrapper: wrapper, | ||
root: root | ||
}); | ||
} | ||
function cleanup() { | ||
mountedRootEntries.forEach(function (_ref4) { | ||
var root = _ref4.root, | ||
container = _ref4.container; | ||
act(function () { | ||
root.unmount(); | ||
}); | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
} | ||
}); | ||
mountedRootEntries.length = 0; | ||
mountedContainers.clear(); | ||
} // just re-export everything from dom-testing-library | ||
@@ -391,0 +490,0 @@ // thing for people using react-dom@16.8.0. Anyone else doesn't need it and |
@@ -10,4 +10,5 @@ import _extends from '@babel/runtime/helpers/esm/extends'; | ||
var reactAct = testUtils.act; | ||
var actSupported = reactAct !== undefined; // act is supported react-dom@16.8.0 | ||
var isomorphicAct = React.unstable_act; | ||
var domAct = testUtils.act; | ||
var actSupported = domAct !== undefined; // act is supported react-dom@16.8.0 | ||
// so for versions that don't have act from test utils | ||
@@ -22,3 +23,3 @@ // we do this little polyfill. No warnings, but it's | ||
var act = reactAct || actPolyfill; | ||
var act = isomorphicAct || domAct || actPolyfill; | ||
var youHaveBeenWarned = false; | ||
@@ -55,3 +56,3 @@ var isAsyncActSupported = null; | ||
try { | ||
result = reactAct(function () { | ||
result = domAct(function () { | ||
cbReturn = cb(); | ||
@@ -261,29 +262,73 @@ return cbReturn; | ||
}); | ||
if (React.startTransition !== undefined) { | ||
configure({ | ||
unstable_advanceTimersWrapper: function unstable_advanceTimersWrapper(cb) { | ||
return act(cb); | ||
}, | ||
asyncWrapper: function asyncWrapper(cb) { | ||
return cb(); | ||
} | ||
}); | ||
} // Ideally we'd just use a WeakMap where containers are keys and roots are values. | ||
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case) | ||
/** | ||
* @type {Set<import('react-dom').Container>} | ||
*/ | ||
var mountedContainers = new Set(); | ||
/** | ||
* @type Array<{container: import('react-dom').Container, root: ReturnType<typeof createConcurrentRoot>}> | ||
*/ | ||
function render(ui, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
container = _ref2.container, | ||
_ref2$baseElement = _ref2.baseElement, | ||
baseElement = _ref2$baseElement === void 0 ? container : _ref2$baseElement, | ||
queries = _ref2.queries, | ||
_ref2$hydrate = _ref2.hydrate, | ||
hydrate = _ref2$hydrate === void 0 ? false : _ref2$hydrate, | ||
WrapperComponent = _ref2.wrapper; | ||
var mountedRootEntries = []; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
function createConcurrentRoot(container, options) { | ||
if (typeof ReactDOM.createRoot !== 'function') { | ||
throw new TypeError("Attempted to use concurrent React with `react-dom@" + ReactDOM.version + "`. Be sure to use the `next` or `experimental` release channel (https://reactjs.org/docs/release-channels.html).'"); | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
var root = options.hydrate ? ReactDOM.hydrateRoot(container) : ReactDOM.createRoot(container); | ||
return { | ||
hydrate: function hydrate(element) { | ||
/* istanbul ignore if */ | ||
if (!options.hydrate) { | ||
throw new Error('Attempted to hydrate a non-hydrateable root. This is a bug in `@testing-library/react`.'); | ||
} | ||
root.render(element); | ||
}, | ||
render: function render(element) { | ||
root.render(element); | ||
}, | ||
unmount: function unmount() { | ||
root.unmount(); | ||
} | ||
}; | ||
} | ||
mountedContainers.add(container); | ||
function createLegacyRoot(container) { | ||
return { | ||
hydrate: function hydrate(element) { | ||
ReactDOM.hydrate(element, container); | ||
}, | ||
render: function render(element) { | ||
ReactDOM.render(element, container); | ||
}, | ||
unmount: function unmount() { | ||
ReactDOM.unmountComponentAtNode(container); | ||
} | ||
}; | ||
} | ||
function renderRoot(ui, _ref2) { | ||
var baseElement = _ref2.baseElement, | ||
container = _ref2.container, | ||
hydrate = _ref2.hydrate, | ||
queries = _ref2.queries, | ||
root = _ref2.root, | ||
WrapperComponent = _ref2.wrapper; | ||
var wrapUiIfNeeded = function wrapUiIfNeeded(innerElement) { | ||
@@ -295,5 +340,5 @@ return WrapperComponent ? /*#__PURE__*/React.createElement(WrapperComponent, null, innerElement) : innerElement; | ||
if (hydrate) { | ||
ReactDOM.hydrate(wrapUiIfNeeded(ui), container); | ||
root.hydrate(wrapUiIfNeeded(ui), container); | ||
} else { | ||
ReactDOM.render(wrapUiIfNeeded(ui), container); | ||
root.render(wrapUiIfNeeded(ui), container); | ||
} | ||
@@ -317,9 +362,10 @@ }); | ||
act(function () { | ||
ReactDOM.unmountComponentAtNode(container); | ||
root.unmount(); | ||
}); | ||
}, | ||
rerender: function rerender(rerenderUi) { | ||
render(wrapUiIfNeeded(rerenderUi), { | ||
renderRoot(wrapUiIfNeeded(rerenderUi), { | ||
container: container, | ||
baseElement: baseElement | ||
baseElement: baseElement, | ||
root: root | ||
}); // Intentionally do not return anything to avoid unnecessarily complicating the API. | ||
@@ -341,18 +387,71 @@ // folks can use all the same utilities we return in the first place that are bound to the container | ||
function cleanup() { | ||
mountedContainers.forEach(cleanupAtContainer); | ||
} // maybe one day we'll expose this (perhaps even as a utility returned by render). | ||
// but let's wait until someone asks for it. | ||
function render(ui, _temp) { | ||
var _ref3 = _temp === void 0 ? {} : _temp, | ||
container = _ref3.container, | ||
_ref3$baseElement = _ref3.baseElement, | ||
baseElement = _ref3$baseElement === void 0 ? container : _ref3$baseElement, | ||
_ref3$legacyRoot = _ref3.legacyRoot, | ||
legacyRoot = _ref3$legacyRoot === void 0 ? typeof ReactDOM.createRoot !== 'function' : _ref3$legacyRoot, | ||
queries = _ref3.queries, | ||
_ref3$hydrate = _ref3.hydrate, | ||
hydrate = _ref3$hydrate === void 0 ? false : _ref3$hydrate, | ||
wrapper = _ref3.wrapper; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
} | ||
function cleanupAtContainer(container) { | ||
act(function () { | ||
ReactDOM.unmountComponentAtNode(container); | ||
}); | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
var root; // eslint-disable-next-line no-negated-condition -- we want to map the evolution of this over time. The root is created first. Only later is it re-used so we don't want to read the case that happens later first. | ||
if (!mountedContainers.has(container)) { | ||
var createRootImpl = legacyRoot ? createLegacyRoot : createConcurrentRoot; | ||
root = createRootImpl(container, { | ||
hydrate: hydrate | ||
}); | ||
mountedRootEntries.push({ | ||
container: container, | ||
root: root | ||
}); // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
mountedContainers.add(container); | ||
} else { | ||
mountedRootEntries.forEach(function (rootEntry) { | ||
if (rootEntry.container === container) { | ||
root = rootEntry.root; | ||
} | ||
}); | ||
} | ||
mountedContainers.delete(container); | ||
return renderRoot(ui, { | ||
container: container, | ||
baseElement: baseElement, | ||
queries: queries, | ||
hydrate: hydrate, | ||
wrapper: wrapper, | ||
root: root | ||
}); | ||
} | ||
function cleanup() { | ||
mountedRootEntries.forEach(function (_ref4) { | ||
var root = _ref4.root, | ||
container = _ref4.container; | ||
act(function () { | ||
root.unmount(); | ||
}); | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
} | ||
}); | ||
mountedRootEntries.length = 0; | ||
mountedContainers.clear(); | ||
} // just re-export everything from dom-testing-library | ||
@@ -359,0 +458,0 @@ // thing for people using react-dom@16.8.0. Anyone else doesn't need it and |
@@ -42,4 +42,5 @@ 'use strict'; | ||
var reactAct = testUtils__namespace.act; | ||
var actSupported = reactAct !== undefined; // act is supported react-dom@16.8.0 | ||
var isomorphicAct = React__namespace.unstable_act; | ||
var domAct = testUtils__namespace.act; | ||
var actSupported = domAct !== undefined; // act is supported react-dom@16.8.0 | ||
// so for versions that don't have act from test utils | ||
@@ -54,3 +55,3 @@ // we do this little polyfill. No warnings, but it's | ||
var act = reactAct || actPolyfill; | ||
var act = isomorphicAct || domAct || actPolyfill; | ||
var youHaveBeenWarned = false; | ||
@@ -87,3 +88,3 @@ var isAsyncActSupported = null; | ||
try { | ||
result = reactAct(function () { | ||
result = domAct(function () { | ||
cbReturn = cb(); | ||
@@ -293,29 +294,73 @@ return cbReturn; | ||
}); | ||
if (React__namespace.startTransition !== undefined) { | ||
dom.configure({ | ||
unstable_advanceTimersWrapper: function unstable_advanceTimersWrapper(cb) { | ||
return act(cb); | ||
}, | ||
asyncWrapper: function asyncWrapper(cb) { | ||
return cb(); | ||
} | ||
}); | ||
} // Ideally we'd just use a WeakMap where containers are keys and roots are values. | ||
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case) | ||
/** | ||
* @type {Set<import('react-dom').Container>} | ||
*/ | ||
var mountedContainers = new Set(); | ||
/** | ||
* @type Array<{container: import('react-dom').Container, root: ReturnType<typeof createConcurrentRoot>}> | ||
*/ | ||
function render(ui, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
container = _ref2.container, | ||
_ref2$baseElement = _ref2.baseElement, | ||
baseElement = _ref2$baseElement === void 0 ? container : _ref2$baseElement, | ||
queries = _ref2.queries, | ||
_ref2$hydrate = _ref2.hydrate, | ||
hydrate = _ref2$hydrate === void 0 ? false : _ref2$hydrate, | ||
WrapperComponent = _ref2.wrapper; | ||
var mountedRootEntries = []; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
function createConcurrentRoot(container, options) { | ||
if (typeof ReactDOM__default['default'].createRoot !== 'function') { | ||
throw new TypeError("Attempted to use concurrent React with `react-dom@" + ReactDOM__default['default'].version + "`. Be sure to use the `next` or `experimental` release channel (https://reactjs.org/docs/release-channels.html).'"); | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
var root = options.hydrate ? ReactDOM__default['default'].hydrateRoot(container) : ReactDOM__default['default'].createRoot(container); | ||
return { | ||
hydrate: function hydrate(element) { | ||
/* istanbul ignore if */ | ||
if (!options.hydrate) { | ||
throw new Error('Attempted to hydrate a non-hydrateable root. This is a bug in `@testing-library/react`.'); | ||
} | ||
root.render(element); | ||
}, | ||
render: function render(element) { | ||
root.render(element); | ||
}, | ||
unmount: function unmount() { | ||
root.unmount(); | ||
} | ||
}; | ||
} | ||
mountedContainers.add(container); | ||
function createLegacyRoot(container) { | ||
return { | ||
hydrate: function hydrate(element) { | ||
ReactDOM__default['default'].hydrate(element, container); | ||
}, | ||
render: function render(element) { | ||
ReactDOM__default['default'].render(element, container); | ||
}, | ||
unmount: function unmount() { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
} | ||
}; | ||
} | ||
function renderRoot(ui, _ref2) { | ||
var baseElement = _ref2.baseElement, | ||
container = _ref2.container, | ||
hydrate = _ref2.hydrate, | ||
queries = _ref2.queries, | ||
root = _ref2.root, | ||
WrapperComponent = _ref2.wrapper; | ||
var wrapUiIfNeeded = function wrapUiIfNeeded(innerElement) { | ||
@@ -327,5 +372,5 @@ return WrapperComponent ? /*#__PURE__*/React__namespace.createElement(WrapperComponent, null, innerElement) : innerElement; | ||
if (hydrate) { | ||
ReactDOM__default['default'].hydrate(wrapUiIfNeeded(ui), container); | ||
root.hydrate(wrapUiIfNeeded(ui), container); | ||
} else { | ||
ReactDOM__default['default'].render(wrapUiIfNeeded(ui), container); | ||
root.render(wrapUiIfNeeded(ui), container); | ||
} | ||
@@ -349,9 +394,10 @@ }); | ||
act(function () { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
root.unmount(); | ||
}); | ||
}, | ||
rerender: function rerender(rerenderUi) { | ||
render(wrapUiIfNeeded(rerenderUi), { | ||
renderRoot(wrapUiIfNeeded(rerenderUi), { | ||
container: container, | ||
baseElement: baseElement | ||
baseElement: baseElement, | ||
root: root | ||
}); // Intentionally do not return anything to avoid unnecessarily complicating the API. | ||
@@ -373,18 +419,71 @@ // folks can use all the same utilities we return in the first place that are bound to the container | ||
function cleanup() { | ||
mountedContainers.forEach(cleanupAtContainer); | ||
} // maybe one day we'll expose this (perhaps even as a utility returned by render). | ||
// but let's wait until someone asks for it. | ||
function render(ui, _temp) { | ||
var _ref3 = _temp === void 0 ? {} : _temp, | ||
container = _ref3.container, | ||
_ref3$baseElement = _ref3.baseElement, | ||
baseElement = _ref3$baseElement === void 0 ? container : _ref3$baseElement, | ||
_ref3$legacyRoot = _ref3.legacyRoot, | ||
legacyRoot = _ref3$legacyRoot === void 0 ? typeof ReactDOM__default['default'].createRoot !== 'function' : _ref3$legacyRoot, | ||
queries = _ref3.queries, | ||
_ref3$hydrate = _ref3.hydrate, | ||
hydrate = _ref3$hydrate === void 0 ? false : _ref3$hydrate, | ||
wrapper = _ref3.wrapper; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
} | ||
function cleanupAtContainer(container) { | ||
act(function () { | ||
ReactDOM__default['default'].unmountComponentAtNode(container); | ||
}); | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
var root; // eslint-disable-next-line no-negated-condition -- we want to map the evolution of this over time. The root is created first. Only later is it re-used so we don't want to read the case that happens later first. | ||
if (!mountedContainers.has(container)) { | ||
var createRootImpl = legacyRoot ? createLegacyRoot : createConcurrentRoot; | ||
root = createRootImpl(container, { | ||
hydrate: hydrate | ||
}); | ||
mountedRootEntries.push({ | ||
container: container, | ||
root: root | ||
}); // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
mountedContainers.add(container); | ||
} else { | ||
mountedRootEntries.forEach(function (rootEntry) { | ||
if (rootEntry.container === container) { | ||
root = rootEntry.root; | ||
} | ||
}); | ||
} | ||
mountedContainers.delete(container); | ||
return renderRoot(ui, { | ||
container: container, | ||
baseElement: baseElement, | ||
queries: queries, | ||
hydrate: hydrate, | ||
wrapper: wrapper, | ||
root: root | ||
}); | ||
} | ||
function cleanup() { | ||
mountedRootEntries.forEach(function (_ref4) { | ||
var root = _ref4.root, | ||
container = _ref4.container; | ||
act(function () { | ||
root.unmount(); | ||
}); | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
} | ||
}); | ||
mountedRootEntries.length = 0; | ||
mountedContainers.clear(); | ||
} // just re-export everything from dom-testing-library | ||
@@ -391,0 +490,0 @@ // thing for people using react-dom@16.8.0. Anyone else doesn't need it and |
@@ -10,4 +10,5 @@ import _extends from '@babel/runtime/helpers/esm/extends'; | ||
var reactAct = testUtils.act; | ||
var actSupported = reactAct !== undefined; // act is supported react-dom@16.8.0 | ||
var isomorphicAct = React.unstable_act; | ||
var domAct = testUtils.act; | ||
var actSupported = domAct !== undefined; // act is supported react-dom@16.8.0 | ||
// so for versions that don't have act from test utils | ||
@@ -22,3 +23,3 @@ // we do this little polyfill. No warnings, but it's | ||
var act = reactAct || actPolyfill; | ||
var act = isomorphicAct || domAct || actPolyfill; | ||
var youHaveBeenWarned = false; | ||
@@ -55,3 +56,3 @@ var isAsyncActSupported = null; | ||
try { | ||
result = reactAct(function () { | ||
result = domAct(function () { | ||
cbReturn = cb(); | ||
@@ -261,29 +262,73 @@ return cbReturn; | ||
}); | ||
if (React.startTransition !== undefined) { | ||
configure({ | ||
unstable_advanceTimersWrapper: function unstable_advanceTimersWrapper(cb) { | ||
return act(cb); | ||
}, | ||
asyncWrapper: function asyncWrapper(cb) { | ||
return cb(); | ||
} | ||
}); | ||
} // Ideally we'd just use a WeakMap where containers are keys and roots are values. | ||
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case) | ||
/** | ||
* @type {Set<import('react-dom').Container>} | ||
*/ | ||
var mountedContainers = new Set(); | ||
/** | ||
* @type Array<{container: import('react-dom').Container, root: ReturnType<typeof createConcurrentRoot>}> | ||
*/ | ||
function render(ui, _temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
container = _ref2.container, | ||
_ref2$baseElement = _ref2.baseElement, | ||
baseElement = _ref2$baseElement === void 0 ? container : _ref2$baseElement, | ||
queries = _ref2.queries, | ||
_ref2$hydrate = _ref2.hydrate, | ||
hydrate = _ref2$hydrate === void 0 ? false : _ref2$hydrate, | ||
WrapperComponent = _ref2.wrapper; | ||
var mountedRootEntries = []; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
function createConcurrentRoot(container, options) { | ||
if (typeof ReactDOM.createRoot !== 'function') { | ||
throw new TypeError("Attempted to use concurrent React with `react-dom@" + ReactDOM.version + "`. Be sure to use the `next` or `experimental` release channel (https://reactjs.org/docs/release-channels.html).'"); | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
var root = options.hydrate ? ReactDOM.hydrateRoot(container) : ReactDOM.createRoot(container); | ||
return { | ||
hydrate: function hydrate(element) { | ||
/* istanbul ignore if */ | ||
if (!options.hydrate) { | ||
throw new Error('Attempted to hydrate a non-hydrateable root. This is a bug in `@testing-library/react`.'); | ||
} | ||
root.render(element); | ||
}, | ||
render: function render(element) { | ||
root.render(element); | ||
}, | ||
unmount: function unmount() { | ||
root.unmount(); | ||
} | ||
}; | ||
} | ||
mountedContainers.add(container); | ||
function createLegacyRoot(container) { | ||
return { | ||
hydrate: function hydrate(element) { | ||
ReactDOM.hydrate(element, container); | ||
}, | ||
render: function render(element) { | ||
ReactDOM.render(element, container); | ||
}, | ||
unmount: function unmount() { | ||
ReactDOM.unmountComponentAtNode(container); | ||
} | ||
}; | ||
} | ||
function renderRoot(ui, _ref2) { | ||
var baseElement = _ref2.baseElement, | ||
container = _ref2.container, | ||
hydrate = _ref2.hydrate, | ||
queries = _ref2.queries, | ||
root = _ref2.root, | ||
WrapperComponent = _ref2.wrapper; | ||
var wrapUiIfNeeded = function wrapUiIfNeeded(innerElement) { | ||
@@ -295,5 +340,5 @@ return WrapperComponent ? /*#__PURE__*/React.createElement(WrapperComponent, null, innerElement) : innerElement; | ||
if (hydrate) { | ||
ReactDOM.hydrate(wrapUiIfNeeded(ui), container); | ||
root.hydrate(wrapUiIfNeeded(ui), container); | ||
} else { | ||
ReactDOM.render(wrapUiIfNeeded(ui), container); | ||
root.render(wrapUiIfNeeded(ui), container); | ||
} | ||
@@ -317,9 +362,10 @@ }); | ||
act(function () { | ||
ReactDOM.unmountComponentAtNode(container); | ||
root.unmount(); | ||
}); | ||
}, | ||
rerender: function rerender(rerenderUi) { | ||
render(wrapUiIfNeeded(rerenderUi), { | ||
renderRoot(wrapUiIfNeeded(rerenderUi), { | ||
container: container, | ||
baseElement: baseElement | ||
baseElement: baseElement, | ||
root: root | ||
}); // Intentionally do not return anything to avoid unnecessarily complicating the API. | ||
@@ -341,18 +387,71 @@ // folks can use all the same utilities we return in the first place that are bound to the container | ||
function cleanup() { | ||
mountedContainers.forEach(cleanupAtContainer); | ||
} // maybe one day we'll expose this (perhaps even as a utility returned by render). | ||
// but let's wait until someone asks for it. | ||
function render(ui, _temp) { | ||
var _ref3 = _temp === void 0 ? {} : _temp, | ||
container = _ref3.container, | ||
_ref3$baseElement = _ref3.baseElement, | ||
baseElement = _ref3$baseElement === void 0 ? container : _ref3$baseElement, | ||
_ref3$legacyRoot = _ref3.legacyRoot, | ||
legacyRoot = _ref3$legacyRoot === void 0 ? typeof ReactDOM.createRoot !== 'function' : _ref3$legacyRoot, | ||
queries = _ref3.queries, | ||
_ref3$hydrate = _ref3.hydrate, | ||
hydrate = _ref3$hydrate === void 0 ? false : _ref3$hydrate, | ||
wrapper = _ref3.wrapper; | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
} | ||
function cleanupAtContainer(container) { | ||
act(function () { | ||
ReactDOM.unmountComponentAtNode(container); | ||
}); | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
var root; // eslint-disable-next-line no-negated-condition -- we want to map the evolution of this over time. The root is created first. Only later is it re-used so we don't want to read the case that happens later first. | ||
if (!mountedContainers.has(container)) { | ||
var createRootImpl = legacyRoot ? createLegacyRoot : createConcurrentRoot; | ||
root = createRootImpl(container, { | ||
hydrate: hydrate | ||
}); | ||
mountedRootEntries.push({ | ||
container: container, | ||
root: root | ||
}); // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
mountedContainers.add(container); | ||
} else { | ||
mountedRootEntries.forEach(function (rootEntry) { | ||
if (rootEntry.container === container) { | ||
root = rootEntry.root; | ||
} | ||
}); | ||
} | ||
mountedContainers.delete(container); | ||
return renderRoot(ui, { | ||
container: container, | ||
baseElement: baseElement, | ||
queries: queries, | ||
hydrate: hydrate, | ||
wrapper: wrapper, | ||
root: root | ||
}); | ||
} | ||
function cleanup() { | ||
mountedRootEntries.forEach(function (_ref4) { | ||
var root = _ref4.root, | ||
container = _ref4.container; | ||
act(function () { | ||
root.unmount(); | ||
}); | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
} | ||
}); | ||
mountedRootEntries.length = 0; | ||
mountedContainers.clear(); | ||
} // just re-export everything from dom-testing-library | ||
@@ -359,0 +458,0 @@ // thing for people using react-dom@16.8.0. Anyone else doesn't need it and |
@@ -21,4 +21,5 @@ "use strict"; | ||
const reactAct = testUtils.act; | ||
const actSupported = reactAct !== undefined; // act is supported react-dom@16.8.0 | ||
const isomorphicAct = React.unstable_act; | ||
const domAct = testUtils.act; | ||
const actSupported = domAct !== undefined; // act is supported react-dom@16.8.0 | ||
// so for versions that don't have act from test utils | ||
@@ -34,3 +35,3 @@ // we do this little polyfill. No warnings, but it's | ||
const act = reactAct || actPolyfill; | ||
const act = isomorphicAct || domAct || actPolyfill; | ||
let youHaveBeenWarned = false; | ||
@@ -64,3 +65,3 @@ let isAsyncActSupported = null; | ||
try { | ||
result = reactAct(() => { | ||
result = domAct(() => { | ||
cbReturn = cb(); | ||
@@ -67,0 +68,0 @@ return cbReturn; |
168
dist/pure.js
@@ -71,26 +71,77 @@ "use strict"; | ||
}); | ||
if (React.startTransition !== undefined) { | ||
(0, _dom.configure)({ | ||
unstable_advanceTimersWrapper: cb => { | ||
return (0, _actCompat.default)(cb); | ||
}, | ||
asyncWrapper: cb => cb() | ||
}); | ||
} // Ideally we'd just use a WeakMap where containers are keys and roots are values. | ||
// We use two variables so that we can bail out in constant time when we render with a new container (most common use case) | ||
/** | ||
* @type {Set<import('react-dom').Container>} | ||
*/ | ||
const mountedContainers = new Set(); | ||
/** | ||
* @type Array<{container: import('react-dom').Container, root: ReturnType<typeof createConcurrentRoot>}> | ||
*/ | ||
function render(ui, { | ||
container, | ||
baseElement = container, | ||
queries, | ||
hydrate = false, | ||
wrapper: WrapperComponent | ||
} = {}) { | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
const mountedRootEntries = []; | ||
function createConcurrentRoot(container, options) { | ||
if (typeof _reactDom.default.createRoot !== 'function') { | ||
throw new TypeError(`Attempted to use concurrent React with \`react-dom@${_reactDom.default.version}\`. Be sure to use the \`next\` or \`experimental\` release channel (https://reactjs.org/docs/release-channels.html).'`); | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
const root = options.hydrate ? _reactDom.default.hydrateRoot(container) : _reactDom.default.createRoot(container); | ||
return { | ||
hydrate(element) { | ||
/* istanbul ignore if */ | ||
if (!options.hydrate) { | ||
throw new Error('Attempted to hydrate a non-hydrateable root. This is a bug in `@testing-library/react`.'); | ||
} | ||
root.render(element); | ||
}, | ||
mountedContainers.add(container); | ||
render(element) { | ||
root.render(element); | ||
}, | ||
unmount() { | ||
root.unmount(); | ||
} | ||
}; | ||
} | ||
function createLegacyRoot(container) { | ||
return { | ||
hydrate(element) { | ||
_reactDom.default.hydrate(element, container); | ||
}, | ||
render(element) { | ||
_reactDom.default.render(element, container); | ||
}, | ||
unmount() { | ||
_reactDom.default.unmountComponentAtNode(container); | ||
} | ||
}; | ||
} | ||
function renderRoot(ui, { | ||
baseElement, | ||
container, | ||
hydrate, | ||
queries, | ||
root, | ||
wrapper: WrapperComponent | ||
}) { | ||
const wrapUiIfNeeded = innerElement => WrapperComponent ? /*#__PURE__*/React.createElement(WrapperComponent, null, innerElement) : innerElement; | ||
@@ -100,5 +151,5 @@ | ||
if (hydrate) { | ||
_reactDom.default.hydrate(wrapUiIfNeeded(ui), container); | ||
root.hydrate(wrapUiIfNeeded(ui), container); | ||
} else { | ||
_reactDom.default.render(wrapUiIfNeeded(ui), container); | ||
root.render(wrapUiIfNeeded(ui), container); | ||
} | ||
@@ -114,9 +165,10 @@ }); | ||
(0, _actCompat.default)(() => { | ||
_reactDom.default.unmountComponentAtNode(container); | ||
root.unmount(); | ||
}); | ||
}, | ||
rerender: rerenderUi => { | ||
render(wrapUiIfNeeded(rerenderUi), { | ||
renderRoot(wrapUiIfNeeded(rerenderUi), { | ||
container, | ||
baseElement | ||
baseElement, | ||
root | ||
}); // Intentionally do not return anything to avoid unnecessarily complicating the API. | ||
@@ -139,18 +191,68 @@ // folks can use all the same utilities we return in the first place that are bound to the container | ||
function cleanup() { | ||
mountedContainers.forEach(cleanupAtContainer); | ||
} // maybe one day we'll expose this (perhaps even as a utility returned by render). | ||
// but let's wait until someone asks for it. | ||
function render(ui, { | ||
container, | ||
baseElement = container, | ||
legacyRoot = typeof _reactDom.default.createRoot !== 'function', | ||
queries, | ||
hydrate = false, | ||
wrapper | ||
} = {}) { | ||
if (!baseElement) { | ||
// default to document.body instead of documentElement to avoid output of potentially-large | ||
// head elements (such as JSS style blocks) in debug output | ||
baseElement = document.body; | ||
} | ||
if (!container) { | ||
container = baseElement.appendChild(document.createElement('div')); | ||
} | ||
function cleanupAtContainer(container) { | ||
(0, _actCompat.default)(() => { | ||
_reactDom.default.unmountComponentAtNode(container); | ||
}); | ||
let root; // eslint-disable-next-line no-negated-condition -- we want to map the evolution of this over time. The root is created first. Only later is it re-used so we don't want to read the case that happens later first. | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
if (!mountedContainers.has(container)) { | ||
const createRootImpl = legacyRoot ? createLegacyRoot : createConcurrentRoot; | ||
root = createRootImpl(container, { | ||
hydrate | ||
}); | ||
mountedRootEntries.push({ | ||
container, | ||
root | ||
}); // we'll add it to the mounted containers regardless of whether it's actually | ||
// added to document.body so the cleanup method works regardless of whether | ||
// they're passing us a custom container or not. | ||
mountedContainers.add(container); | ||
} else { | ||
mountedRootEntries.forEach(rootEntry => { | ||
if (rootEntry.container === container) { | ||
root = rootEntry.root; | ||
} | ||
}); | ||
} | ||
mountedContainers.delete(container); | ||
return renderRoot(ui, { | ||
container, | ||
baseElement, | ||
queries, | ||
hydrate, | ||
wrapper, | ||
root | ||
}); | ||
} | ||
function cleanup() { | ||
mountedRootEntries.forEach(({ | ||
root, | ||
container | ||
}) => { | ||
(0, _actCompat.default)(() => { | ||
root.unmount(); | ||
}); | ||
if (container.parentNode === document.body) { | ||
document.body.removeChild(container); | ||
} | ||
}); | ||
mountedRootEntries.length = 0; | ||
mountedContainers.clear(); | ||
} // just re-export everything from dom-testing-library | ||
@@ -157,0 +259,0 @@ // NOTE: we're not going to export asyncAct because that's our own compatibility |
{ | ||
"name": "@testing-library/react", | ||
"version": "12.1.0", | ||
"version": "13.0.0-alpha.1", | ||
"description": "Simple and complete React DOM testing utilities that encourage good testing practices.", | ||
@@ -48,3 +48,3 @@ "main": "dist/index.js", | ||
"@babel/runtime": "^7.12.5", | ||
"@testing-library/dom": "^8.0.0" | ||
"@testing-library/dom": "^8.5.0" | ||
}, | ||
@@ -51,0 +51,0 @@ "devDependencies": { |
@@ -62,2 +62,7 @@ // TypeScript Version: 3.8 | ||
/** | ||
* Set to `true` if you want to force synchronous `ReactDOM.render`. | ||
* Otherwise `render` will default to concurrent React if available. | ||
*/ | ||
legacyRoot?: boolean | ||
/** | ||
* Queries to bind. Overrides the default set from DOM Testing Library unless merged. | ||
@@ -64,0 +69,0 @@ * |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5476613
34289
3
Updated@testing-library/dom@^8.5.0