Skip to content

Commit ce4ce12

Browse files
committed
Basic features covered
1 parent 27b02bb commit ce4ce12

File tree

7 files changed

+286
-20
lines changed

7 files changed

+286
-20
lines changed

karma.conf.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ module.exports = function(config) {
3535
sauceLabs: {
3636
testName: "@zeecoder/container-query",
3737
public: "public"
38+
},
39+
40+
client: {
41+
jasmine: {
42+
// Order of the tests matter, so don't randomise it
43+
random: false
44+
}
3845
}
3946
});
4047
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"babel-regenerator-runtime": "^6.5.0",
2323
"coveralls": "^3.0.2",
2424
"css-loader": "^2.0.2",
25+
"dom-testing-library": "^3.16.1",
2526
"husky": "^1.1.4",
2627
"jasmine-core": "^3.3.0",
2728
"jest": "^23.6.0",

tests/react/Basic/Basic.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import { meta as rawMeta } from "./Basic.pcss";
66
const meta = JSON.parse(rawMeta.slice(1, -1));
77

88
const Basic = () => (
9-
<ContainerQuery meta={meta} className="Basic" id="rendered-component">
9+
<ContainerQuery meta={meta} className="Basic">
1010
{(width, height) => {
1111
return (
12-
<div>
12+
<div className="Basic__content" data-testid="content">
1313
{width}x{height}
1414
</div>
1515
);

tests/react/Basic/Basic.pcss

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
11
.Basic {
2+
color: black;
3+
position: absolute;
4+
width: 100%;
5+
height: 100%;
6+
background-color: rgb(255, 0, 0);
7+
border: 2px solid rgb(255, 255, 255);
8+
--h: 100rh;
9+
--w: 100rw;
10+
11+
@container (width > 100px) {
12+
background-color: rgb(0, 128, 0);
13+
border-width: 4rw;
14+
}
15+
16+
@container (height > 50px) {
217
color: white;
3-
width: 101px;
4-
height: 100px;
5-
background-color: red;
18+
border-width: 4rh;
19+
}
20+
21+
@container (orientation: portrait) {
22+
border-color: rgb(0, 0, 0);
23+
border-width: 2rw;
24+
}
25+
26+
&__content {
27+
text-align: center;
28+
font-size: 50rh;
29+
line-height: 100rh;
630

7-
@container (width > 100px) {
8-
background-color: green;
31+
@container (width > 100px) and (height > 100px) {
32+
font-weight: 700;
33+
font-size: 15rh;
934
}
35+
}
1036
}

tests/react/index.js

Lines changed: 115 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,125 @@
11
import React from "react";
2-
import ReactDOM from "react-dom";
32
import Basic from "./Basic/Basic";
3+
import { wait, getNodeText } from "dom-testing-library";
4+
import {
5+
renderTestComponent,
6+
getByTestId,
7+
changeRootSize,
8+
expectTestComponentToHaveStyle,
9+
expectTestComponentToHaveCustomProperties,
10+
expectElementToHaveStyle
11+
} from "../utils";
412

5-
const delay = time => new Promise(resolve => setTimeout(resolve, time));
13+
// Features covered:
14+
// - Style applying and restoring on width, height and orientation change
15+
// - rw / rh unit applying / removing (With max precision of 4)
16+
// - All the above on a descendant
17+
// - Getting the size from the ContainerQuery component
18+
describe("Basic", () => {
19+
const refs = {};
20+
beforeAll(() => {
21+
renderTestComponent(<Basic />, {
22+
width: 100,
23+
height: 50
24+
});
625

7-
it("should render Basic", async () => {
8-
const div = document.createElement("div");
9-
document.body.appendChild(div);
26+
refs.content = getByTestId("content");
27+
});
1028

11-
ReactDOM.render(<Basic />, div);
29+
it("should not have any of the container queries applied", async () => {
30+
// Assertions before the ResizeObserver kicks in
31+
expect(getNodeText(refs.content)).toBe("1x1");
1232

13-
const rendered = document.getElementById("rendered-component");
33+
// Wait for resize observer to kick in
34+
await wait(() => expect(getNodeText(refs.content)).toBe("100x50"));
1435

15-
// Assertions before the ResizeObserver kicks in
16-
expect(rendered.textContent).toBe("1x1");
36+
expectTestComponentToHaveCustomProperties({
37+
"--w": "100px",
38+
"--h": "50px"
39+
});
1740

18-
// wait a little before asserting
19-
await delay(50);
41+
expectTestComponentToHaveStyle({
42+
backgroundColor: "rgb(255, 0, 0)",
43+
color: "rgb(0, 0, 0)",
44+
border: "2px solid rgb(255, 255, 255)"
45+
});
2046

21-
expect(rendered.textContent).toBe("101x100");
22-
expect(rendered.style.backgroundColor).toBe("green");
47+
expectElementToHaveStyle(refs.content, {
48+
textAlign: "center",
49+
fontSize: "25px", // 50rh
50+
lineHeight: "50px" // 100rh
51+
});
52+
});
53+
54+
it("should react to width change", async () => {
55+
await changeRootSize({ width: 101 });
56+
57+
expectTestComponentToHaveStyle({
58+
backgroundColor: "rgb(0, 128, 0)",
59+
border: "4.03125px solid rgb(255, 255, 255)"
60+
});
61+
expectTestComponentToHaveCustomProperties({
62+
"--w": "101px",
63+
"--h": "50px"
64+
});
65+
});
66+
67+
it("should revert styles after width changes back", async () => {
68+
await changeRootSize({ width: 100 });
69+
70+
expectTestComponentToHaveStyle({
71+
backgroundColor: "rgb(255, 0, 0)",
72+
border: "2px solid rgb(255, 255, 255)"
73+
});
74+
expectTestComponentToHaveCustomProperties({
75+
"--w": "100px",
76+
"--h": "50px"
77+
});
78+
});
79+
80+
it("should react to height change", async () => {
81+
await changeRootSize({ height: 51 });
82+
83+
expectTestComponentToHaveStyle({
84+
color: "rgb(255, 255, 255)",
85+
border: "2.03125px solid rgb(255, 255, 255)"
86+
});
87+
expectTestComponentToHaveCustomProperties({
88+
"--w": "100px",
89+
"--h": "51px"
90+
});
91+
});
92+
93+
it("should revert styles after height changes back", async () => {
94+
await changeRootSize({ height: 50 });
95+
96+
expectTestComponentToHaveStyle({
97+
color: "rgb(0, 0, 0)",
98+
border: "2px solid rgb(255, 255, 255)"
99+
});
100+
expectTestComponentToHaveCustomProperties({
101+
"--w": "100px",
102+
"--h": "50px"
103+
});
104+
});
105+
106+
it("should handle all queries at the same time", async () => {
107+
// changing to portrait, as well as being bigger than 100x50
108+
await changeRootSize({ width: 200, height: 300 });
109+
110+
expectTestComponentToHaveStyle({
111+
backgroundColor: "rgb(0, 128, 0)",
112+
color: "rgb(255, 255, 255)",
113+
border: "4px solid rgb(0, 0, 0)"
114+
});
115+
expectTestComponentToHaveCustomProperties({
116+
"--w": "200px",
117+
"--h": "300px"
118+
});
119+
120+
expectElementToHaveStyle(refs.content, {
121+
fontWeight: "700",
122+
fontSize: "45px" // 15rh
123+
});
124+
});
23125
});

tests/utils/index.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import ReactDOM from "react-dom";
2+
import { getByTestId as rawGetByTestId } from "dom-testing-library";
3+
4+
let root = null;
5+
let componentElement = null;
6+
7+
const waitForAnimationFrame = () =>
8+
new Promise(resolve => requestAnimationFrame(resolve));
9+
10+
const waitForNAnimationFrame = async n => {
11+
for (let i = 0; i < n; i++) {
12+
await waitForAnimationFrame();
13+
}
14+
};
15+
16+
/**
17+
* @param {Component} component
18+
* @param {{width: int, height: int}} size
19+
* @return {HTMLElement}
20+
*/
21+
export const renderTestComponent = (
22+
component,
23+
size = { width: 100, height: 100 }
24+
) => {
25+
root = document.createElement("div");
26+
root.style.position = "relative";
27+
changeRootSize(size);
28+
document.body.appendChild(root);
29+
30+
ReactDOM.render(component, root);
31+
32+
componentElement = root.children[0];
33+
34+
return componentElement;
35+
};
36+
37+
/**
38+
* Changing the root size, which results in changing the size of the component
39+
* rendered inside.
40+
* @param {int} width
41+
* @param {int} height
42+
*/
43+
export const changeRootSize = async ({ width, height }) => {
44+
if (width) {
45+
root.style.width = `${width}px`;
46+
}
47+
48+
if (height) {
49+
root.style.height = `${height}px`;
50+
}
51+
52+
// Style changes will be applied in the first frame, and then they'll be
53+
// accessible in the one after that.
54+
// (Waiting 1 frame would result us querying the element in the same frame it's
55+
// expected to be updated.)
56+
await waitForNAnimationFrame(2);
57+
};
58+
59+
/**
60+
* @param {string} id
61+
* @return {HTMLElement}
62+
*/
63+
export const getByTestId = id => rawGetByTestId(root, id);
64+
65+
/**
66+
* Asserts whether the given element has the expected styles.
67+
* @param {HTMLElement} element
68+
* @param {{}} style
69+
*/
70+
export const expectElementToHaveStyle = (element, style) => {
71+
const computedStyle = getComputedStyle(element);
72+
for (let prop of Object.keys(style)) {
73+
expect(computedStyle[prop]).toBe(style[prop]);
74+
}
75+
};
76+
77+
/**
78+
* Asserts whether the currently rendered component has the expected styles.
79+
* @param {{}} style
80+
*/
81+
export const expectTestComponentToHaveStyle = style =>
82+
expectElementToHaveStyle(componentElement, style);
83+
84+
/**
85+
* @param {HTMLElement} element
86+
* @param {{}} props
87+
*/
88+
export const expectElementToHaveCustomProperties = (element, props) => {
89+
for (let prop of Object.keys(props)) {
90+
expect(element.style.getPropertyValue(prop)).toBe(props[prop]);
91+
}
92+
};
93+
94+
/**
95+
* @param {{}} props
96+
*/
97+
export const expectTestComponentToHaveCustomProperties = props =>
98+
expectElementToHaveCustomProperties(componentElement, props);

yarn.lock

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,13 @@
624624
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
625625
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
626626

627+
"@babel/runtime@^7.1.5":
628+
version "7.2.0"
629+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f"
630+
integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==
631+
dependencies:
632+
regenerator-runtime "^0.12.0"
633+
627634
"@babel/template@^7.1.0", "@babel/template@^7.1.2":
628635
version "7.1.2"
629636
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644"
@@ -1284,6 +1291,11 @@
12841291
dependencies:
12851292
any-observable "^0.3.0"
12861293

1294+
"@sheerun/mutationobserver-shim@^0.3.2":
1295+
version "0.3.2"
1296+
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
1297+
integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==
1298+
12871299
"@webassemblyjs/[email protected]":
12881300
version "1.7.11"
12891301
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace"
@@ -3284,6 +3296,16 @@ dom-serialize@^2.2.0:
32843296
extend "^3.0.0"
32853297
void-elements "^2.0.0"
32863298

3299+
dom-testing-library@^3.16.1:
3300+
version "3.16.1"
3301+
resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.16.1.tgz#9911d775adba1cf5b68ec30a02bbf6b2989727f9"
3302+
integrity sha512-dYVeCXo7cBviHP7c+bRlXm0r0HXSOcUeMt6kKqnpCSKhyPbRFas1IKhjB/APP4yhBDwn9XECIC84ZlgTEiCm4A==
3303+
dependencies:
3304+
"@babel/runtime" "^7.1.5"
3305+
"@sheerun/mutationobserver-shim" "^0.3.2"
3306+
pretty-format "^23.6.0"
3307+
wait-for-expect "^1.1.0"
3308+
32873309
domain-browser@^1.1.1:
32883310
version "1.2.0"
32893311
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
@@ -7703,6 +7725,11 @@ regenerator-runtime@^0.11.0:
77037725
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
77047726
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
77057727

7728+
regenerator-runtime@^0.12.0:
7729+
version "0.12.1"
7730+
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
7731+
integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
7732+
77067733
regenerator-runtime@^0.13.1:
77077734
version "0.13.1"
77087735
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.1.tgz#522ea2aafd9200a00eee143dc14219a35a0f3991"
@@ -9112,6 +9139,11 @@ w3c-hr-time@^1.0.1:
91129139
dependencies:
91139140
browser-process-hrtime "^0.1.2"
91149141

9142+
wait-for-expect@^1.1.0:
9143+
version "1.1.0"
9144+
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.1.0.tgz#6607375c3f79d32add35cd2c87ce13f351a3d453"
9145+
integrity sha512-vQDokqxyMyknfX3luCDn16bSaRcOyH6gGuUXMIbxBLeTo6nWuEWYqMTT9a+44FmW8c2m6TRWBdNvBBjA1hwEKg==
9146+
91159147
walker@~1.0.5:
91169148
version "1.0.7"
91179149
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"

0 commit comments

Comments
 (0)