(refInst = ref)} />,
+ {createNodeMock},
+ );
+ });
+
const root = renderer.getInstance();
expect(root).toEqual(refInst);
});
- it('toTree() renders complicated trees of composites and hosts', () => {
+ it('toTree() renders complicated trees of composites and hosts', async () => {
// SFC returning host. no children props.
const Qoo = () =>
;
@@ -823,7 +926,11 @@ describe('ReactTestRenderer', () => {
}
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
+
const tree = renderer.toTree();
// we test for the presence of instances before nulling them out
@@ -882,30 +989,45 @@ describe('ReactTestRenderer', () => {
);
});
- it('can update text nodes when rendered as root', () => {
- const renderer = ReactTestRenderer.create(['Hello', 'world']);
+ it('can update text nodes when rendered as root', async () => {
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(['Hello', 'world']);
+ });
expect(renderer.toJSON()).toEqual(['Hello', 'world']);
- renderer.update(42);
+ await act(() => {
+ renderer.update(42);
+ });
expect(renderer.toJSON()).toEqual('42');
- renderer.update([42, 'world']);
+ await act(() => {
+ renderer.update([42, 'world']);
+ });
expect(renderer.toJSON()).toEqual(['42', 'world']);
});
- it('can render and update root fragments', () => {
+ it('can render and update root fragments', async () => {
const Component = props => props.children;
- const renderer = ReactTestRenderer.create([
-
,
- ]);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create([
+
,
+ ]);
+ });
+
expect(renderer.toJSON()).toEqual(['Hi', 'Bye']);
- renderer.update(
);
+ });
expect(renderer.toJSON()).toEqual({
type: 'div',
children: null,
props: {},
});
- renderer.update([
, 'world']);
+ });
expect(renderer.toJSON()).toEqual([
{
type: 'div',
@@ -916,7 +1038,7 @@ describe('ReactTestRenderer', () => {
]);
});
- it('supports context providers and consumers', () => {
+ it('supports context providers and consumers', async () => {
const {Consumer, Provider} = React.createContext('a');
function Child(props) {
@@ -931,7 +1053,10 @@ describe('ReactTestRenderer', () => {
);
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const child = renderer.root.findByType(Child);
expect(child.children).toEqual(['b']);
expect(prettyFormat(renderer.toTree())).toEqual(
@@ -953,7 +1078,7 @@ describe('ReactTestRenderer', () => {
);
});
- it('supports modes', () => {
+ it('supports modes', async () => {
function Child(props) {
return props.value;
}
@@ -966,7 +1091,10 @@ describe('ReactTestRenderer', () => {
);
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const child = renderer.root.findByType(Child);
expect(child.children).toEqual(['a']);
expect(prettyFormat(renderer.toTree())).toEqual(
@@ -990,7 +1118,7 @@ describe('ReactTestRenderer', () => {
);
});
- it('supports forwardRef', () => {
+ it('supports forwardRef', async () => {
const InnerRefed = React.forwardRef((props, ref) => (
@@ -1008,7 +1136,10 @@ describe('ReactTestRenderer', () => {
}
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const tree = renderer.toTree();
cleanNodeOrArray(tree);
@@ -1053,12 +1184,17 @@ describe('ReactTestRenderer', () => {
);
ReactNoop.render(
);
await waitForAll([]);
- ReactTestRenderer.create(
);
+ await act(() => {
+ ReactTestRenderer.create(
);
+ });
});
- it('calling findByType() with an invalid component will fall back to "Unknown" for component name', () => {
+ it('calling findByType() with an invalid component will fall back to "Unknown" for component name', async () => {
const App = () => null;
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const NonComponent = {};
expect(() => {
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
index 0118fa53f3ad3..e6ed9fa11c291 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
@@ -13,7 +13,7 @@ let ReactDOM;
let React;
let ReactCache;
let ReactTestRenderer;
-let waitForAll;
+let act;
describe('ReactTestRenderer', () => {
beforeEach(() => {
@@ -26,32 +26,28 @@ describe('ReactTestRenderer', () => {
ReactCache = require('react-cache');
ReactTestRenderer = require('react-test-renderer');
const InternalTestUtils = require('internal-test-utils');
- waitForAll = InternalTestUtils.waitForAll;
+ act = InternalTestUtils.act;
});
- it('should warn if used to render a ReactDOM portal', () => {
+ it('should warn if used to render a ReactDOM portal', async () => {
const container = document.createElement('div');
- expect(() => {
- let error;
- try {
+ let error;
+
+ await expect(async () => {
+ await act(() => {
ReactTestRenderer.create(ReactDOM.createPortal('foo', container));
- } catch (e) {
- error = e;
- }
- // After the update throws, a subsequent render is scheduled to
- // unmount the whole tree. This update also causes an error, so React
- // throws an AggregateError.
- const errors = error.errors;
- expect(errors.length).toBe(2);
- expect(errors[0].message.includes('indexOf is not a function')).toBe(
- true,
- );
- expect(errors[1].message.includes('indexOf is not a function')).toBe(
- true,
- );
+ }).catch(e => (error = e));
}).toErrorDev('An invalid container has been provided.', {
withoutStack: true,
});
+
+ // After the update throws, a subsequent render is scheduled to
+ // unmount the whole tree. This update also causes an error, so React
+ // throws an AggregateError.
+ const errors = error.errors;
+ expect(errors.length).toBe(2);
+ expect(errors[0].message.includes('indexOf is not a function')).toBe(true);
+ expect(errors[1].message.includes('indexOf is not a function')).toBe(true);
});
describe('timed out Suspense hidden subtrees should not be observable via toJSON', () => {
@@ -84,16 +80,23 @@ describe('ReactTestRenderer', () => {
);
};
- const root = ReactTestRenderer.create(
);
- PendingResources.initial('initial');
- await waitForAll([]);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(
);
+ });
+ await act(() => {
+ PendingResources.initial('initial');
+ });
expect(root.toJSON()).toEqual('initial');
- root.update(
);
+ await act(() => {
+ root.update(
);
+ });
expect(root.toJSON()).toEqual('fallback');
- PendingResources.dynamic('dynamic');
- await waitForAll([]);
+ await act(() => {
+ PendingResources.dynamic('dynamic');
+ });
expect(root.toJSON()).toEqual('dynamic');
});
@@ -108,16 +111,23 @@ describe('ReactTestRenderer', () => {
);
};
- const root = ReactTestRenderer.create(
);
- PendingResources.initial('initial');
- await waitForAll([]);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(
);
+ });
+ await act(() => {
+ PendingResources.initial('initial');
+ });
expect(root.toJSON().children).toEqual(['initial']);
- root.update(
);
+ await act(() => {
+ root.update(
);
+ });
expect(root.toJSON().children).toEqual(['fallback']);
- PendingResources.dynamic('dynamic');
- await waitForAll([]);
+ await act(() => {
+ PendingResources.dynamic('dynamic');
+ });
expect(root.toJSON().children).toEqual(['dynamic']);
});
});
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
index 2306a895b785c..ef27de6d0fe2f 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
@@ -16,6 +16,7 @@ describe('ReactTestRenderer.act()', () => {
const InternalTestUtils = require('internal-test-utils');
assertLog = InternalTestUtils.assertLog;
+ global.IS_REACT_ACT_ENVIRONMENT = true;
});
// @gate __DEV__
@@ -91,7 +92,10 @@ describe('ReactTestRenderer.act()', () => {
});
return step;
}
- const root = ReactTestRenderer.create(null);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(null);
+ });
await act(async () => {
root.update(
);
});
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js
index 51c7e0a950ddc..468f62d39a722 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js
@@ -34,7 +34,7 @@ describe('ReactTestRendererAsync', () => {
return props.children;
}
const renderer = ReactTestRenderer.create(
Hi, {
- isConcurrent: true,
+ unstable_isConcurrent: true,
});
// Before flushing, nothing has mounted.
@@ -68,7 +68,7 @@ describe('ReactTestRendererAsync', () => {
);
}
const renderer = ReactTestRenderer.create(
, {
- isConcurrent: true,
+ unstable_isConcurrent: true,
});
await waitForAll(['A:1', 'B:1', 'C:1']);
@@ -97,7 +97,7 @@ describe('ReactTestRendererAsync', () => {
let renderer;
React.startTransition(() => {
renderer = ReactTestRenderer.create(
, {
- isConcurrent: true,
+ unstable_isConcurrent: true,
});
});
@@ -137,7 +137,7 @@ describe('ReactTestRendererAsync', () => {
let renderer;
React.startTransition(() => {
renderer = ReactTestRenderer.create(
, {
- isConcurrent: true,
+ unstable_isConcurrent: true,
});
});
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
index d61f0a7c9075a..b4f79d2c55f19 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
@@ -13,6 +13,7 @@
const React = require('react');
let ReactTestRenderer;
let Context;
+let act;
const RCTView = 'RCTView';
const View = props =>
;
@@ -21,6 +22,7 @@ describe('ReactTestRendererTraversal', () => {
beforeEach(() => {
jest.resetModules();
ReactTestRenderer = require('react-test-renderer');
+ act = require('internal-test-utils').act;
Context = React.createContext(null);
});
@@ -68,8 +70,11 @@ describe('ReactTestRendererTraversal', () => {
));
- it('initializes', () => {
- const render = ReactTestRenderer.create(
);
+ it('initializes', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
const hasFooProp = node => node.props.hasOwnProperty('foo');
// assert .props, .type and .parent attributes
@@ -80,8 +85,12 @@ describe('ReactTestRendererTraversal', () => {
expect(foo.children[0].parent).toBe(foo);
});
- it('searches via .find() / .findAll()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .find() / .findAll()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
+
const hasFooProp = node => node.props.hasOwnProperty('foo');
const hasBarProp = node => node.props.hasOwnProperty('bar');
const hasBazProp = node => node.props.hasOwnProperty('baz');
@@ -135,8 +144,11 @@ describe('ReactTestRendererTraversal', () => {
expect(itself.findAll(hasBazProp)).toHaveLength(2);
});
- it('searches via .findByType() / .findAllByType()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .findByType() / .findAllByType()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
expect(() => render.root.findByType(ExampleFn)).not.toThrow(); // 1 match
expect(() => render.root.findByType(View)).not.toThrow(); // 1 match
@@ -159,8 +171,11 @@ describe('ReactTestRendererTraversal', () => {
expect(fn[0].findAllByType(View)).toHaveLength(1);
});
- it('searches via .findByProps() / .findAllByProps()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .findByProps() / .findAllByProps()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
const foo = 'foo';
const bar = 'bar';
const baz = 'baz';
@@ -182,8 +197,11 @@ describe('ReactTestRendererTraversal', () => {
expect(render.root.findAllByProps({qux})).toHaveLength(3);
});
- it('skips special nodes', () => {
- const render = ReactTestRenderer.create(
);
+ it('skips special nodes', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
expect(render.root.findAllByType(React.Fragment)).toHaveLength(0);
expect(render.root.findAllByType(Context.Consumer)).toHaveLength(0);
expect(render.root.findAllByType(Context.Provider)).toHaveLength(0);
@@ -200,47 +218,62 @@ describe('ReactTestRendererTraversal', () => {
expect(nestedViews[2].parent).toBe(expectedParent);
});
- it('can have special nodes as roots', () => {
+ it('can have special nodes as roots', async () => {
const FR = React.forwardRef((props, ref) =>
);
- expect(
- ReactTestRenderer.create(
+
+ let render1;
+ await act(() => {
+ render1 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render1.root.findAllByType('div').length).toBe(2);
+
+ let render2;
+ await act(() => {
+ render2 = ReactTestRenderer.create(
<>
>,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render2.root.findAllByType('div').length).toBe(2);
+
+ let render3;
+ await act(() => {
+ render3 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render3.root.findAllByType('div').length).toBe(2);
+
+ let render4;
+ await act(() => {
+ render4 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render4.root.findAllByType('div').length).toBe(2);
+
+ let render5;
+ await act(() => {
+ render5 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
+ );
+ });
+ expect(render5.root.findAllByType('div').length).toBe(2);
});
});
diff --git a/packages/react/src/__tests__/ReactProfiler-test.internal.js b/packages/react/src/__tests__/ReactProfiler-test.internal.js
index fd42561393101..0762c901cb2e2 100644
--- a/packages/react/src/__tests__/ReactProfiler-test.internal.js
+++ b/packages/react/src/__tests__/ReactProfiler-test.internal.js
@@ -40,6 +40,7 @@ function loadModules({
enableProfilerNestedUpdateScheduledHook;
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback =
replayFailedUnitOfWorkWithInvokeGuardedCallback;
+ ReactFeatureFlags.enableReactTestRendererLegacyMode = true;
React = require('react');
Scheduler = require('scheduler');
@@ -213,7 +214,7 @@ describe(`onRender`, () => {
,
{
- isConcurrent: true,
+ unstable_isConcurrent: true,
},
);
});
@@ -752,7 +753,7 @@ describe(`onRender`, () => {
,
- {isConcurrent: true},
+ {unstable_isConcurrent: true},
);
});
@@ -793,7 +794,7 @@ describe(`onRender`, () => {
,
- {isConcurrent: true},
+ {unstable_isConcurrent: true},
);
});
@@ -844,7 +845,7 @@ describe(`onRender`, () => {
,
- {isConcurrent: true},
+ {unstable_isConcurrent: true},
);
});
@@ -897,7 +898,7 @@ describe(`onRender`, () => {
,
- {isConcurrent: true},
+ {unstable_isConcurrent: true},
);
// Render everything initially.
@@ -1002,7 +1003,7 @@ describe(`onRender`, () => {
,
- {isConcurrent: true},
+ {unstable_isConcurrent: true},
);
// Render everything initially.
diff --git a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
index 572abd354da63..d28e2ad8de64a 100644
--- a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
+++ b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
@@ -150,7 +150,7 @@ describe('ReactProfiler DevTools integration', () => {
return text;
}
- const root = ReactTestRenderer.create(null, {isConcurrent: true});
+ const root = ReactTestRenderer.create(null, {unstable_isConcurrent: true});
// Commit something
root.update(
);
diff --git a/packages/react/src/__tests__/ReactStartTransition-test.js b/packages/react/src/__tests__/ReactStartTransition-test.js
index c98372a7c74b7..9e689ac6e7105 100644
--- a/packages/react/src/__tests__/ReactStartTransition-test.js
+++ b/packages/react/src/__tests__/ReactStartTransition-test.js
@@ -49,7 +49,7 @@ describe('ReactStartTransition', () => {
await act(() => {
ReactTestRenderer.create(
, {
- isConcurrent: true,
+ unstable_isConcurrent: true,
});
});
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 1655c4eed031e..079d7a75ca034 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -191,6 +191,7 @@ export const enableRefAsProp = __NEXT_MAJOR__;
// Needs more internal cleanup
// Warn on any usage of ReactTestRenderer
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = false;
// -----------------------------------------------------------------------------
// Chopping Block
diff --git a/packages/shared/ReactVersion.js b/packages/shared/ReactVersion.js
index d0a14cfff7806..9055167e29cc5 100644
--- a/packages/shared/ReactVersion.js
+++ b/packages/shared/ReactVersion.js
@@ -1,16 +1 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-// TODO: this is special because it gets imported during build.
-//
-// TODO: 18.0.0 has not been released to NPM;
-// It exists as a placeholder so that DevTools can support work tag changes between releases.
-// When we next publish a release, update the matching TODO in backend/renderer.js
-// TODO: This module is used both by the release scripts and to expose a version
-// at runtime. We should instead inject the version number as part of the build
-// process, and use the ReactVersions.js module as the single source of truth.
-export default '18.2.0';
+export default '18.3.0-PLACEHOLDER';
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 1bf08bdffee0a..c232d28c8943b 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -103,6 +103,7 @@ export const enableInfiniteRenderLoopDetection = false;
export const enableRefAsProp = false;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = false;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 703c1b706c113..dd77eb567e418 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -94,6 +94,7 @@ export const enableServerComponentLogs = true;
export const enableRefAsProp = false;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = false;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 7a76a71b2750a..76b258ace344e 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -99,6 +99,7 @@ export const enableInfiniteRenderLoopDetection = false;
const __NEXT_MAJOR__ = __EXPERIMENTAL__;
export const enableRefAsProp = __NEXT_MAJOR__;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = false;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
index c0e2ccf107295..7be22a057cab4 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
@@ -90,6 +90,7 @@ export const enableServerComponentLogs = true;
export const enableRefAsProp = false;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = true;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 7771505830eb1..a9cbcf4ebe921 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -93,6 +93,7 @@ export const enableInfiniteRenderLoopDetection = false;
export const enableRefAsProp = false;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = true;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index f54309be42530..7f5f3979c4d64 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -119,6 +119,7 @@ export const enableServerComponentKeys = true;
export const enableServerComponentLogs = true;
export const enableReactTestRendererWarning = false;
+export const enableReactTestRendererLegacyMode = false;
// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);