Skip to content

Commit e6d3027

Browse files
test: Unit tests for block type guards (#2103)
* Added tests for block type guards * Made `editorHasBlockWithType` pass when a provided set of prop values is a subset of those in the schema * Added custom block tests and small fix
1 parent 9c6f563 commit e6d3027

File tree

2 files changed

+142
-18
lines changed

2 files changed

+142
-18
lines changed

packages/core/src/blocks/defaultBlockTypeGuards.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,16 @@ export function editorHasBlockWithType<
5050
if (typeof propSpec === "string") {
5151
if (
5252
editor.schema.blockSpecs[blockType].config.propSchema[propName]
53-
.default &&
53+
.default !== undefined &&
5454
typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]
5555
.default !== propSpec
5656
) {
5757
return false;
5858
}
5959

6060
if (
61-
editor.schema.blockSpecs[blockType].config.propSchema[propName].type &&
61+
editor.schema.blockSpecs[blockType].config.propSchema[propName].type !==
62+
undefined &&
6263
editor.schema.blockSpecs[blockType].config.propSchema[propName].type !==
6364
propSpec
6465
) {
@@ -97,23 +98,11 @@ export function editorHasBlockWithType<
9798
.values === "object" &&
9899
typeof propSpec.values === "object"
99100
) {
100-
if (
101-
editor.schema.blockSpecs[blockType].config.propSchema[propName].values
102-
.length !== propSpec.values.length
103-
) {
104-
return false;
105-
}
106-
107-
for (
108-
let i = 0;
109-
i <
110-
editor.schema.blockSpecs[blockType].config.propSchema[propName].values
111-
.length;
112-
i++
113-
) {
101+
for (const value of propSpec.values) {
114102
if (
115-
editor.schema.blockSpecs[blockType].config.propSchema[propName]
116-
.values[i] !== propSpec.values[i]
103+
!editor.schema.blockSpecs[blockType].config.propSchema[
104+
propName
105+
].values.includes(value)
117106
) {
118107
return false;
119108
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { BlockNoteEditor, editorHasBlockWithType } from "@blocknote/core";
2+
import { describe, expect, it } from "vitest";
3+
4+
import { createTestEditor } from "../createTestEditor.js";
5+
import { testSchema } from "../testSchema.js";
6+
7+
// Tests for verifying that type guards which check if an editor's schema
8+
// contains a block (and its props) are working correctly.
9+
describe("Editor block schema type guard tests", () => {
10+
const getEditor = createTestEditor(testSchema) as () => BlockNoteEditor<
11+
any,
12+
any,
13+
any
14+
>;
15+
16+
it("blockType", () => {
17+
expect(editorHasBlockWithType(getEditor(), "heading")).toBeTruthy();
18+
});
19+
20+
it("blockTypeInvalid", () => {
21+
expect(editorHasBlockWithType(getEditor(), "embed")).toBeFalsy();
22+
});
23+
24+
it("blockWithPropTypes", () => {
25+
expect(
26+
editorHasBlockWithType(getEditor(), "heading", {
27+
level: "number",
28+
textColor: "string",
29+
}),
30+
).toBeTruthy();
31+
});
32+
33+
it("blockWithPropTypesInvalidType", () => {
34+
expect(
35+
editorHasBlockWithType(getEditor(), "heading", {
36+
level: "number",
37+
textColor: "number",
38+
}),
39+
).toBeFalsy();
40+
});
41+
42+
it("blockWithPropSchema", () => {
43+
expect(
44+
editorHasBlockWithType(getEditor(), "heading", {
45+
level: { default: 1, values: [1, 2, 3] },
46+
textColor: { default: "default" },
47+
}),
48+
).toBeTruthy();
49+
});
50+
51+
it("blockWithPropSchemaInvalidType", () => {
52+
expect(
53+
editorHasBlockWithType(getEditor(), "heading", {
54+
level: { default: 1, values: [1, 2, 3] },
55+
textColor: { default: 1 },
56+
}),
57+
).toBeFalsy();
58+
});
59+
60+
it("blockWithPropSchemaInvalidValues", () => {
61+
expect(
62+
editorHasBlockWithType(getEditor(), "heading", {
63+
level: { default: 1, values: [1, 2, 3, 4, 5, 6, 7] },
64+
textColor: { default: "default" },
65+
}),
66+
).toBeFalsy();
67+
});
68+
69+
it("blockWithPropTypesUndefinedDefault", () => {
70+
expect(
71+
editorHasBlockWithType(getEditor(), "numberedListItem", {
72+
start: "number",
73+
textColor: "string",
74+
}),
75+
).toBeTruthy();
76+
});
77+
78+
it("blockWithPropSchemaUndefinedDefaultInvalidType", () => {
79+
expect(
80+
editorHasBlockWithType(getEditor(), "numberedListItem", {
81+
start: "string",
82+
textColor: "string",
83+
}),
84+
).toBeFalsy();
85+
});
86+
87+
it("customBlockType", () => {
88+
expect(editorHasBlockWithType(getEditor(), "simpleImage")).toBeTruthy();
89+
});
90+
91+
it("customBlockWithPropTypes", () => {
92+
expect(
93+
editorHasBlockWithType(getEditor(), "simpleImage", {
94+
name: "string",
95+
url: "string",
96+
}),
97+
).toBeTruthy();
98+
});
99+
100+
it("customBlockWithPropTypesInvalidType", () => {
101+
expect(
102+
editorHasBlockWithType(getEditor(), "simpleImage", {
103+
name: "string",
104+
url: "number",
105+
}),
106+
).toBeFalsy();
107+
});
108+
109+
it("customBlockWithPropSchema", () => {
110+
expect(
111+
editorHasBlockWithType(getEditor(), "simpleImage", {
112+
name: { default: "" },
113+
url: { default: "" },
114+
}),
115+
).toBeTruthy();
116+
});
117+
118+
it("customBlockWithPropSchemaInvalidType", () => {
119+
expect(
120+
editorHasBlockWithType(getEditor(), "simpleImage", {
121+
name: { default: false },
122+
url: { default: "" },
123+
}),
124+
).toBeFalsy();
125+
});
126+
127+
it("customBlockWithPropSchemaInvalidValues", () => {
128+
expect(
129+
editorHasBlockWithType(getEditor(), "simpleImage", {
130+
name: { default: "", values: ["image", "photo"] },
131+
url: { default: "" },
132+
}),
133+
).toBeFalsy();
134+
});
135+
});

0 commit comments

Comments
 (0)