emotion
emotion copied to clipboard
PrettyFormatPluginError: Cannot delete property 'className' of #<Object>
Current behavior:
Components that have a static defaultProps
(with className
set to ''
) cannot be serialized using the @emotion/jest/enzyme-serializer
(and probably also with @emotion/jest/serializer
as it's using shared logic).
The tests are throwing:
PrettyFormatPluginError: Cannot delete property 'className' of #<Object>
TypeError: Cannot delete property 'className' of #<Object>
at clean (node_modules/@emotion/jest/dist/create-serializer-3afd473f.cjs.dev.js:506:19)
at Object.serialize (node_modules/@emotion/jest/dist/create-serializer-3afd473f.cjs.dev.js:537:5)
at Object.serialize (node_modules/@emotion/jest/dist/create-enzyme-serializer-c92dc591.cjs.dev.js:31:32)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at printer (node_modules/pretty-format/build/index.js:379:12)
at node_modules/pretty-format/build/plugins/lib/markup.js:73:13
at Array.map (<anonymous>)
at printChildren (node_modules/pretty-format/build/plugins/lib/markup.js:67:6)
at Object.serialize (node_modules/pretty-format/build/plugins/ReactElement.js:144:35)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at printer (node_modules/pretty-format/build/index.js:379:12)
at Object.serialize (node_modules/@emotion/jest/dist/create-serializer-3afd473f.cjs.dev.js:539:22)
at Object.serialize (node_modules/@emotion/jest/dist/create-enzyme-serializer-c92dc591.cjs.dev.js:31:32)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at printer (node_modules/pretty-format/build/index.js:379:12)
at node_modules/pretty-format/build/plugins/lib/markup.js:33:21
at Array.map (<anonymous>)
at printProps (node_modules/pretty-format/build/plugins/lib/markup.js:31:6)
at Object.serialize (node_modules/pretty-format/build/plugins/ReactTestComponent.js:45:36)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at printer (node_modules/pretty-format/build/index.js:379:12)
at Object.serialize (node_modules/@emotion/jest/dist/create-serializer-3afd473f.cjs.dev.js:539:22)
at Object.serialize (node_modules/@emotion/jest/dist/create-enzyme-serializer-c92dc591.cjs.dev.js:31:32)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at printer (node_modules/pretty-format/build/index.js:379:12)
at node_modules/@emotion/jest/dist/create-enzyme-serializer-c92dc591.cjs.dev.js:26:18
at Object.print (node_modules/enzyme-to-json/createSerializer.js:21:14)
at Object.serialize (node_modules/@emotion/jest/dist/create-enzyme-serializer-c92dc591.cjs.dev.js:24:33)
at printPlugin (node_modules/pretty-format/build/index.js:330:16)
at format (node_modules/pretty-format/build/index.js:567:16)
at __EXTERNAL_MATCHER_TRAP__ (node_modules/expect/build/index.js:386:30)
at Object.throwingMatcher (node_modules/expect/build/index.js:387:15)
at Object.<anonymous> ([redacted])
Looks like t's failing on this line: https://github.com/emotion-js/emotion/blob/main/packages/jest/src/create-serializer.js#L174
To reproduce:
Define a component with defaultProps. Use either the syntax:
class SomeComponent extends Component {
static defaultProps = {
className: ''
}
// ...
}
or
class SomeComponent extends Component {
// ...
}
SomeComponent.defaultProps = {
className: '',
}
then prepare a test where this component is used and serialized to a snapshot:
import React from "react";
import { shallow } from "enzyme";
import SomeComponent from "./SomeComponent";
Enzyme.configure({ adapter: new Adapter() });
describe("SomeComponent", () => {
it("should match snapshot", function () {
const node = shallow(<SomeComponent />);
expect(node).toMatchSnapshot();
});
});
Expected behavior:
Test should run and either fail if snapshots are not matching, or succeed if they are matching.
Actual behavior: The test fails on the serialization process.
Environment information:
-
react
version:^17.0.2
-
@emotion/css
version:11.5.0
-
@emotion/jest
version:11.5.0
-
@emotion/react
version:11.5.0
-
@emotion/styled
version:11.3.0
-
jest
version:^27.5.1
-
ts-jest
version:^27.1.3
-
babel-jest
version:^27.5.1
Jest config:
{
preset: 'ts-jest/presets/js-with-babel',
displayName: 'client',
automock: false,
timers: 'legacy',
testTimeout: 20000,
testRunner: 'jest-jasmine2',
verbose: true,
coveragePathIgnorePatterns: [
// [redacted]
],
collectCoverageFrom: [
// [redacted]
],
testPathIgnorePatterns: [
// [redacted]
],
snapshotSerializers: ['@emotion/jest/enzyme-serializer'],
testEnvironment: 'jsdom',
setupFiles: ['<rootDir>/jest-setup.js'],
globals: {
window: {},
document: {},
'ts-jest': {
diagnostics: false,
},
},
transformIgnorePatterns: [
// [redacted]
],
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest',
},
}
I've added such tests locally and they pass: https://github.com/emotion-js/emotion/commit/6f678f894623ab3a7c18074fd7d6a5f59763d037
You'd have to provide a full runnable repro case for me to investigate it any further.
Hi, I managed to reproduce this consistently with a node passed in a render prop: PR #2959
(I'll try to find the cause and submit a real PR if I find the time :sweat_smile: )
Forgot to mention here that I updated my PR to suggest a fix!
@Andarist - are you able to get this merged?