diff --git a/packages/core/src/blocks/defaultBlockTypeGuards.ts b/packages/core/src/blocks/defaultBlockTypeGuards.ts index 00bb122098..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 ) { @@ -97,23 +98,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; } 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..a803e5f1e5 --- /dev/null +++ b/tests/src/unit/core/typeGuards/runTests.test.ts @@ -0,0 +1,135 @@ +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(); + }); + + 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(); + }); +});