From ebb5aa7cb77ac02afb8f2953f1c3bc6ee1214284 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 14 Oct 2025 18:38:43 +0200 Subject: [PATCH 1/3] Added tests for block type guards --- .../src/unit/core/typeGuards/runTests.test.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/src/unit/core/typeGuards/runTests.test.ts diff --git a/tests/src/unit/core/typeGuards/runTests.test.ts b/tests/src/unit/core/typeGuards/runTests.test.ts new file mode 100644 index 0000000000..37f7ddd1c2 --- /dev/null +++ b/tests/src/unit/core/typeGuards/runTests.test.ts @@ -0,0 +1,86 @@ +import { BlockNoteEditor, editorHasBlockWithType } from "@blocknote/core"; +import { describe, expect, it } from "vitest"; + +import { createTestEditor } from "../createTestEditor.js"; +import { testSchema } from "../testSchema.js"; + +// Tests for verifying that type guards which check if an editor's schema +// contains a block (and its props) are working correctly. +describe("Editor block schema type guard tests", () => { + const getEditor = createTestEditor(testSchema) as () => BlockNoteEditor< + any, + any, + any + >; + + it("blockType", () => { + expect(editorHasBlockWithType(getEditor(), "heading")).toBeTruthy(); + }); + + it("blockTypeInvalid", () => { + expect(editorHasBlockWithType(getEditor(), "embed")).toBeFalsy(); + }); + + it("blockWithPropTypes", () => { + expect( + editorHasBlockWithType(getEditor(), "heading", { + level: "number", + textColor: "string", + }), + ).toBeTruthy(); + }); + + it("blockWithPropTypesInvalidType", () => { + expect( + editorHasBlockWithType(getEditor(), "heading", { + level: "number", + textColor: "number", + }), + ).toBeFalsy(); + }); + + it("blockWithPropSchema", () => { + expect( + editorHasBlockWithType(getEditor(), "heading", { + level: { default: 1, values: [1, 2, 3] }, + textColor: { default: "default" }, + }), + ).toBeTruthy(); + }); + + it("blockWithPropSchemaInvalidType", () => { + expect( + editorHasBlockWithType(getEditor(), "heading", { + level: { default: 1, values: [1, 2, 3] }, + textColor: { default: 1 }, + }), + ).toBeFalsy(); + }); + + it("blockWithPropSchemaInvalidValues", () => { + expect( + editorHasBlockWithType(getEditor(), "heading", { + level: { default: 1, values: [1, 2, 3, 4, 5, 6, 7] }, + textColor: { default: "default" }, + }), + ).toBeFalsy(); + }); + + it("blockWithPropTypesUndefinedDefault", () => { + expect( + editorHasBlockWithType(getEditor(), "numberedListItem", { + start: "number", + textColor: "string", + }), + ).toBeTruthy(); + }); + + it("blockWithPropSchemaUndefinedDefaultInvalidType", () => { + expect( + editorHasBlockWithType(getEditor(), "numberedListItem", { + start: "string", + textColor: "string", + }), + ).toBeFalsy(); + }); +}); From bb8f3369f9eed8a2cd1dde95dbc71a4cfa2b576c Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Tue, 14 Oct 2025 18:39:27 +0200 Subject: [PATCH 2/3] Made `editorHasBlockWithType` pass when a provided set of prop values is a subset of those in the schema --- .../core/src/blocks/defaultBlockTypeGuards.ts | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/packages/core/src/blocks/defaultBlockTypeGuards.ts b/packages/core/src/blocks/defaultBlockTypeGuards.ts index 00bb122098..ddd57b5ecb 100644 --- a/packages/core/src/blocks/defaultBlockTypeGuards.ts +++ b/packages/core/src/blocks/defaultBlockTypeGuards.ts @@ -97,23 +97,11 @@ export function editorHasBlockWithType< .values === "object" && typeof propSpec.values === "object" ) { - if ( - editor.schema.blockSpecs[blockType].config.propSchema[propName].values - .length !== propSpec.values.length - ) { - return false; - } - - for ( - let i = 0; - i < - editor.schema.blockSpecs[blockType].config.propSchema[propName].values - .length; - i++ - ) { + for (const value of propSpec.values) { if ( - editor.schema.blockSpecs[blockType].config.propSchema[propName] - .values[i] !== propSpec.values[i] + !editor.schema.blockSpecs[blockType].config.propSchema[ + propName + ].values.includes(value) ) { return false; } From eca2839ca353d85318c0133f879001d041b77310 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 16 Oct 2025 13:13:31 +0200 Subject: [PATCH 3/3] Added custom block tests and small fix --- .../core/src/blocks/defaultBlockTypeGuards.ts | 5 +- .../src/unit/core/typeGuards/runTests.test.ts | 49 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packages/core/src/blocks/defaultBlockTypeGuards.ts b/packages/core/src/blocks/defaultBlockTypeGuards.ts index ddd57b5ecb..e9a4f8e9b5 100644 --- a/packages/core/src/blocks/defaultBlockTypeGuards.ts +++ b/packages/core/src/blocks/defaultBlockTypeGuards.ts @@ -50,7 +50,7 @@ export function editorHasBlockWithType< if (typeof propSpec === "string") { if ( editor.schema.blockSpecs[blockType].config.propSchema[propName] - .default && + .default !== undefined && typeof editor.schema.blockSpecs[blockType].config.propSchema[propName] .default !== propSpec ) { @@ -58,7 +58,8 @@ export function editorHasBlockWithType< } if ( - editor.schema.blockSpecs[blockType].config.propSchema[propName].type && + editor.schema.blockSpecs[blockType].config.propSchema[propName].type !== + undefined && editor.schema.blockSpecs[blockType].config.propSchema[propName].type !== propSpec ) { diff --git a/tests/src/unit/core/typeGuards/runTests.test.ts b/tests/src/unit/core/typeGuards/runTests.test.ts index 37f7ddd1c2..a803e5f1e5 100644 --- a/tests/src/unit/core/typeGuards/runTests.test.ts +++ b/tests/src/unit/core/typeGuards/runTests.test.ts @@ -83,4 +83,53 @@ describe("Editor block schema type guard tests", () => { }), ).toBeFalsy(); }); + + it("customBlockType", () => { + expect(editorHasBlockWithType(getEditor(), "simpleImage")).toBeTruthy(); + }); + + it("customBlockWithPropTypes", () => { + expect( + editorHasBlockWithType(getEditor(), "simpleImage", { + name: "string", + url: "string", + }), + ).toBeTruthy(); + }); + + it("customBlockWithPropTypesInvalidType", () => { + expect( + editorHasBlockWithType(getEditor(), "simpleImage", { + name: "string", + url: "number", + }), + ).toBeFalsy(); + }); + + it("customBlockWithPropSchema", () => { + expect( + editorHasBlockWithType(getEditor(), "simpleImage", { + name: { default: "" }, + url: { default: "" }, + }), + ).toBeTruthy(); + }); + + it("customBlockWithPropSchemaInvalidType", () => { + expect( + editorHasBlockWithType(getEditor(), "simpleImage", { + name: { default: false }, + url: { default: "" }, + }), + ).toBeFalsy(); + }); + + it("customBlockWithPropSchemaInvalidValues", () => { + expect( + editorHasBlockWithType(getEditor(), "simpleImage", { + name: { default: "", values: ["image", "photo"] }, + url: { default: "" }, + }), + ).toBeFalsy(); + }); });