Skip to content

Commit c627ade

Browse files
authored
feat(dom): DOM - toHaveSomeStyle (#158)
1 parent 09f28e1 commit c627ade

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

packages/dom/src/lib/ElementAssertion.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,50 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
216216
});
217217
}
218218

219+
/**
220+
* Asserts that the element has one or more of the specified CSS styles.
221+
*
222+
* @example
223+
* ```
224+
* expect(component).toHaveSomeStyle({ color: 'green', display: 'block' });
225+
* ```
226+
*
227+
* @param expected the expected CSS style/s.
228+
* @returns the assertion instance.
229+
*/
230+
231+
public toHaveSomeStyle(expected: Partial<CSSStyleDeclaration>): this {
232+
233+
const [expectedStyle, elementProcessedStyle] = getExpectedAndReceivedStyles(this.actual, expected);
234+
235+
if (!expectedStyle || !elementProcessedStyle) {
236+
throw new Error("No available styles.");
237+
}
238+
239+
const hasSomeStyle = Object.entries(expectedStyle).some(([expectedProp, expectedValue]) => {
240+
return Object.entries(elementProcessedStyle).some(([receivedProp, receivedValue]) => {
241+
return equal(expectedProp, receivedProp) && equal(expectedValue, receivedValue);
242+
});
243+
});
244+
245+
const error = new AssertionError({
246+
actual: this.actual,
247+
message: `Expected the element to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`,
248+
});
249+
250+
const invertedError = new AssertionError({
251+
actual: this.actual,
252+
// eslint-disable-next-line max-len
253+
message: `Expected the element NOT to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`,
254+
});
255+
256+
return this.execute({
257+
assertWhen: hasSomeStyle,
258+
error,
259+
invertedError,
260+
});
261+
}
262+
219263
/**
220264
* Helper method to assert the presence or absence of class names.
221265
*

packages/dom/test/unit/lib/ElementAssertion.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,47 @@ describe("[Unit] ElementAssertion.test.ts", () => {
368368
});
369369
});
370370
});
371+
372+
describe(".toHaveSomeStyle", () => {
373+
context("when the element contains one or more expected styles", () => {
374+
it("returns the assertion instance", () => {
375+
const { getByTestId } = render(
376+
<div
377+
style={{ color: "blue", maxHeight: "3rem", width: "2rem" }}
378+
data-testid="test-div"
379+
/>,
380+
);
381+
const divTest = getByTestId("test-div");
382+
const test = new ElementAssertion(divTest);
383+
384+
expect(test.toHaveSomeStyle({ color: "red", display: "flex", height: "3rem", width: "2rem" })).toBeEqual(test);
385+
386+
expect(() => test.not.toHaveSomeStyle({ color: "blue" }))
387+
.toThrowError(AssertionError)
388+
// eslint-disable-next-line max-len
389+
.toHaveMessage("Expected the element NOT to match some of the following styles:\n{\n \"color\": \"rgb(0, 0, 255)\"\n}");
390+
});
391+
});
392+
393+
context("when the element does not contain any of the expected styles", () => {
394+
it("throws an assertion error", () => {
395+
const { getByTestId } = render(
396+
<div
397+
className="foo bar test"
398+
style={{ border: "1px solid black", color: "blue", display: "block" }}
399+
data-testid="test-div"
400+
/>,
401+
);
402+
const divTest = getByTestId("test-div");
403+
const test = new ElementAssertion(divTest);
404+
405+
expect(() => test.toHaveSomeStyle({ color: "red", display: "flex" }))
406+
.toThrowError(AssertionError)
407+
// eslint-disable-next-line max-len
408+
.toHaveMessage("Expected the element to match some of the following styles:\n{\n \"color\": \"rgb(255, 0, 0)\",\n \"display\": \"flex\"\n}");
409+
410+
expect(test.not.toHaveSomeStyle({ border: "1px solid blue", color: "red", display: "flex" })).toBeEqual(test);
411+
});
412+
});
413+
});
371414
});

0 commit comments

Comments
 (0)