Skip to content

Commit 5bedb23

Browse files
committed
Add: function getExepectedAndReceivedStyles refactored and included on matchers
1 parent 9e88d39 commit 5bedb23

File tree

2 files changed

+42
-35
lines changed

2 files changed

+42
-35
lines changed

packages/dom/src/lib/ElementAssertion.ts

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Assertion, AssertionError } from "@assertive-ts/core";
22
import equal from "fast-deep-equal";
33

4-
import { getReceivedStyle, normalizeStyles } from "./helpers/helpers";
4+
import { getExpectedAndReceivedStyles } from "./helpers/helpers";
55

66
export class ElementAssertion<T extends Element> extends Assertion<T> {
77

@@ -158,20 +158,12 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
158158
*/
159159

160160
public toHaveStyle(expected: Partial<CSSStyleDeclaration>): this {
161-
if (!this.actual.ownerDocument.defaultView) {
162-
throw new Error("The element is not attached to a document with a default view.");
163-
}
164-
if (!(this.actual instanceof HTMLElement)) {
165-
throw new Error("The element is not an HTMLElement.");
166-
}
167-
168-
const window = this.actual.ownerDocument.defaultView;
169-
170-
const received = window.getComputedStyle(this.actual);
171161

172-
const { props, expectedStyle } = normalizeStyles(expected);
162+
const [expectedStyle, receivedStyle] = getExpectedAndReceivedStyles(this.actual, expected);
173163

174-
const receivedStyle = getReceivedStyle(props, received);
164+
if (!expectedStyle || !receivedStyle) {
165+
throw new Error("No available styles.");
166+
}
175167

176168
const error = new AssertionError({
177169
actual: this.actual,
@@ -191,51 +183,43 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
191183
}
192184

193185
/**
194-
* Asserts that the element has the one of the specified CSS style.
186+
* Asserts that the element has one or more of the specified CSS style.
195187
*
196188
* @example
197189
* ```
198-
* expect(component).toHaveStyle({ color: 'green', display: 'block' });
190+
* expect(component).toHaveSomeStyle({ color: 'green', display: 'block' });
199191
* ```
200192
*
201-
* @param expected the expected CSS styles.
193+
* @param expected the expected CSS style/s.
202194
* @returns the assertion instance.
203195
*/
204196

205197
public toHaveSomeStyle(expected: Partial<CSSStyleDeclaration>): this {
206198

207-
if (!this.actual.ownerDocument.defaultView) {
208-
throw new Error("The element is not attached to a document with a default view.");
209-
}
210-
if (!(this.actual instanceof HTMLElement)) {
211-
throw new Error("The element is not an HTMLElement.");
212-
}
213-
214-
const window = this.actual.ownerDocument.defaultView;
199+
const [expectedStyle, receivedStyle] = getExpectedAndReceivedStyles(this.actual, expected);
215200

216-
const received = window.getComputedStyle(this.actual);
217-
218-
const { props, expectedStyle } = normalizeStyles(expected);
219-
220-
const receivedStyle = getReceivedStyle(props, received);
201+
if (!expectedStyle || !receivedStyle) {
202+
throw new Error("No available styles.");
203+
}
221204

222-
const a = Object.values(receivedStyle).some((receivedItem, idx) => {
205+
const hasSomeStyle = Object.values(receivedStyle).some((receivedItem, idx) => {
223206
const expectedItem = Object.values(expectedStyle)[idx];
224207
return equal(expectedItem, receivedItem);
225208
});
226209

227210
const error = new AssertionError({
228211
actual: this.actual,
229-
message: "Error",
212+
message: `Expected the element to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`,
230213
});
231214

232215
const invertedError = new AssertionError({
233216
actual: this.actual,
234-
message: "Inverted Error",
217+
// eslint-disable-next-line max-len
218+
message: `Expected the element NOT to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`,
235219
});
236220

237221
return this.execute({
238-
assertWhen: a,
222+
assertWhen: hasSomeStyle,
239223
error,
240224
invertedError,
241225
});

packages/dom/src/lib/helpers/helpers.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface StyleDeclaration extends Record<string, string> {
1313
value: string;
1414
}
1515

16-
export const normalizeStyles = (css: Partial<CSSStyleDeclaration>):
16+
const normalizeStyles = (css: Partial<CSSStyleDeclaration>):
1717
{ expectedStyle: StyleDeclaration; props: string[]; } => {
1818
const normalizer = document.createElement("div");
1919
document.body.appendChild(normalizer);
@@ -48,9 +48,32 @@ export const normalizeStyles = (css: Partial<CSSStyleDeclaration>):
4848
return { expectedStyle, props };
4949
};
5050

51-
export const getReceivedStyle = (props: string[], received: CSSStyleDeclaration): StyleDeclaration => {
51+
const getReceivedStyle = (props: string[], received: CSSStyleDeclaration): StyleDeclaration => {
5252
return props.reduce((acc, prop) => {
5353
acc[prop] = received?.getPropertyValue(prop).trim();
5454
return acc;
5555
}, {} as StyleDeclaration);
5656
};
57+
58+
export const getExpectedAndReceivedStyles =
59+
(actual: Element, expected: Partial<CSSStyleDeclaration>): StyleDeclaration[] => {
60+
if (!actual.ownerDocument.defaultView) {
61+
throw new Error("The element is not attached to a document with a default view.");
62+
}
63+
if (!(actual instanceof HTMLElement)) {
64+
throw new Error("The element is not an HTMLElement.");
65+
}
66+
67+
const window = actual.ownerDocument.defaultView;
68+
69+
const received = window.getComputedStyle(actual);
70+
71+
const { props, expectedStyle } = normalizeStyles(expected);
72+
73+
const receivedStyle = getReceivedStyle(props, received);
74+
75+
return [
76+
expectedStyle,
77+
receivedStyle,
78+
];
79+
};

0 commit comments

Comments
 (0)