Skip to content

Commit

Permalink
fix(atomic,core,react): jest compatibility (#1233)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anber committed Apr 3, 2023
1 parent 7196993 commit 3402908
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 33 deletions.
7 changes: 7 additions & 0 deletions .changeset/proud-boats-study.md
@@ -0,0 +1,7 @@
---
'@linaria/atomic': patch
'@linaria/core': patch
'@linaria/react': patch
---

Usages of `styled` and `css` in Jest no longer trigger the "Using the … tag in runtime is not supported" exception.
3 changes: 2 additions & 1 deletion packages/atomic/package.json
Expand Up @@ -60,7 +60,8 @@
"ts-invariant": "^0.10.3"
},
"devDependencies": {
"@babel/types": "^7.20.2"
"@babel/types": "^7.20.2",
"@types/node": "^17.0.39"
},
"peerDependencies": {
"react": ">=16"
Expand Down
7 changes: 7 additions & 0 deletions packages/atomic/src/css.ts
Expand Up @@ -7,7 +7,14 @@ type CSS = (
...exprs: Array<string | number | CSSProperties>
) => LinariaClassName;

let idx = 0;

export const css: CSS = () => {
if (process.env.NODE_ENV === 'test') {
// eslint-disable-next-line no-plusplus
return `mocked-atomic-css-${idx++}` as LinariaClassName;
}

throw new Error(
'Using the "css" tag in runtime is not supported. Make sure you have set up the Babel plugin correctly.'
);
Expand Down
6 changes: 5 additions & 1 deletion packages/atomic/tsconfig.json
@@ -1,5 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": { "paths": {}, "rootDir": "src/" },
"compilerOptions": {
"paths": {},
"rootDir": "src/",
"types": ["node"]
},
"references": [{ "path": "../core" }, { "path": "../logger" }, { "path": "../react" }, { "path": "../utils" }]
}
7 changes: 7 additions & 0 deletions packages/core/src/css.ts
Expand Up @@ -8,7 +8,14 @@ type CSS = (
...exprs: Array<string | number | CSSProperties | StyledMeta>
) => LinariaClassName;

let idx = 0;

const css: CSS = () => {
if (process.env.NODE_ENV === 'test') {
// eslint-disable-next-line no-plusplus
return `mocked-css-${idx++}` as LinariaClassName;
}

throw new Error(
'Using the "css" tag in runtime is not supported. Make sure you have set up the Babel plugin correctly.'
);
Expand Down
26 changes: 13 additions & 13 deletions packages/react/__tests__/__snapshots__/styled.test.tsx.snap
Expand Up @@ -2,7 +2,7 @@

exports[`applies CSS variables in style prop 1`] = `
<div
className="abcdefg"
className="mocked-styled-2 abcdefg"
size={24}
style={
Object {
Expand All @@ -24,7 +24,7 @@ exports[`does not filter attributes for components 1`] = `

exports[`does not filter attributes for kebab cased custom elements 1`] = `
<my-element
className="abcdefg"
className="mocked-styled-14 abcdefg"
unknownAttribute="voila"
>
This is a test
Expand All @@ -33,7 +33,7 @@ exports[`does not filter attributes for kebab cased custom elements 1`] = `

exports[`does not filter attributes for unknown tag 1`] = `
<definitelyunknowntag
className="abcdefg"
className="mocked-styled-16 abcdefg"
hoverClass="voila"
>
This is a test
Expand All @@ -42,7 +42,7 @@ exports[`does not filter attributes for unknown tag 1`] = `

exports[`does not filter attributes for upper camel cased custom elements 1`] = `
<View
className="abcdefg"
className="mocked-styled-15 abcdefg"
hoverClass="voila"
>
This is a test
Expand All @@ -51,31 +51,31 @@ exports[`does not filter attributes for upper camel cased custom elements 1`] =

exports[`filters unknown html attributes for HTML tag 1`] = `
<div
className="abcdefg"
className="mocked-styled-13 abcdefg"
>
This is a test
</div>
`;

exports[`forwards as prop when wrapping another styled component 1`] = `
<a
className="hijklmn abcdefg"
className="mocked-styled-12 abcdefg hijklmn abcdefg"
>
This is a test
</a>
`;

exports[`handles wrapping another styled component 1`] = `
<div
className="hijklmn abcdefg"
className="mocked-styled-10 abcdefg hijklmn abcdefg"
>
This is a test
</div>
`;

exports[`merges CSS variables with custom style prop 1`] = `
<div
className="abcdefg"
className="mocked-styled-3 abcdefg"
style={
Object {
"--foo": "tomato",
Expand All @@ -97,23 +97,23 @@ exports[`provides linaria component className for composition as last item in pr

exports[`renders component with display name and class name 1`] = `
<div
className="abcdefg"
className="mocked-styled-1 abcdefg"
>
This is a test
</div>
`;

exports[`renders tag with display name and class name 1`] = `
<h1
className="abcdefg"
className="mocked-styled-0 abcdefg"
>
This is a test
</h1>
`;

exports[`replaces custom component with as prop for primitive 1`] = `
<a
className="abcdefg"
className="mocked-styled-7 abcdefg"
id="test"
>
This is a test
Expand All @@ -122,7 +122,7 @@ exports[`replaces custom component with as prop for primitive 1`] = `

exports[`replaces primitive with as prop for custom component 1`] = `
<div
className="abcdefg"
className="mocked-styled-8 abcdefg"
foo="bar"
id="test"
style={
Expand All @@ -137,7 +137,7 @@ exports[`replaces primitive with as prop for custom component 1`] = `

exports[`replaces simple component with as prop 1`] = `
<a
className="abcdefg"
className="mocked-styled-6 abcdefg"
id="test"
>
This is a test
Expand Down
6 changes: 6 additions & 0 deletions packages/react/__tests__/styled.test.tsx
Expand Up @@ -273,6 +273,10 @@ it('provides linaria component className for composition as last item in props.c
});

it('throws when using as tag for template literal', () => {
// styled uses process.env.NODE_ENV to determine if it's running in a test environment
const nodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;

expect(
() =>
styled('div')`
Expand All @@ -286,6 +290,8 @@ it('throws when using as tag for template literal', () => {
color: blue;
`
).toThrow('Using the "styled" tag in runtime is not supported');

process.env.NODE_ENV = nodeEnv;
});

it('can get rest keys from object', () => {
Expand Down
17 changes: 14 additions & 3 deletions packages/react/src/styled.ts
Expand Up @@ -105,6 +105,8 @@ interface IProps {
[props: string]: unknown;
}

let idx = 0;

// Components with props are not allowed
function styled(
componentWithStyle: () => any
Expand Down Expand Up @@ -132,8 +134,17 @@ function styled(
component: 'The target component should have a className prop'
): never;
function styled(tag: any): any {
// eslint-disable-next-line no-plusplus
let mockedClass = `mocked-styled-${idx++}`;
if (tag?.__linaria?.className) {
mockedClass += ` ${tag.__linaria.className}`;
}

return (options: Options) => {
if (process.env.NODE_ENV !== 'production') {
if (
process.env.NODE_ENV !== 'production' &&
process.env.NODE_ENV !== 'test'
) {
if (Array.isArray(options)) {
// We received a strings array since it's used as a tag
throw new Error(
Expand All @@ -143,7 +154,7 @@ function styled(tag: any): any {
}

const render = (props: any, ref: any) => {
const { as: component = tag, class: className } = props;
const { as: component = tag, class: className = mockedClass } = props;
const shouldKeepProps =
options.propsAsIs === undefined
? !(
Expand Down Expand Up @@ -213,7 +224,7 @@ function styled(tag: any): any {

// These properties will be read by the babel plugin for interpolation
(Result as any).__linaria = {
className: options.class,
className: options.class ?? mockedClass,
extends: tag,
};

Expand Down
32 changes: 17 additions & 15 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3402908

Please sign in to comment.