Skip to content

Commit 98f74dd

Browse files
Added assertComponents
1 parent 441209b commit 98f74dd

File tree

6 files changed

+116
-25
lines changed

6 files changed

+116
-25
lines changed

index.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as assertComponent } from "./src/assertComponent.mjs";
2+
export { default as assertComponents } from "./src/assertComponents.mjs";

src/assertComponent.mjs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,29 @@ import assert from "node:assert/strict";
55
* @param { import('react').ReactElement | string } expectedElement
66
*/
77
function assertComponent(result, expectedElement) {
8-
assertComponentImpl(
9-
typeof expectedElement === "string"
10-
? expectedElement
11-
: Object(expectedElement.type).toString(),
12-
result,
13-
expectedElement
14-
);
8+
assertComponentImpl("", result, expectedElement);
159
}
1610

1711
/**
18-
* @param { string } name
12+
* @param { string } path
1913
* @param { import('./assertComponent').TestInstance | string } result
2014
* @param { import('./assertComponent').TestInstance | string } expectedElement
2115
*/
22-
function assertComponentImpl(name, result, expectedElement) {
16+
function assertComponentImpl(path, result, expectedElement) {
17+
const name =
18+
typeof expectedElement === "string"
19+
? expectedElement
20+
: expectedElement.type.displayName
21+
? expectedElement.type.displayName
22+
: expectedElement.type;
23+
24+
const pathName = path ? `${path} > ${name}` : Object(name).toString();
25+
2326
if (typeof result === "string" || typeof expectedElement === "string") {
2427
assert.deepEqual(
2528
result,
2629
expectedElement,
27-
`Elements doesn't match for ${name}` +
30+
`Element doesn't match for ${pathName}` +
2831
`\n\tactual: ${result}` +
2932
`\n\texpected: ${expectedElement}`
3033
);
@@ -34,7 +37,7 @@ function assertComponentImpl(name, result, expectedElement) {
3437
assert.deepEqual(
3538
result.type,
3639
expectedElement.type,
37-
`Components types doesn't match for ${name}` +
40+
`Component type doesn't match for ${pathName}` +
3841
`\n\tactual: ${
3942
result.type.displayName ? result.type.displayName : result.type
4043
}` +
@@ -47,15 +50,15 @@ function assertComponentImpl(name, result, expectedElement) {
4750

4851
Object.keys(expectedElement.props)
4952
.filter((p) => {
50-
return p != "children" && p != "assertWrapped" && p != "assertPlain";
53+
return p != "children";
5154
})
5255
.forEach((attr) => {
5356
const resultValue = result.props[attr];
5457
const expectedValue = expectedElement.props[attr];
5558
if (typeof expectedValue === "object" && !Array.isArray(expectedValue)) {
56-
assertObject(`${name}.${attr}`, resultValue, expectedValue);
59+
assertObject(`${pathName}.${attr}`, resultValue, expectedValue);
5760
} else {
58-
assertAttrValue(`${name}.${attr}`, resultValue, expectedValue);
61+
assertAttrValue(`${pathName}.${attr}`, resultValue, expectedValue);
5962
}
6063
});
6164

@@ -73,20 +76,20 @@ function assertComponentImpl(name, result, expectedElement) {
7376
: Object(child.type).toString();
7477
});
7578
assert.fail(
76-
`Expected no children for ${name}, but got: ${resultChildren}`
79+
`Expected no children for ${pathName}, but got: ${resultChildren}`
7780
);
7881
}
7982
} else {
8083
assert.deepEqual(
8184
children.length,
8285
expectedChildren.length,
83-
`Children count doesn't match for ${name}` +
86+
`Children count doesn't match for ${pathName}` +
8487
`\n\tactual: ${children.length}` +
8588
`\n\texpected: ${expectedChildren.length}`
8689
);
8790

8891
expectedChildren.forEach((expected, i) => {
89-
assertComponentImpl(name, children[i], expected);
92+
assertComponentImpl(pathName, children[i], expected);
9093
});
9194
}
9295
}

src/assertComponents.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import assert from "node:assert/strict";
2+
import assertComponent from "./assertComponent.mjs";
3+
4+
/**
5+
* @param { (import('react-test-renderer').ReactTestInstance | string)[] } results
6+
* @param { (import('react').ReactElement | string)[] } expectedElements
7+
*/
8+
function assertComponents(results, ...expectedElements) {
9+
assert.deepEqual(
10+
results.length,
11+
expectedElements.length,
12+
`Components count doesn't match` +
13+
`\n\tactual: ${results.length}` +
14+
`\n\texpected: ${expectedElements.length}`
15+
);
16+
17+
expectedElements.forEach((expected, i) => {
18+
assertComponent(results[i], expected);
19+
});
20+
}
21+
22+
export default assertComponents;

test/all.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
await import("./testRenderer.test.mjs");
22
await import("./assertComponent.test.mjs");
3+
await import("./assertComponents.test.mjs");

test/assertComponent.test.mjs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,32 +114,32 @@ describe("assertComponent.test.mjs", () => {
114114
//then
115115
assert.deepEqual(
116116
resError?.message,
117-
"Elements doesn't match for p" +
117+
"Element doesn't match for p > comp2" +
118118
"\n\tactual: comp" +
119119
"\n\texpected: comp2"
120120
);
121121
});
122122

123-
it("should fail if child types doesn't match", () => {
123+
it("should fail if root element doesn't match", () => {
124124
//given
125125
const Comp = () => {
126-
return h("p", {}, h("comp"));
126+
return h("comp");
127127
};
128128
const comp = TestRenderer.create(h(Comp)).root.children[0];
129129
/** @type {Error?} */
130130
let resError = null;
131131

132132
//when
133133
try {
134-
assertComponent(comp, h("p", {}, h("comp2")));
134+
assertComponent(comp, h("comp2"));
135135
} catch (error) {
136136
resError = error;
137137
}
138138

139139
//then
140140
assert.deepEqual(
141141
resError?.message,
142-
"Components types doesn't match for p" +
142+
"Component type doesn't match for comp2" +
143143
"\n\tactual: comp" +
144144
"\n\texpected: comp2"
145145
);
@@ -164,7 +164,7 @@ describe("assertComponent.test.mjs", () => {
164164
//then
165165
assert.deepEqual(
166166
resError?.message,
167-
"Components types doesn't match for p" +
167+
"Component type doesn't match for p > TestComp2" +
168168
"\n\tactual: TestComp" +
169169
"\n\texpected: TestComp2"
170170
);
@@ -173,7 +173,7 @@ describe("assertComponent.test.mjs", () => {
173173
it("should fail if non-empty", () => {
174174
//given
175175
const Comp = () => {
176-
return h("p", {}, h(TestComp));
176+
return h("p", {}, "test_text", h("div"), h(TestComp));
177177
};
178178
const comp = TestRenderer.create(h(Comp)).root.children[0];
179179
/** @type {Error?} */
@@ -189,7 +189,7 @@ describe("assertComponent.test.mjs", () => {
189189
//then
190190
assert.deepEqual(
191191
resError?.message,
192-
"Expected no children for p, but got: TestComp"
192+
"Expected no children for p, but got: test_text,div,TestComp"
193193
);
194194
});
195195

test/assertComponents.test.mjs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from "react";
2+
import TestRenderer from "react-test-renderer";
3+
import { assertComponents } from "../index.mjs";
4+
import { TestComp, TestComp2 } from "./testComponents.mjs";
5+
6+
import { strict as assert } from "node:assert";
7+
const { describe, it } = await (async () => {
8+
// @ts-ignore
9+
return process.isBun // @ts-ignore
10+
? Promise.resolve({ describe: (_, fn) => fn(), it: test })
11+
: import("node:test");
12+
})();
13+
14+
const h = React.createElement;
15+
16+
describe("assertComponents.test.mjs", () => {
17+
it("should fail if components count doesn't match", () => {
18+
//given
19+
const Comp = () => {
20+
return h(React.Fragment, null, "test_text", h("div"), h(TestComp));
21+
};
22+
const comp = TestRenderer.create(h(Comp)).root;
23+
/** @type {Error?} */
24+
let resError = null;
25+
26+
//when
27+
try {
28+
assertComponents(comp.children, h("div"), "test_text");
29+
} catch (error) {
30+
resError = error;
31+
}
32+
33+
//then
34+
assert.deepEqual(
35+
resError?.message,
36+
"Components count doesn't match\n\tactual: 3\n\texpected: 2"
37+
);
38+
});
39+
40+
it("should fail if component child doesn't match", () => {
41+
//given
42+
const Comp = () => {
43+
return h("p", {}, h("comp"), h(TestComp));
44+
};
45+
const comp = TestRenderer.create(h(Comp)).root;
46+
/** @type {Error?} */
47+
let resError = null;
48+
49+
//when
50+
try {
51+
assertComponents(comp.children, h("p", {}, h("comp"), h(TestComp2)));
52+
} catch (error) {
53+
resError = error;
54+
}
55+
56+
//then
57+
assert.deepEqual(
58+
resError?.message,
59+
"Component type doesn't match for p > TestComp2" +
60+
"\n\tactual: TestComp" +
61+
"\n\texpected: TestComp2"
62+
);
63+
});
64+
});

0 commit comments

Comments
 (0)