@mui/internal-test-utils 2.0.14 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{src/chai.types.ts → chai.types.d.ts} +7 -40
- package/chai.types.js +5 -0
- package/chaiPlugin.d.ts +4 -0
- package/chaiPlugin.js +287 -0
- package/{build/components.d.ts → components.d.ts} +18 -19
- package/components.js +64 -0
- package/createDOM.d.ts +2 -0
- package/{src/createDOM.js → createDOM.js} +17 -35
- package/createDescribe.d.ts +7 -0
- package/createDescribe.js +26 -0
- package/createRenderer.d.ts +214 -0
- package/createRenderer.js +428 -0
- package/createRenderer.test.d.ts +1 -0
- package/describeConformance.d.ts +200 -0
- package/describeConformance.js +1038 -0
- package/env.d.ts +1 -0
- package/env.js +11 -0
- package/esm/chai.types.d.ts +74 -0
- package/esm/chai.types.js +3 -0
- package/esm/chaiPlugin.d.ts +4 -0
- package/esm/chaiPlugin.js +281 -0
- package/esm/components.d.ts +35 -0
- package/esm/components.js +56 -0
- package/esm/createDOM.d.ts +2 -0
- package/esm/createDOM.js +47 -0
- package/esm/createDescribe.d.ts +7 -0
- package/esm/createDescribe.js +19 -0
- package/esm/createRenderer.d.ts +214 -0
- package/esm/createRenderer.js +390 -0
- package/esm/createRenderer.test.d.ts +1 -0
- package/esm/describeConformance.d.ts +200 -0
- package/esm/describeConformance.js +1024 -0
- package/esm/env.d.ts +1 -0
- package/esm/env.js +5 -0
- package/{build → esm}/fireDiscreteEvent.d.ts +1 -2
- package/{src/fireDiscreteEvent.ts → esm/fireDiscreteEvent.js} +10 -18
- package/esm/flushMicrotasks.d.ts +1 -0
- package/{src/flushMicrotasks.ts → esm/flushMicrotasks.js} +2 -3
- package/{build → esm}/focusVisible.d.ts +1 -2
- package/{src/focusVisible.ts → esm/focusVisible.js} +10 -9
- package/esm/index.d.ts +18 -0
- package/esm/index.js +27 -0
- package/esm/init.d.ts +1 -0
- package/{src → esm}/init.js +4 -2
- package/esm/initMatchers.d.ts +1 -0
- package/esm/initMatchers.js +6 -0
- package/esm/initMatchers.test.d.ts +1 -0
- package/esm/initPlaywrightMatchers.d.ts +24 -0
- package/esm/initPlaywrightMatchers.js +40 -0
- package/esm/package.json +1 -0
- package/esm/reactMajor.d.ts +2 -0
- package/esm/reactMajor.js +2 -0
- package/esm/setup.d.ts +1 -0
- package/{src → esm}/setup.js +2 -4
- package/esm/setupVitest.d.ts +1 -0
- package/esm/setupVitest.js +28 -0
- package/esm/setupVitestBrowser.d.ts +1 -0
- package/esm/setupVitestBrowser.js +30 -0
- package/fireDiscreteEvent.d.ts +6 -0
- package/fireDiscreteEvent.js +79 -0
- package/flushMicrotasks.d.ts +1 -0
- package/flushMicrotasks.js +10 -0
- package/focusVisible.d.ts +7 -0
- package/focusVisible.js +44 -0
- package/index.d.ts +18 -0
- package/index.js +139 -0
- package/init.d.ts +1 -0
- package/init.js +15 -0
- package/initMatchers.d.ts +1 -0
- package/initMatchers.js +10 -0
- package/initMatchers.test.d.ts +1 -0
- package/initPlaywrightMatchers.d.ts +24 -0
- package/initPlaywrightMatchers.js +42 -0
- package/package.json +89 -46
- package/reactMajor.d.ts +2 -0
- package/reactMajor.js +9 -0
- package/setup.d.ts +1 -0
- package/setup.js +10 -0
- package/setupVitest.d.ts +1 -0
- package/setupVitest.js +32 -0
- package/setupVitestBrowser.d.ts +1 -0
- package/setupVitestBrowser.js +34 -0
- package/build/.tsbuildinfo +0 -1
- package/build/KarmaReporterReactProfiler.d.ts +0 -51
- package/build/KarmaReporterReactProfiler.d.ts.map +0 -1
- package/build/KarmaReporterReactProfiler.js +0 -66
- package/build/KarmaReporterReactProfiler.js.map +0 -1
- package/build/chai.types.d.ts +0 -75
- package/build/chai.types.d.ts.map +0 -1
- package/build/chai.types.js +0 -3
- package/build/chai.types.js.map +0 -1
- package/build/chaiPlugin.d.ts +0 -5
- package/build/chaiPlugin.d.ts.map +0 -1
- package/build/chaiPlugin.js +0 -417
- package/build/chaiPlugin.js.map +0 -1
- package/build/components.d.ts.map +0 -1
- package/build/components.js +0 -88
- package/build/components.js.map +0 -1
- package/build/createDOM.d.ts +0 -3
- package/build/createDOM.d.ts.map +0 -1
- package/build/createDOM.js +0 -60
- package/build/createDOM.js.map +0 -1
- package/build/createDescribe.d.ts +0 -8
- package/build/createDescribe.d.ts.map +0 -1
- package/build/createDescribe.js +0 -22
- package/build/createDescribe.js.map +0 -1
- package/build/createRenderer.d.ts +0 -215
- package/build/createRenderer.d.ts.map +0 -1
- package/build/createRenderer.js +0 -565
- package/build/createRenderer.js.map +0 -1
- package/build/createRenderer.test.d.ts +0 -2
- package/build/createRenderer.test.d.ts.map +0 -1
- package/build/createRenderer.test.js +0 -58
- package/build/createRenderer.test.js.map +0 -1
- package/build/describeConformance.d.ts +0 -201
- package/build/describeConformance.d.ts.map +0 -1
- package/build/describeConformance.js +0 -859
- package/build/describeConformance.js.map +0 -1
- package/build/describeSkipIf.d.ts +0 -4
- package/build/describeSkipIf.d.ts.map +0 -1
- package/build/describeSkipIf.js +0 -10
- package/build/describeSkipIf.js.map +0 -1
- package/build/fireDiscreteEvent.d.ts.map +0 -1
- package/build/fireDiscreteEvent.js +0 -77
- package/build/fireDiscreteEvent.js.map +0 -1
- package/build/flushMicrotasks.d.ts +0 -2
- package/build/flushMicrotasks.d.ts.map +0 -1
- package/build/flushMicrotasks.js +0 -8
- package/build/flushMicrotasks.js.map +0 -1
- package/build/focusVisible.d.ts.map +0 -1
- package/build/focusVisible.js +0 -38
- package/build/focusVisible.js.map +0 -1
- package/build/index.d.ts +0 -18
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -68
- package/build/index.js.map +0 -1
- package/build/init.d.ts +0 -2
- package/build/init.d.ts.map +0 -1
- package/build/init.js +0 -46
- package/build/init.js.map +0 -1
- package/build/initMatchers.d.ts +0 -2
- package/build/initMatchers.d.ts.map +0 -1
- package/build/initMatchers.js +0 -45
- package/build/initMatchers.js.map +0 -1
- package/build/initMatchers.test.d.ts +0 -2
- package/build/initMatchers.test.d.ts.map +0 -1
- package/build/initMatchers.test.js +0 -101
- package/build/initMatchers.test.js.map +0 -1
- package/build/initPlaywrightMatchers.d.ts +0 -25
- package/build/initPlaywrightMatchers.d.ts.map +0 -1
- package/build/initPlaywrightMatchers.js +0 -73
- package/build/initPlaywrightMatchers.js.map +0 -1
- package/build/mochaHooks.d.ts +0 -24
- package/build/mochaHooks.d.ts.map +0 -1
- package/build/mochaHooks.js +0 -165
- package/build/mochaHooks.js.map +0 -1
- package/build/mochaHooks.test.d.ts +0 -2
- package/build/mochaHooks.test.d.ts.map +0 -1
- package/build/mochaHooks.test.js +0 -127
- package/build/mochaHooks.test.js.map +0 -1
- package/build/reactMajor.d.ts +0 -3
- package/build/reactMajor.d.ts.map +0 -1
- package/build/reactMajor.js +0 -38
- package/build/reactMajor.js.map +0 -1
- package/build/setup.d.ts +0 -2
- package/build/setup.d.ts.map +0 -1
- package/build/setup.js +0 -10
- package/build/setup.js.map +0 -1
- package/build/setupBabel.d.ts +0 -2
- package/build/setupBabel.d.ts.map +0 -1
- package/build/setupBabel.js +0 -5
- package/build/setupBabel.js.map +0 -1
- package/build/setupBabelPlaywright.d.ts +0 -2
- package/build/setupBabelPlaywright.d.ts.map +0 -1
- package/build/setupBabelPlaywright.js +0 -14
- package/build/setupBabelPlaywright.js.map +0 -1
- package/build/setupJSDOM.d.ts +0 -7
- package/build/setupJSDOM.d.ts.map +0 -1
- package/build/setupJSDOM.js +0 -17
- package/build/setupJSDOM.js.map +0 -1
- package/build/setupKarma.d.ts +0 -2
- package/build/setupKarma.d.ts.map +0 -1
- package/build/setupKarma.js +0 -56
- package/build/setupKarma.js.map +0 -1
- package/build/setupVitest.d.ts +0 -2
- package/build/setupVitest.d.ts.map +0 -1
- package/build/setupVitest.js +0 -131
- package/build/setupVitest.js.map +0 -1
- package/src/KarmaReporterReactProfiler.js +0 -82
- package/src/chai-augmentation.d.ts +0 -8
- package/src/chaiPlugin.ts +0 -516
- package/src/components.tsx +0 -61
- package/src/createDOM.d.ts +0 -9
- package/src/createDescribe.ts +0 -31
- package/src/createRenderer.test.js +0 -31
- package/src/createRenderer.tsx +0 -809
- package/src/describeConformance.tsx +0 -1257
- package/src/describeSkipIf.tsx +0 -11
- package/src/index.ts +0 -25
- package/src/initMatchers.test.js +0 -124
- package/src/initMatchers.ts +0 -7
- package/src/initPlaywrightMatchers.ts +0 -101
- package/src/mochaHooks.js +0 -200
- package/src/mochaHooks.test.js +0 -115
- package/src/reactMajor.ts +0 -3
- package/src/setupBabel.js +0 -3
- package/src/setupBabelPlaywright.js +0 -13
- package/src/setupJSDOM.js +0 -20
- package/src/setupKarma.js +0 -65
- package/src/setupVitest.ts +0 -117
- package/tsconfig.build.json +0 -16
- package/tsconfig.json +0 -17
|
@@ -1,859 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.randomStringValue = randomStringValue;
|
|
40
|
-
exports.testClassName = testClassName;
|
|
41
|
-
exports.testComponentProp = testComponentProp;
|
|
42
|
-
exports.testPropsSpread = testPropsSpread;
|
|
43
|
-
exports.describeRef = describeRef;
|
|
44
|
-
exports.testRootClass = testRootClass;
|
|
45
|
-
/* eslint-env mocha */
|
|
46
|
-
const chai_1 = require("chai");
|
|
47
|
-
const React = __importStar(require("react"));
|
|
48
|
-
const createDescribe_1 = __importDefault(require("./createDescribe"));
|
|
49
|
-
function capitalize(string) {
|
|
50
|
-
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Glossary
|
|
54
|
-
* - root component:
|
|
55
|
-
* - renders the outermost host component
|
|
56
|
-
* - has the `root` class if the component has one
|
|
57
|
-
* - excess props are spread to this component
|
|
58
|
-
* - has the type of `inheritComponent`
|
|
59
|
-
*/
|
|
60
|
-
function randomStringValue() {
|
|
61
|
-
return `s${Math.random().toString(36).slice(2)}`;
|
|
62
|
-
}
|
|
63
|
-
function throwMissingPropError(field) {
|
|
64
|
-
throw new Error(`missing "${field}" in options
|
|
65
|
-
|
|
66
|
-
> describeConformance(element, () => options)
|
|
67
|
-
`);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* MUI components have a `className` prop. The `className` is applied to
|
|
71
|
-
* the root component.
|
|
72
|
-
*/
|
|
73
|
-
function testClassName(element, getOptions) {
|
|
74
|
-
it('applies the className to the root component', async () => {
|
|
75
|
-
const { render } = getOptions();
|
|
76
|
-
if (!render) {
|
|
77
|
-
throwMissingPropError('render');
|
|
78
|
-
}
|
|
79
|
-
const className = randomStringValue();
|
|
80
|
-
const testId = randomStringValue();
|
|
81
|
-
const { getByTestId } = await render(React.cloneElement(element, { className, 'data-testid': testId }));
|
|
82
|
-
(0, chai_1.expect)(getByTestId(testId)).to.have.class(className);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* MUI components have a `component` prop that allows rendering a different
|
|
87
|
-
* Component from @inheritComponent
|
|
88
|
-
*/
|
|
89
|
-
function testComponentProp(element, getOptions) {
|
|
90
|
-
describe('prop: component', () => {
|
|
91
|
-
it('can render another root component with the `component` prop', async () => {
|
|
92
|
-
const { render, testComponentPropWith: component = 'em' } = getOptions();
|
|
93
|
-
if (!render) {
|
|
94
|
-
throwMissingPropError('render');
|
|
95
|
-
}
|
|
96
|
-
const testId = randomStringValue();
|
|
97
|
-
if (typeof component === 'string') {
|
|
98
|
-
const { getByTestId } = await render(React.cloneElement(element, { component, 'data-testid': testId }));
|
|
99
|
-
(0, chai_1.expect)(getByTestId(testId)).not.to.equal(null);
|
|
100
|
-
(0, chai_1.expect)(getByTestId(testId).nodeName.toLowerCase()).to.eq(component);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
const componentWithTestId = (props) => React.createElement(component, { ...props, 'data-testid': testId });
|
|
104
|
-
const { getByTestId } = await render(React.cloneElement(element, {
|
|
105
|
-
component: componentWithTestId,
|
|
106
|
-
}));
|
|
107
|
-
(0, chai_1.expect)(getByTestId(testId)).not.to.equal(null);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* MUI components spread additional props to its root.
|
|
114
|
-
*/
|
|
115
|
-
function testPropsSpread(element, getOptions) {
|
|
116
|
-
it(`spreads props to the root component`, async () => {
|
|
117
|
-
// type def in ConformanceOptions
|
|
118
|
-
const { render } = getOptions();
|
|
119
|
-
if (!render) {
|
|
120
|
-
throwMissingPropError('render');
|
|
121
|
-
}
|
|
122
|
-
const testProp = 'data-test-props-spread';
|
|
123
|
-
const value = randomStringValue();
|
|
124
|
-
const testId = randomStringValue();
|
|
125
|
-
const { getByTestId } = await render(React.cloneElement(element, { [testProp]: value, 'data-testid': testId }));
|
|
126
|
-
(0, chai_1.expect)(getByTestId(testId)).to.have.attribute(testProp, value);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Tests that the `ref` of a component will return the correct instance
|
|
131
|
-
*
|
|
132
|
-
* This is determined by a given constructor i.e. a React.Component or HTMLElement for
|
|
133
|
-
* components that forward their ref and attach it to a host component.
|
|
134
|
-
*/
|
|
135
|
-
function describeRef(element, getOptions) {
|
|
136
|
-
describe('ref', () => {
|
|
137
|
-
it(`attaches the ref`, async () => {
|
|
138
|
-
// type def in ConformanceOptions
|
|
139
|
-
const { render, refInstanceof } = getOptions();
|
|
140
|
-
if (!render) {
|
|
141
|
-
throwMissingPropError('render');
|
|
142
|
-
}
|
|
143
|
-
const ref = React.createRef();
|
|
144
|
-
await render(React.cloneElement(element, { ref }));
|
|
145
|
-
(0, chai_1.expect)(ref.current).to.be.instanceof(refInstanceof);
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Tests that the root component has the root class
|
|
151
|
-
*/
|
|
152
|
-
function testRootClass(element, getOptions) {
|
|
153
|
-
it('applies the root class to the root component if it has this class', async () => {
|
|
154
|
-
const { classes, render, skip } = getOptions();
|
|
155
|
-
if (classes.root == null) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const className = randomStringValue();
|
|
159
|
-
const classesRootClassname = randomStringValue();
|
|
160
|
-
const { container } = await render(React.cloneElement(element, {
|
|
161
|
-
className,
|
|
162
|
-
classes: { ...classes, root: `${classes.root} ${classesRootClassname}` },
|
|
163
|
-
}));
|
|
164
|
-
// we established that the root component renders the outermost host previously. We immediately
|
|
165
|
-
// jump to the host component because some components pass the `root` class
|
|
166
|
-
// to the `classes` prop of the root component.
|
|
167
|
-
// https://github.com/mui/material-ui/blob/f9896bcd129a1209153106296b3d2487547ba205/packages/material-ui/src/OutlinedInput/OutlinedInput.js#L101
|
|
168
|
-
(0, chai_1.expect)(container.firstChild).to.have.class(className);
|
|
169
|
-
(0, chai_1.expect)(container.firstChild).to.have.class(classes.root);
|
|
170
|
-
(0, chai_1.expect)(document.querySelectorAll(`.${classes.root}`).length).to.equal(1);
|
|
171
|
-
// classes test only for @mui/material
|
|
172
|
-
if (!skip || !skip.includes('classesRoot')) {
|
|
173
|
-
// Test that classes prop works
|
|
174
|
-
(0, chai_1.expect)(container.firstChild).to.have.class(classesRootClassname);
|
|
175
|
-
// Test that `classes` does not spread to DOM
|
|
176
|
-
(0, chai_1.expect)(document.querySelectorAll('[classes]').length).to.equal(0);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
function forEachSlot(slots, callback) {
|
|
181
|
-
if (!slots) {
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
const slotNames = Object.keys(slots);
|
|
185
|
-
slotNames.forEach((slotName) => {
|
|
186
|
-
const slot = slots[slotName];
|
|
187
|
-
callback(slotName, slot);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
function testSlotsProp(element, getOptions) {
|
|
191
|
-
const { render, slots, testLegacyComponentsProp } = getOptions();
|
|
192
|
-
const CustomComponent = React.forwardRef(({ className, children }, ref) => (React.createElement("i", { className: className, ref: ref, "data-testid": "custom" }, children)));
|
|
193
|
-
forEachSlot(slots, (slotName, slotOptions) => {
|
|
194
|
-
it(`allows overriding the ${slotName} slot with a component using the slots.${slotName} prop`, async () => {
|
|
195
|
-
if (!render) {
|
|
196
|
-
throwMissingPropError('render');
|
|
197
|
-
}
|
|
198
|
-
const slotComponent = slotOptions.testWithComponent ?? CustomComponent;
|
|
199
|
-
const components = {
|
|
200
|
-
[slotName]: slotComponent,
|
|
201
|
-
};
|
|
202
|
-
const { queryByTestId } = await render(React.cloneElement(element, { slots: components }));
|
|
203
|
-
const renderedElement = queryByTestId('custom');
|
|
204
|
-
(0, chai_1.expect)(renderedElement).not.to.equal(null);
|
|
205
|
-
if (slotOptions.expectedClassName) {
|
|
206
|
-
(0, chai_1.expect)(renderedElement).to.have.class(slotOptions.expectedClassName);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
if (slotOptions.testWithElement !== null) {
|
|
210
|
-
it(`allows overriding the ${slotName} slot with an element using the slots.${slotName} prop`, async () => {
|
|
211
|
-
if (!render) {
|
|
212
|
-
throwMissingPropError('render');
|
|
213
|
-
}
|
|
214
|
-
const slotElement = slotOptions.testWithElement ?? 'i';
|
|
215
|
-
const components = {
|
|
216
|
-
[slotName]: slotElement,
|
|
217
|
-
};
|
|
218
|
-
const slotProps = {
|
|
219
|
-
[slotName]: {
|
|
220
|
-
'data-testid': 'customized',
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
const { queryByTestId } = await render(React.cloneElement(element, { slots: components, slotProps }));
|
|
224
|
-
const renderedElement = queryByTestId('customized');
|
|
225
|
-
(0, chai_1.expect)(renderedElement).not.to.equal(null);
|
|
226
|
-
if (typeof slotElement === 'string') {
|
|
227
|
-
(0, chai_1.expect)(renderedElement.nodeName.toLowerCase()).to.equal(slotElement);
|
|
228
|
-
}
|
|
229
|
-
if (slotOptions.expectedClassName) {
|
|
230
|
-
(0, chai_1.expect)(renderedElement).to.have.class(slotOptions.expectedClassName);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
// For testing Material UI components v5, and v6. Likely to be removed in a future major release.
|
|
235
|
-
if (testLegacyComponentsProp === true ||
|
|
236
|
-
(Array.isArray(testLegacyComponentsProp) && testLegacyComponentsProp.includes(slotName))) {
|
|
237
|
-
it(`allows overriding the ${slotName} slot with a component using the components.${capitalize(slotName)} prop`, async () => {
|
|
238
|
-
if (!render) {
|
|
239
|
-
throwMissingPropError('render');
|
|
240
|
-
}
|
|
241
|
-
const slotComponent = slotOptions.testWithComponent ?? CustomComponent;
|
|
242
|
-
const components = {
|
|
243
|
-
[capitalize(slotName)]: slotComponent,
|
|
244
|
-
};
|
|
245
|
-
const { queryByTestId } = await render(React.cloneElement(element, { components }));
|
|
246
|
-
const renderedElement = queryByTestId('custom');
|
|
247
|
-
(0, chai_1.expect)(renderedElement).not.to.equal(null);
|
|
248
|
-
if (slotOptions.expectedClassName) {
|
|
249
|
-
(0, chai_1.expect)(renderedElement).to.have.class(slotOptions.expectedClassName);
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
it(`prioritizes the 'slots.${slotName}' over components.${capitalize(slotName)} if both are defined`, async () => {
|
|
253
|
-
if (!render) {
|
|
254
|
-
throwMissingPropError('render');
|
|
255
|
-
}
|
|
256
|
-
const ComponentForComponentsProp = React.forwardRef(({ children }, ref) => {
|
|
257
|
-
const SlotComponent = slotOptions.testWithComponent ?? 'div';
|
|
258
|
-
return (React.createElement(SlotComponent, { ref: ref, "data-testid": "from-components" }, children));
|
|
259
|
-
});
|
|
260
|
-
const ComponentForSlotsProp = React.forwardRef(({ children }, ref) => {
|
|
261
|
-
const SlotComponent = slotOptions.testWithComponent ?? 'div';
|
|
262
|
-
return (React.createElement(SlotComponent, { ref: ref, "data-testid": "from-slots" }, children));
|
|
263
|
-
});
|
|
264
|
-
const components = {
|
|
265
|
-
[capitalize(slotName)]: ComponentForComponentsProp,
|
|
266
|
-
};
|
|
267
|
-
const slotOverrides = {
|
|
268
|
-
[slotName]: ComponentForSlotsProp,
|
|
269
|
-
};
|
|
270
|
-
const { queryByTestId } = await render(React.cloneElement(element, { components, slots: slotOverrides }));
|
|
271
|
-
(0, chai_1.expect)(queryByTestId('from-slots')).not.to.equal(null);
|
|
272
|
-
(0, chai_1.expect)(queryByTestId('from-components')).to.equal(null);
|
|
273
|
-
});
|
|
274
|
-
if (slotOptions.testWithElement !== null) {
|
|
275
|
-
it(`allows overriding the ${slotName} slot with an element using the components.${capitalize(slotName)} prop`, async () => {
|
|
276
|
-
if (!render) {
|
|
277
|
-
throwMissingPropError('render');
|
|
278
|
-
}
|
|
279
|
-
const slotElement = slotOptions.testWithElement ?? 'i';
|
|
280
|
-
const components = {
|
|
281
|
-
[capitalize(slotName)]: slotElement,
|
|
282
|
-
};
|
|
283
|
-
const componentsProps = {
|
|
284
|
-
[slotName]: {
|
|
285
|
-
'data-testid': 'customized',
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
const { queryByTestId } = await render(React.cloneElement(element, { components, componentsProps }));
|
|
289
|
-
const renderedElement = queryByTestId('customized');
|
|
290
|
-
(0, chai_1.expect)(renderedElement).not.to.equal(null);
|
|
291
|
-
if (typeof slotElement === 'string') {
|
|
292
|
-
(0, chai_1.expect)(renderedElement.nodeName.toLowerCase()).to.equal(slotElement);
|
|
293
|
-
}
|
|
294
|
-
if (slotOptions.expectedClassName) {
|
|
295
|
-
(0, chai_1.expect)(renderedElement).to.have.class(slotOptions.expectedClassName);
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
function testSlotPropsProp(element, getOptions) {
|
|
303
|
-
const { render, slots, testLegacyComponentsProp } = getOptions();
|
|
304
|
-
if (!render) {
|
|
305
|
-
throwMissingPropError('render');
|
|
306
|
-
}
|
|
307
|
-
forEachSlot(slots, (slotName, slotOptions) => {
|
|
308
|
-
it(`sets custom properties on the ${slotName} slot's element with the slotProps.${slotName} prop`, async () => {
|
|
309
|
-
const slotProps = {
|
|
310
|
-
[slotName]: {
|
|
311
|
-
'data-testid': 'custom',
|
|
312
|
-
},
|
|
313
|
-
};
|
|
314
|
-
const { queryByTestId } = await render(React.cloneElement(element, { slotProps }));
|
|
315
|
-
const slotComponent = queryByTestId('custom');
|
|
316
|
-
(0, chai_1.expect)(slotComponent).not.to.equal(null);
|
|
317
|
-
if (slotOptions.expectedClassName) {
|
|
318
|
-
(0, chai_1.expect)(slotComponent).to.have.class(slotOptions.expectedClassName);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
if (slotOptions.expectedClassName) {
|
|
322
|
-
it(`merges the class names provided in slotsProps.${slotName} with the built-in ones`, async () => {
|
|
323
|
-
const slotProps = {
|
|
324
|
-
[slotName]: {
|
|
325
|
-
'data-testid': 'custom',
|
|
326
|
-
className: randomStringValue(),
|
|
327
|
-
},
|
|
328
|
-
};
|
|
329
|
-
const { getByTestId } = await render(React.cloneElement(element, { slotProps }));
|
|
330
|
-
(0, chai_1.expect)(getByTestId('custom')).to.have.class(slotOptions.expectedClassName);
|
|
331
|
-
(0, chai_1.expect)(getByTestId('custom')).to.have.class(slotProps[slotName].className);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
if (testLegacyComponentsProp === true ||
|
|
335
|
-
(Array.isArray(testLegacyComponentsProp) && testLegacyComponentsProp.includes(slotName))) {
|
|
336
|
-
it(`sets custom properties on the ${slotName} slot's element with the componentsProps.${slotName} prop`, async () => {
|
|
337
|
-
const componentsProps = {
|
|
338
|
-
[slotName]: {
|
|
339
|
-
'data-testid': 'custom',
|
|
340
|
-
},
|
|
341
|
-
};
|
|
342
|
-
const { queryByTestId } = await render(React.cloneElement(element, { componentsProps }));
|
|
343
|
-
const slotComponent = queryByTestId('custom');
|
|
344
|
-
(0, chai_1.expect)(slotComponent).not.to.equal(null);
|
|
345
|
-
if (slotOptions.expectedClassName) {
|
|
346
|
-
(0, chai_1.expect)(slotComponent).to.have.class(slotOptions.expectedClassName);
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
it(`prioritizes the 'slotProps.${slotName}' over componentsProps.${slotName} if both are defined`, async () => {
|
|
350
|
-
const componentsProps = {
|
|
351
|
-
[slotName]: {
|
|
352
|
-
'data-testid': 'custom',
|
|
353
|
-
'data-from-components-props': 'true',
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
const slotProps = {
|
|
357
|
-
[slotName]: {
|
|
358
|
-
'data-testid': 'custom',
|
|
359
|
-
'data-from-slot-props': 'true',
|
|
360
|
-
},
|
|
361
|
-
};
|
|
362
|
-
const { queryByTestId } = await render(React.cloneElement(element, { componentsProps, slotProps }));
|
|
363
|
-
const slotComponent = queryByTestId('custom');
|
|
364
|
-
(0, chai_1.expect)(slotComponent).to.have.attribute('data-from-slot-props', 'true');
|
|
365
|
-
(0, chai_1.expect)(slotComponent).not.to.have.attribute('data-from-components-props');
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
function testSlotPropsCallback(element, getOptions) {
|
|
371
|
-
const { render, slots } = getOptions();
|
|
372
|
-
if (!render) {
|
|
373
|
-
throwMissingPropError('render');
|
|
374
|
-
}
|
|
375
|
-
forEachSlot(slots, (slotName) => {
|
|
376
|
-
it(`sets custom properties on the ${slotName} slot's element with the slotProps.${slotName} callback`, async () => {
|
|
377
|
-
const slotProps = {
|
|
378
|
-
[slotName]: () => ({
|
|
379
|
-
'data-testid': 'custom',
|
|
380
|
-
}),
|
|
381
|
-
};
|
|
382
|
-
const { queryByTestId } = await render(React.cloneElement(element, { slotProps, className: 'custom' }));
|
|
383
|
-
const slotComponent = queryByTestId('custom');
|
|
384
|
-
(0, chai_1.expect)(slotComponent).not.to.equal(null);
|
|
385
|
-
});
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
function testSlotPropsCallbackWithPropsAsOwnerState(element, getOptions) {
|
|
389
|
-
const { render, slots } = getOptions();
|
|
390
|
-
if (!render) {
|
|
391
|
-
throwMissingPropError('render');
|
|
392
|
-
}
|
|
393
|
-
forEachSlot(slots, (slotName) => {
|
|
394
|
-
it(`sets custom properties on the ${slotName} slot's element with the slotProps.${slotName} callback using the ownerState`, async () => {
|
|
395
|
-
const slotProps = {
|
|
396
|
-
[slotName]: (ownerState) => ({
|
|
397
|
-
'data-testid': ownerState.className,
|
|
398
|
-
}),
|
|
399
|
-
};
|
|
400
|
-
const { queryByTestId } = await render(React.cloneElement(element, { slotProps, className: 'custom' }));
|
|
401
|
-
const slotComponent = queryByTestId('custom', { exact: false });
|
|
402
|
-
(0, chai_1.expect)(slotComponent).not.to.equal(null);
|
|
403
|
-
});
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* MUI components have a `components` prop that allows rendering a different
|
|
408
|
-
* Components from @inheritComponent
|
|
409
|
-
*/
|
|
410
|
-
function testComponentsProp(element, getOptions) {
|
|
411
|
-
describe('prop components:', () => {
|
|
412
|
-
it('can render another root component with the `components` prop', async () => {
|
|
413
|
-
const { render, testComponentsRootPropWith: component = 'em' } = getOptions();
|
|
414
|
-
if (!render) {
|
|
415
|
-
throwMissingPropError('render');
|
|
416
|
-
}
|
|
417
|
-
const testId = randomStringValue();
|
|
418
|
-
const { getByTestId } = await render(React.cloneElement(element, { components: { Root: component }, 'data-testid': testId }));
|
|
419
|
-
(0, chai_1.expect)(getByTestId(testId)).not.to.equal(null);
|
|
420
|
-
(0, chai_1.expect)(getByTestId(testId).nodeName.toLowerCase()).to.eq(component);
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* MUI theme has a components section that allows specifying default props.
|
|
426
|
-
* Components from @inheritComponent
|
|
427
|
-
*/
|
|
428
|
-
function testThemeDefaultProps(element, getOptions) {
|
|
429
|
-
describe('theme default components:', () => {
|
|
430
|
-
it("respect theme's defaultProps", async () => {
|
|
431
|
-
const testProp = 'data-id';
|
|
432
|
-
const { muiName, render, ThemeProvider, createTheme } = getOptions();
|
|
433
|
-
if (!muiName) {
|
|
434
|
-
throwMissingPropError('muiName');
|
|
435
|
-
}
|
|
436
|
-
if (!render) {
|
|
437
|
-
throwMissingPropError('render');
|
|
438
|
-
}
|
|
439
|
-
if (!ThemeProvider) {
|
|
440
|
-
throwMissingPropError('ThemeProvider');
|
|
441
|
-
}
|
|
442
|
-
if (!createTheme) {
|
|
443
|
-
throwMissingPropError('createTheme');
|
|
444
|
-
}
|
|
445
|
-
const theme = createTheme({
|
|
446
|
-
components: {
|
|
447
|
-
[muiName]: {
|
|
448
|
-
defaultProps: {
|
|
449
|
-
[testProp]: 'testProp',
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
|
-
const { container } = await render(React.createElement(ThemeProvider, { theme: theme }, element));
|
|
455
|
-
(0, chai_1.expect)(container.firstChild).to.have.attribute(testProp, 'testProp');
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
describe('default props provider:', () => {
|
|
459
|
-
it('respect custom default props', async function test(t = {}) {
|
|
460
|
-
const testProp = 'data-id';
|
|
461
|
-
const { muiName, render, DefaultPropsProvider } = getOptions();
|
|
462
|
-
if (!DefaultPropsProvider) {
|
|
463
|
-
// @ts-ignore
|
|
464
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
465
|
-
this?.skip?.() ?? t?.skip();
|
|
466
|
-
}
|
|
467
|
-
if (!muiName) {
|
|
468
|
-
throwMissingPropError('muiName');
|
|
469
|
-
}
|
|
470
|
-
if (!render) {
|
|
471
|
-
throwMissingPropError('render');
|
|
472
|
-
}
|
|
473
|
-
const { container } = await render(
|
|
474
|
-
// @ts-expect-error we skip it above.
|
|
475
|
-
React.createElement(DefaultPropsProvider, { value: {
|
|
476
|
-
[muiName]: {
|
|
477
|
-
defaultProps: {
|
|
478
|
-
[testProp]: 'testProp',
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
} }, element));
|
|
482
|
-
(0, chai_1.expect)(container.firstChild).to.have.attribute(testProp, 'testProp');
|
|
483
|
-
});
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* MUI theme has a components section that allows specifying style overrides.
|
|
488
|
-
* Components from @inheritComponent
|
|
489
|
-
*/
|
|
490
|
-
function testThemeStyleOverrides(element, getOptions) {
|
|
491
|
-
describe('theme style overrides:', () => {
|
|
492
|
-
it("respect theme's styleOverrides custom state", async function test(t = {}) {
|
|
493
|
-
if (window.navigator.userAgent.includes('jsdom')) {
|
|
494
|
-
// @ts-ignore
|
|
495
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
496
|
-
this?.skip?.() ?? t?.skip();
|
|
497
|
-
}
|
|
498
|
-
const { muiName, testStateOverrides, render, ThemeProvider, createTheme } = getOptions();
|
|
499
|
-
if (!testStateOverrides) {
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
if (!muiName) {
|
|
503
|
-
throwMissingPropError('muiName');
|
|
504
|
-
}
|
|
505
|
-
if (!render) {
|
|
506
|
-
throwMissingPropError('render');
|
|
507
|
-
}
|
|
508
|
-
if (!ThemeProvider) {
|
|
509
|
-
throwMissingPropError('ThemeProvider');
|
|
510
|
-
}
|
|
511
|
-
if (!createTheme) {
|
|
512
|
-
throwMissingPropError('createTheme');
|
|
513
|
-
}
|
|
514
|
-
const testStyle = {
|
|
515
|
-
marginTop: '13px',
|
|
516
|
-
};
|
|
517
|
-
const theme = createTheme({
|
|
518
|
-
components: {
|
|
519
|
-
[muiName]: {
|
|
520
|
-
styleOverrides: {
|
|
521
|
-
[testStateOverrides.styleKey]: testStyle,
|
|
522
|
-
},
|
|
523
|
-
},
|
|
524
|
-
},
|
|
525
|
-
});
|
|
526
|
-
if (!testStateOverrides.prop) {
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
const { container } = await render(React.createElement(ThemeProvider, { theme: theme }, React.cloneElement(element, {
|
|
530
|
-
[testStateOverrides.prop]: testStateOverrides.value,
|
|
531
|
-
})));
|
|
532
|
-
(0, chai_1.expect)(container.firstChild).to.toHaveComputedStyle(testStyle);
|
|
533
|
-
});
|
|
534
|
-
it("respect theme's styleOverrides slots", async function test(t = {}) {
|
|
535
|
-
if (window.navigator.userAgent.includes('jsdom')) {
|
|
536
|
-
// @ts-ignore
|
|
537
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
538
|
-
this?.skip?.() ?? t?.skip();
|
|
539
|
-
}
|
|
540
|
-
const { muiName, testDeepOverrides, testRootOverrides = { slotName: 'root' }, render, ThemeProvider, createTheme, } = getOptions();
|
|
541
|
-
if (!ThemeProvider) {
|
|
542
|
-
throwMissingPropError('ThemeProvider');
|
|
543
|
-
}
|
|
544
|
-
if (!createTheme) {
|
|
545
|
-
throwMissingPropError('createTheme');
|
|
546
|
-
}
|
|
547
|
-
const testStyle = {
|
|
548
|
-
mixBlendMode: 'darken',
|
|
549
|
-
};
|
|
550
|
-
function resolveDeepOverrides(callback) {
|
|
551
|
-
if (!testDeepOverrides) {
|
|
552
|
-
return {};
|
|
553
|
-
}
|
|
554
|
-
const styles = {};
|
|
555
|
-
if (Array.isArray(testDeepOverrides)) {
|
|
556
|
-
testDeepOverrides.forEach((slot) => {
|
|
557
|
-
callback(styles, slot);
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
callback(styles, testDeepOverrides);
|
|
562
|
-
}
|
|
563
|
-
return styles;
|
|
564
|
-
}
|
|
565
|
-
const theme = createTheme({
|
|
566
|
-
components: {
|
|
567
|
-
[muiName]: {
|
|
568
|
-
styleOverrides: {
|
|
569
|
-
[testRootOverrides.slotName]: {
|
|
570
|
-
...testStyle,
|
|
571
|
-
...resolveDeepOverrides((styles, slot) => {
|
|
572
|
-
styles[`& .${slot.slotClassName}`] = {
|
|
573
|
-
fontVariantCaps: 'all-petite-caps',
|
|
574
|
-
};
|
|
575
|
-
}),
|
|
576
|
-
},
|
|
577
|
-
...resolveDeepOverrides((styles, slot) => {
|
|
578
|
-
styles[slot.slotName] = {
|
|
579
|
-
mixBlendMode: 'darken',
|
|
580
|
-
};
|
|
581
|
-
}),
|
|
582
|
-
},
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
});
|
|
586
|
-
const { container, setProps } = await render(React.createElement(ThemeProvider, { theme: theme }, element));
|
|
587
|
-
if (testRootOverrides.slotClassName) {
|
|
588
|
-
(0, chai_1.expect)(document.querySelector(`.${testRootOverrides.slotClassName}`)).to.toHaveComputedStyle(testStyle);
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
(0, chai_1.expect)(container.firstChild).to.toHaveComputedStyle(testStyle);
|
|
592
|
-
}
|
|
593
|
-
if (testDeepOverrides) {
|
|
594
|
-
(Array.isArray(testDeepOverrides) ? testDeepOverrides : [testDeepOverrides]).forEach((slot) => {
|
|
595
|
-
(0, chai_1.expect)(document.querySelector(`.${slot.slotClassName}`)).to.toHaveComputedStyle({
|
|
596
|
-
fontVariantCaps: 'all-petite-caps',
|
|
597
|
-
mixBlendMode: 'darken',
|
|
598
|
-
});
|
|
599
|
-
});
|
|
600
|
-
const themeWithoutRootOverrides = createTheme({
|
|
601
|
-
components: {
|
|
602
|
-
[muiName]: {
|
|
603
|
-
styleOverrides: {
|
|
604
|
-
...resolveDeepOverrides((styles, slot) => {
|
|
605
|
-
styles[slot.slotName] = testStyle;
|
|
606
|
-
}),
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
},
|
|
610
|
-
});
|
|
611
|
-
setProps({ theme: themeWithoutRootOverrides });
|
|
612
|
-
(Array.isArray(testDeepOverrides) ? testDeepOverrides : [testDeepOverrides]).forEach((slot) => {
|
|
613
|
-
(0, chai_1.expect)(document.querySelector(`.${slot.slotClassName}`)).to.toHaveComputedStyle(testStyle);
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
});
|
|
617
|
-
it('overrideStyles does not replace each other in slots', async function test(t = {}) {
|
|
618
|
-
if (window.navigator.userAgent.includes('jsdom')) {
|
|
619
|
-
// @ts-ignore
|
|
620
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
621
|
-
this?.skip?.() ?? t?.skip();
|
|
622
|
-
}
|
|
623
|
-
const { muiName, classes, testStateOverrides, render, ThemeProvider, createTheme } = getOptions();
|
|
624
|
-
if (!ThemeProvider) {
|
|
625
|
-
throwMissingPropError('ThemeProvider');
|
|
626
|
-
}
|
|
627
|
-
if (!createTheme) {
|
|
628
|
-
throwMissingPropError('createTheme');
|
|
629
|
-
}
|
|
630
|
-
const classKeys = Object.keys(classes);
|
|
631
|
-
// only test the component that has `root` and other classKey
|
|
632
|
-
if (!testStateOverrides || !classKeys.includes('root') || classKeys.length === 1) {
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
// `styleKey` in some tests is `foo` or `bar`, so need to check if it is a valid classKey.
|
|
636
|
-
const isStyleKeyExists = classKeys.includes(testStateOverrides.styleKey);
|
|
637
|
-
if (!isStyleKeyExists) {
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
const theme = createTheme({
|
|
641
|
-
components: {
|
|
642
|
-
[muiName]: {
|
|
643
|
-
styleOverrides: {
|
|
644
|
-
root: {
|
|
645
|
-
[`&.${classes.root}`]: {
|
|
646
|
-
filter: 'blur(1px)',
|
|
647
|
-
mixBlendMode: 'darken',
|
|
648
|
-
},
|
|
649
|
-
},
|
|
650
|
-
...(testStateOverrides && {
|
|
651
|
-
[testStateOverrides.styleKey]: {
|
|
652
|
-
[`&.${classes.root}`]: {
|
|
653
|
-
mixBlendMode: 'color',
|
|
654
|
-
},
|
|
655
|
-
},
|
|
656
|
-
}),
|
|
657
|
-
},
|
|
658
|
-
},
|
|
659
|
-
},
|
|
660
|
-
});
|
|
661
|
-
if (!testStateOverrides.prop) {
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
await render(React.createElement(ThemeProvider, { theme: theme }, React.cloneElement(element, {
|
|
665
|
-
[testStateOverrides.prop]: testStateOverrides.value,
|
|
666
|
-
})));
|
|
667
|
-
(0, chai_1.expect)(document.querySelector(`.${classes.root}`)).toHaveComputedStyle({
|
|
668
|
-
filter: 'blur(1px)', // still valid in root
|
|
669
|
-
mixBlendMode: 'color', // overridden by `styleKey`
|
|
670
|
-
});
|
|
671
|
-
});
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* MUI theme has a components section that allows specifying custom variants.
|
|
676
|
-
* Components from @inheritComponent
|
|
677
|
-
*/
|
|
678
|
-
function testThemeVariants(element, getOptions) {
|
|
679
|
-
describe('theme variants:', () => {
|
|
680
|
-
it("respect theme's variants", async function test(t = {}) {
|
|
681
|
-
if (window.navigator.userAgent.includes('jsdom')) {
|
|
682
|
-
// @ts-ignore
|
|
683
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
684
|
-
this?.skip?.() ?? t?.skip();
|
|
685
|
-
}
|
|
686
|
-
const { muiName, testVariantProps, render, ThemeProvider, createTheme } = getOptions();
|
|
687
|
-
if (!testVariantProps) {
|
|
688
|
-
throw new Error('missing testVariantProps');
|
|
689
|
-
}
|
|
690
|
-
if (!muiName) {
|
|
691
|
-
throwMissingPropError('muiName');
|
|
692
|
-
}
|
|
693
|
-
if (!render) {
|
|
694
|
-
throwMissingPropError('render');
|
|
695
|
-
}
|
|
696
|
-
if (!ThemeProvider) {
|
|
697
|
-
throwMissingPropError('ThemeProvider');
|
|
698
|
-
}
|
|
699
|
-
if (!createTheme) {
|
|
700
|
-
throwMissingPropError('createTheme');
|
|
701
|
-
}
|
|
702
|
-
const testStyle = {
|
|
703
|
-
mixBlendMode: 'darken',
|
|
704
|
-
};
|
|
705
|
-
const theme = createTheme({
|
|
706
|
-
components: {
|
|
707
|
-
[muiName]: {
|
|
708
|
-
variants: [
|
|
709
|
-
{
|
|
710
|
-
props: testVariantProps,
|
|
711
|
-
style: testStyle,
|
|
712
|
-
},
|
|
713
|
-
],
|
|
714
|
-
},
|
|
715
|
-
},
|
|
716
|
-
});
|
|
717
|
-
const { getByTestId } = await render(React.createElement(ThemeProvider, { theme: theme },
|
|
718
|
-
React.cloneElement(element, { ...testVariantProps, 'data-testid': 'with-props' }),
|
|
719
|
-
React.cloneElement(element, { 'data-testid': 'without-props' })));
|
|
720
|
-
(0, chai_1.expect)(getByTestId('with-props')).to.toHaveComputedStyle(testStyle);
|
|
721
|
-
(0, chai_1.expect)(getByTestId('without-props')).not.to.toHaveComputedStyle(testStyle);
|
|
722
|
-
});
|
|
723
|
-
it('supports custom variant', async function test(t = {}) {
|
|
724
|
-
if (window.navigator.userAgent.includes('jsdom')) {
|
|
725
|
-
// @ts-ignore
|
|
726
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
727
|
-
this?.skip?.() ?? t?.skip();
|
|
728
|
-
}
|
|
729
|
-
const { muiName, testCustomVariant, render, ThemeProvider, createTheme } = getOptions();
|
|
730
|
-
if (!ThemeProvider) {
|
|
731
|
-
throwMissingPropError('ThemeProvider');
|
|
732
|
-
}
|
|
733
|
-
if (!createTheme) {
|
|
734
|
-
throwMissingPropError('createTheme');
|
|
735
|
-
}
|
|
736
|
-
if (!testCustomVariant) {
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
const theme = createTheme({
|
|
740
|
-
components: {
|
|
741
|
-
[muiName]: {
|
|
742
|
-
styleOverrides: {
|
|
743
|
-
root: ({ ownerState }) => ({
|
|
744
|
-
...(ownerState.variant === 'unknown' && {
|
|
745
|
-
mixBlendMode: 'darken',
|
|
746
|
-
}),
|
|
747
|
-
}),
|
|
748
|
-
},
|
|
749
|
-
},
|
|
750
|
-
},
|
|
751
|
-
});
|
|
752
|
-
const { getByTestId } = await render(React.createElement(ThemeProvider, { theme: theme }, React.cloneElement(element, { variant: 'unknown', 'data-testid': 'custom-variant' })));
|
|
753
|
-
(0, chai_1.expect)(getByTestId('custom-variant')).toHaveComputedStyle({ mixBlendMode: 'darken' });
|
|
754
|
-
});
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* MUI theme supports custom palettes.
|
|
759
|
-
* The components that iterate over the palette via `variants` should be able to render with or without applying the custom palette styles.
|
|
760
|
-
*/
|
|
761
|
-
function testThemeCustomPalette(element, getOptions) {
|
|
762
|
-
describe('theme extended palette:', () => {
|
|
763
|
-
it('should render without errors', function test(t = {}) {
|
|
764
|
-
const { render, ThemeProvider, createTheme } = getOptions();
|
|
765
|
-
if (!window.navigator.userAgent.includes('jsdom') ||
|
|
766
|
-
!render ||
|
|
767
|
-
!ThemeProvider ||
|
|
768
|
-
!createTheme) {
|
|
769
|
-
// @ts-ignore
|
|
770
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
771
|
-
this?.skip?.() ?? t?.skip();
|
|
772
|
-
}
|
|
773
|
-
// @ts-ignore
|
|
774
|
-
const theme = createTheme({
|
|
775
|
-
palette: {
|
|
776
|
-
custom: {
|
|
777
|
-
main: '#ff5252',
|
|
778
|
-
},
|
|
779
|
-
unknown: null,
|
|
780
|
-
custom2: {
|
|
781
|
-
main: {
|
|
782
|
-
blue: {
|
|
783
|
-
dark: '#FFCC00',
|
|
784
|
-
},
|
|
785
|
-
},
|
|
786
|
-
},
|
|
787
|
-
},
|
|
788
|
-
});
|
|
789
|
-
// @ts-ignore
|
|
790
|
-
(0, chai_1.expect)(() => render(React.createElement(ThemeProvider, { theme: theme }, element))).not.to.throw();
|
|
791
|
-
});
|
|
792
|
-
});
|
|
793
|
-
}
|
|
794
|
-
const fullSuite = {
|
|
795
|
-
componentProp: testComponentProp,
|
|
796
|
-
componentsProp: testComponentsProp,
|
|
797
|
-
mergeClassName: testClassName,
|
|
798
|
-
propsSpread: testPropsSpread,
|
|
799
|
-
refForwarding: describeRef,
|
|
800
|
-
rootClass: testRootClass,
|
|
801
|
-
slotPropsProp: testSlotPropsProp,
|
|
802
|
-
slotPropsCallback: testSlotPropsCallback,
|
|
803
|
-
slotPropsCallbackWithPropsAsOwnerState: testSlotPropsCallbackWithPropsAsOwnerState,
|
|
804
|
-
slotsProp: testSlotsProp,
|
|
805
|
-
themeDefaultProps: testThemeDefaultProps,
|
|
806
|
-
themeStyleOverrides: testThemeStyleOverrides,
|
|
807
|
-
themeVariants: testThemeVariants,
|
|
808
|
-
themeCustomPalette: testThemeCustomPalette,
|
|
809
|
-
};
|
|
810
|
-
/**
|
|
811
|
-
* Tests various aspects of a component that should be equal across MUI
|
|
812
|
-
* components.
|
|
813
|
-
*/
|
|
814
|
-
function describeConformance(minimalElement, getOptions) {
|
|
815
|
-
let originalMatchmedia;
|
|
816
|
-
const storage = {};
|
|
817
|
-
beforeEach(() => {
|
|
818
|
-
originalMatchmedia = window.matchMedia;
|
|
819
|
-
// Create mocks of localStorage getItem and setItem functions
|
|
820
|
-
Object.defineProperty(globalThis, 'localStorage', {
|
|
821
|
-
value: {
|
|
822
|
-
getItem: (key) => storage[key],
|
|
823
|
-
setItem: (key, value) => {
|
|
824
|
-
storage[key] = value;
|
|
825
|
-
},
|
|
826
|
-
},
|
|
827
|
-
configurable: true,
|
|
828
|
-
});
|
|
829
|
-
window.matchMedia = () => ({
|
|
830
|
-
// Keep mocking legacy methods because @mui/material v5 still uses them
|
|
831
|
-
addListener: () => { },
|
|
832
|
-
addEventListener: () => { },
|
|
833
|
-
removeListener: () => { },
|
|
834
|
-
removeEventListener: () => { },
|
|
835
|
-
});
|
|
836
|
-
});
|
|
837
|
-
afterEach(() => {
|
|
838
|
-
window.matchMedia = originalMatchmedia;
|
|
839
|
-
});
|
|
840
|
-
const { after: runAfterHook = () => { }, only = Object.keys(fullSuite), slots, skip = [], } = getOptions();
|
|
841
|
-
let filteredTests = Object.keys(fullSuite).filter((testKey) => only.includes(testKey) && !skip.includes(testKey));
|
|
842
|
-
const slotBasedTests = [
|
|
843
|
-
'slotsProp',
|
|
844
|
-
'slotPropsProp',
|
|
845
|
-
'slotPropsCallback',
|
|
846
|
-
'slotPropsCallbackWithPropsAsOwnerState',
|
|
847
|
-
];
|
|
848
|
-
if (!slots) {
|
|
849
|
-
// if `slots` are not defined, do not run tests that depend on them
|
|
850
|
-
filteredTests = filteredTests.filter((testKey) => !slotBasedTests.includes(testKey));
|
|
851
|
-
}
|
|
852
|
-
after(runAfterHook);
|
|
853
|
-
filteredTests.forEach((testKey) => {
|
|
854
|
-
const test = fullSuite[testKey];
|
|
855
|
-
test(minimalElement, getOptions);
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
exports.default = (0, createDescribe_1.default)('MUI component API', describeConformance);
|
|
859
|
-
//# sourceMappingURL=describeConformance.js.map
|