Skip to content

Commit 03d8887

Browse files
committed
refactor: logic improved
1 parent 38a575c commit 03d8887

2 files changed

Lines changed: 44 additions & 33 deletions

File tree

packages/dom/src/lib/ElementAssertion.ts

Lines changed: 5 additions & 13 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

@@ -196,20 +196,12 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
196196
*/
197197

198198
public toHaveStyle(expected: Partial<CSSStyleDeclaration>): this {
199-
if (!this.actual.ownerDocument.defaultView) {
200-
throw new Error("The element is not attached to a document with a default view.");
201-
}
202-
if (!(this.actual instanceof HTMLElement)) {
203-
throw new Error("The element is not an HTMLElement.");
204-
}
205-
206-
const window = this.actual.ownerDocument.defaultView;
207199

208-
const received = window.getComputedStyle(this.actual);
200+
const [expectedStyle, receivedStyle] = getExpectedAndReceivedStyles(this.actual, expected);
209201

210-
const { props, expectedStyle } = normalizeStyles(expected);
211-
212-
const receivedStyle = getReceivedStyle(props, received);
202+
if (!expectedStyle || !receivedStyle) {
203+
throw new Error("Currently there are no available styles.");
204+
}
213205

214206
const error = new AssertionError({
215207
actual: this.actual,
Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
export interface CssAtRuleAST {
2-
declarations: StyleDeclaration[];
3-
rules: Rule[];
4-
}
5-
6-
interface Rule {
7-
declarations: StyleDeclaration[];
8-
selectors: string[];
9-
}
10-
111
interface StyleDeclaration extends Record<string, string> {
122
property: string;
133
value: string;
144
}
155

16-
export const normalizeStyles = (css: Partial<CSSStyleDeclaration>):
17-
{ expectedStyle: StyleDeclaration; props: string[]; } => {
6+
function normalizeStyles(css: Partial<CSSStyleDeclaration>): StyleDeclaration {
187
const normalizer = document.createElement("div");
198
document.body.appendChild(normalizer);
209

21-
const { props, expectedStyle } = Object.entries(css).reduce(
10+
const { expectedStyle } = Object.entries(css).reduce(
2211
(acc, [property, value]) => {
2312

2413
if (typeof value !== "string") {
@@ -37,20 +26,50 @@ export const normalizeStyles = (css: Partial<CSSStyleDeclaration>):
3726
...acc.expectedStyle,
3827
[property]: normalizedValue,
3928
},
40-
props: [...acc.props, property],
4129
};
4230
},
43-
{ expectedStyle: {} as StyleDeclaration, props: [] as string[] },
31+
{ expectedStyle: {} as StyleDeclaration },
4432
);
4533

4634
document.body.removeChild(normalizer);
4735

48-
return { expectedStyle, props };
49-
};
36+
return expectedStyle;
37+
}
38+
39+
function getReceivedStyle (props: string[], received: CSSStyleDeclaration): StyleDeclaration {
5040

51-
export const getReceivedStyle = (props: string[], received: CSSStyleDeclaration): StyleDeclaration => {
5241
return props.reduce((acc, prop) => {
53-
acc[prop] = received?.getPropertyValue(prop).trim();
54-
return acc;
42+
43+
const actualStyle = received.getPropertyValue(prop).trim();
44+
45+
return actualStyle
46+
? { ...acc, [prop]: actualStyle }
47+
: acc;
48+
5549
}, {} as StyleDeclaration);
50+
}
51+
52+
export const getExpectedAndReceivedStyles =
53+
(actual: Element, expected: Partial<CSSStyleDeclaration>): StyleDeclaration[] => {
54+
if (!actual.ownerDocument.defaultView) {
55+
throw new Error("The element is not attached to a document with a default view.");
56+
}
57+
if (!(actual instanceof HTMLElement)) {
58+
throw new Error("The element is not an HTMLElement.");
59+
}
60+
61+
const window = actual.ownerDocument.defaultView;
62+
63+
const rawElementStyles = window.getComputedStyle(actual);
64+
65+
const expectedStyle = normalizeStyles(expected);
66+
67+
const styleKeys = Object.keys(expectedStyle);
68+
69+
const elementProcessedStyle = getReceivedStyle(styleKeys, rawElementStyles);
70+
71+
return [
72+
expectedStyle,
73+
elementProcessedStyle,
74+
];
5675
};

0 commit comments

Comments
 (0)