Skip to content

Commit

Permalink
Add media and state for asserting styles.
Browse files Browse the repository at this point in the history
  • Loading branch information
ankeetmaini committed Apr 22, 2020
1 parent 1d05089 commit 964470f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 7 deletions.
74 changes: 74 additions & 0 deletions packages/jest/src/__tests__/matchers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,78 @@ describe('toHaveCompliedCss', () => {
color: 'blue',
});
});

it('should match styles with state', () => {
const { getByText } = render(
<div
css={{
fontSize: '12px',
':hover': {
transform: 'scale(2)',
},
}}>
hello world
</div>
);
const el = getByText('hello world');
expect(el).toHaveCompiledCss('transform', 'scale(2)', { state: 'hover' });
expect(el).not.toHaveCompiledCss('transform', 'scale(2)', { state: 'active' });
});

it('should match styles with state', () => {
const { getByText } = render(
<div
css={{
fontSize: '12px',
':hover': {
transform: 'scale(2)',
},
':active': {
color: 'blue',
},
}}>
hello world
</div>
);
const el = getByText('hello world');
expect(el).not.toHaveCompiledCss('color', 'blue', { state: 'hover' });
expect(el).not.toHaveCompiledCss('transform', 'scale(2)', { state: 'active' });
expect(el).toHaveCompiledCss('color', 'blue', { state: 'active' });
});

it('should match styles with media', () => {
const { getByText } = render(
<div
css={{
color: 'green',
'@media screen': {
color: 'yellow',
},
}}>
hello world
</div>
);
const el = getByText('hello world');
expect(el).toHaveCompiledCss('color', 'green');
expect(el).toHaveCompiledCss('color', 'yellow', { media: '@media screen' });
});

it('should match styles with media and state', () => {
const { getByText } = render(
<div
css={{
color: 'green',
'@media screen': {
color: 'yellow',
':hover': {
background: 'red',
},
},
}}>
hello world
</div>
);
const el = getByText('hello world');
expect(el).toHaveCompiledCss('background', 'red', { media: '@media screen', state: 'hover' });
});
});
5 changes: 3 additions & 2 deletions packages/jest/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
declare global {
type MatchFilter = Partial<Record<'state' | 'media', string>>;
namespace jest {
interface Matchers<R> {
toHaveCompiledCss(properties: { [key: string]: string }): R;
toHaveCompiledCss(property: string, value: string): R;
toHaveCompiledCss(properties: { [key: string]: string }, matchFilter?: MatchFilter): R;
toHaveCompiledCss(property: string, value: string, matchFilter?: MatchFilter): R;
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions packages/jest/src/matchers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ const getMountedProperties = () =>
)
.join(' ');

// sorry but using ? was throwing TS off
type Arg = [{ [key: string]: string }, MatchFilter?];
export function toHaveCompiledCss(
this: jest.MatcherUtils,
element: HTMLElement,
...args: [{ [key: string]: string } | string, string]
...args: [Arg | string, string, MatchFilter?]
): jest.CustomMatcherResult {
const [property, value] = args;
const [property, value, matchFilter] = args;
const { media, state } = matchFilter || { media: undefined, state: undefined };
const properties = typeof property === 'string' ? { [property]: value } : property;
const inlineStyleTag = element.parentElement && element.parentElement.querySelector('style');
const styleElements: HTMLStyleElement[] =
Expand Down Expand Up @@ -54,9 +57,11 @@ export function toHaveCompiledCss(
}

classNames.forEach(c => {
if (css.includes(c)) {
const found = stylesToFind.filter(s => css.includes(s));
foundStyles.push(...found);
let matcher = c;
if (state) matcher += `:${state}`;
if (media) matcher = `${media}{.*${matcher}`;
if (css.match(matcher)) {
foundStyles.push(...stylesToFind.filter(s => css.includes(s)));
}
});
}
Expand Down

0 comments on commit 964470f

Please sign in to comment.