diff --git a/src/lib/litegraph/src/node/NodeSlot.draw.test.ts b/src/lib/litegraph/src/node/NodeSlot.draw.test.ts index 00341a2f37..1b3cf8ba25 100644 --- a/src/lib/litegraph/src/node/NodeSlot.draw.test.ts +++ b/src/lib/litegraph/src/node/NodeSlot.draw.test.ts @@ -1,7 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { fromAny, fromPartial } from '@total-typescript/shoehorn' +import { fromPartial } from '@total-typescript/shoehorn' -import type { DefaultConnectionColors } from '@/lib/litegraph/src/interfaces' +import type { + DefaultConnectionColors, + INodeInputSlot, + INodeOutputSlot +} from '@/lib/litegraph/src/interfaces' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' import { SlotType } from '@/lib/litegraph/src/draw' import { @@ -29,33 +33,33 @@ function createNode(): LGraphNode { } function createInputSlot( - overrides: Partial = {}, + overrides: Partial = {}, node = createNode() ): NodeInputSlot { return new NodeInputSlot( - fromAny({ + { name: 'in', type: 'STRING', link: null, - boundingRect: [10, 20, 20, 20], + boundingRect: [10, 20, 20, 20] as const, ...overrides - }), + }, node ) } function createOutputSlot( - overrides: Partial = {}, + overrides: Partial = {}, node = createNode() ): NodeOutputSlot { return new NodeOutputSlot( - fromAny({ + { name: 'out', type: 'STRING', links: null, - boundingRect: [10, 20, 20, 20], + boundingRect: [10, 20, 20, 20] as const, ...overrides - }), + }, node ) } @@ -310,12 +314,12 @@ describe('NodeSlot rendering', () => { }) it('falls back to the selected title colour, then text colour', () => { - LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR = fromAny(undefined) + LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR = undefined expect(createInputSlot().highlightColor).toBe( LiteGraph.NODE_SELECTED_TITLE_COLOR ) - LiteGraph.NODE_SELECTED_TITLE_COLOR = fromAny(undefined) + LiteGraph.NODE_SELECTED_TITLE_COLOR = undefined expect(createInputSlot().highlightColor).toBe(LiteGraph.NODE_TEXT_COLOR) }) }) diff --git a/src/lib/litegraph/src/node/slotUtils.test.ts b/src/lib/litegraph/src/node/slotUtils.test.ts index 61f8a9533d..4093b87e31 100644 --- a/src/lib/litegraph/src/node/slotUtils.test.ts +++ b/src/lib/litegraph/src/node/slotUtils.test.ts @@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest' import type { INodeOutputSlot } from '@/lib/litegraph/src/interfaces' import type { IWidget } from '@/lib/litegraph/src/litegraph' import { LGraphNode } from '@/lib/litegraph/src/litegraph' +import type { INumericWidget } from '@/lib/litegraph/src/types/widgets' import { toLinkId } from '@/types/linkId' import { outputAsSerialisable } from './slotUtils' @@ -37,7 +38,12 @@ describe('outputAsSerialisable', () => { it('serialises only the widget name for outputs with widgets', () => { const node = new LGraphNode('test') const output = node.addOutput('out', 'number') as OutputSlotParam - output.widget = { name: 'my-widget', type: 'number' } as IWidget + output.widget = node.addWidget( + 'number', + 'my-widget', + 0, + null + ) as INumericWidget const serialised = outputAsSerialisable(output) expect(serialised.widget).toEqual({ name: 'my-widget' }) diff --git a/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.test.ts b/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.test.ts index 81f203f26e..ceae4da785 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { fromAny, fromPartial } from '@total-typescript/shoehorn' +import { fromPartial } from '@total-typescript/shoehorn' import type { CanvasPointer } from '@/lib/litegraph/src/CanvasPointer' import { LGraphCanvas } from '@/lib/litegraph/src/LGraphCanvas' @@ -11,6 +11,7 @@ import type { import { LiteGraph } from '@/lib/litegraph/src/litegraph' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import { CanvasItem } from '@/lib/litegraph/src/types/globalEnums' +import { toLinkId } from '@/types/linkId' import { createTestSubgraph, @@ -131,7 +132,7 @@ describe('SubgraphIONodeBase', () => { beforeEach(() => { captured = undefined - LiteGraph.ContextMenu = fromAny( + LiteGraph.ContextMenu = fromPartial( class { constructor( options: (IContextMenuValue | null)[], @@ -150,7 +151,7 @@ describe('SubgraphIONodeBase', () => { it('offers disconnect, rename, and remove for connected slots', () => { const { subgraph, inputNode } = createArrangedInputNode() const slot = inputNode.slots[0] - slot.linkIds.push(fromAny(1)) + slot.linkIds.push(toLinkId(1)) const [slotX, slotY] = slotCentre(slot) inputNode.onPointerDown( @@ -168,21 +169,11 @@ describe('SubgraphIONodeBase', () => { ]) // Disconnect action clears the slot's links. - void captured?.opts.callback?.( - fromPartial({ value: 'disconnect' }), - fromAny({}), - fromAny({}), - fromAny({}) - ) + void captured?.opts.callback?.(fromPartial({ value: 'disconnect' })) expect(slot.linkIds).toHaveLength(0) // Remove action deletes the slot from the subgraph. - void captured?.opts.callback?.( - fromPartial({ value: 'remove' }), - fromAny({}), - fromAny({}), - fromAny({}) - ) + void captured?.opts.callback?.(fromPartial({ value: 'remove' })) expect(subgraph.inputs).toHaveLength(0) }) @@ -208,12 +199,7 @@ describe('SubgraphIONodeBase', () => { fromPartial({}), fromPartial({}) ) - void captured?.opts.callback?.( - fromPartial({ value: 'rename' }), - fromAny({}), - fromAny({}), - fromAny({}) - ) + void captured?.opts.callback?.(fromPartial({ value: 'rename' })) expect(prompt).toHaveBeenCalledWith( 'Slot name', @@ -269,14 +255,14 @@ describe('SubgraphIONodeBase', () => { linkConnector ) - pointer.onDragStart?.(fromAny({})) + pointer.onDragStart?.(pointer) expect(linkConnector.dragNewFromSubgraphInput).toHaveBeenCalledWith( subgraph, inputNode, slot ) - pointer.onDragEnd?.(fromAny({})) + pointer.onDragEnd?.(fromPartial({})) expect(linkConnector.dropLinks).toHaveBeenCalled() pointer.finally?.() @@ -296,7 +282,7 @@ describe('SubgraphIONodeBase', () => { pointer, fromPartial({}) ) - pointer.onDoubleClick?.(fromAny({})) + pointer.onDoubleClick?.(fromPartial({})) expect(prompt).toHaveBeenCalled() }) @@ -313,7 +299,7 @@ describe('SubgraphIONodeBase', () => { pointer, fromPartial({}) ) - pointer.onDoubleClick?.(fromAny({})) + pointer.onDoubleClick?.(fromPartial({})) expect(prompt).not.toHaveBeenCalled() }) @@ -363,7 +349,7 @@ describe('SubgraphIONodeBase', () => { const { inputNode } = createArrangedInputNode() const strokeStyles: unknown[] = [] const ctx = fromPartial({ - getTransform: vi.fn(() => fromAny({})), + getTransform: vi.fn(() => new DOMMatrix()), setTransform: vi.fn(), translate: vi.fn(), beginPath: vi.fn(), diff --git a/src/lib/litegraph/src/subgraph/SubgraphSlotEdgeCases.test.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotEdgeCases.test.ts index b5b1e70843..3a7e3433dd 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphSlotEdgeCases.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotEdgeCases.test.ts @@ -1,17 +1,19 @@ import { createTestingPinia } from '@pinia/testing' import { setActivePinia } from 'pinia' -import { fromAny, fromPartial } from '@total-typescript/shoehorn' +import { fromPartial } from '@total-typescript/shoehorn' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { CanvasPointer } from '@/lib/litegraph/src/CanvasPointer' import type { LinkConnector } from '@/lib/litegraph/src/canvas/LinkConnector' -import type { Subgraph } from '@/lib/litegraph/src/LGraph' import type { INodeInputSlot, - INodeOutputSlot + INodeOutputSlot, + Point } from '@/lib/litegraph/src/interfaces' import { RenderShape } from '@/lib/litegraph/src/types/globalEnums' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' +import type { SubgraphIO } from '@/lib/litegraph/src/types/serialisation' +import type { Subgraph } from '@/lib/litegraph/src/litegraph' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' import { toLinkId } from '@/types/linkId' import { createMockCanvasRenderingContext2D } from '@/utils/__tests__/litegraphTestUtils' @@ -260,7 +262,7 @@ describe('SubgraphInput.getConnectedWidgets', () => { expect(subgraph.inputs[0].getConnectedWidgets()).toEqual([]) expect(warn).toHaveBeenCalledWith('Widget not found', { name: 'missing' }) - input.widget = fromAny({ name: '' }) + input.widget = { name: '' } expect(subgraph.inputs[0].getConnectedWidgets()).toEqual([]) expect(warn).toHaveBeenCalledWith('Invalid widget name', { name: '' }) }) @@ -292,7 +294,7 @@ describe('SubgraphSlot base behaviour', () => { const slot = subgraph.inputs[0] slot.pos = [3, 4] - slot.pos = fromAny([5]) + slot.pos = fromPartial([5]) expect([slot.pos[0], slot.pos[1]]).toEqual([3, 4]) }) @@ -300,7 +302,7 @@ describe('SubgraphSlot base behaviour', () => { it('generates an id when the serialised slot has none', () => { const subgraph = createIoSubgraph() const slot = new SubgraphInput( - fromAny({ name: 'anon', type: 'STRING', linkIds: [] }), + fromPartial({ name: 'anon', type: 'STRING', linkIds: [] }), subgraph.inputNode ) @@ -392,7 +394,7 @@ describe('SubgraphSlot base behaviour', () => { it('falls back to the default label colour when unset', () => { const originalColor = LiteGraph.NODE_TEXT_COLOR try { - LiteGraph.NODE_TEXT_COLOR = fromAny('') + LiteGraph.NODE_TEXT_COLOR = '' const subgraph = createIoSubgraph() const fillStyles: unknown[] = [] const ctx = createMockCanvasRenderingContext2D({ @@ -442,13 +444,13 @@ describe('SubgraphOutputNode interaction', () => { linkConnector ) - pointer.onDragStart?.(fromAny({})) + pointer.onDragStart?.(pointer) expect(linkConnector.dragNewFromSubgraphOutput).toHaveBeenCalledWith( subgraph, outputNode, slot ) - pointer.onDragEnd?.(fromAny({})) + pointer.onDragEnd?.(fromPartial({})) expect(linkConnector.dropLinks).toHaveBeenCalled() pointer.finally?.() expect(linkConnector.reset).toHaveBeenCalledWith(true) @@ -458,7 +460,7 @@ describe('SubgraphOutputNode interaction', () => { const { outputNode } = createArrangedOutputNode() const OriginalContextMenu = LiteGraph.ContextMenu let constructed = false - LiteGraph.ContextMenu = fromAny( + LiteGraph.ContextMenu = fromPartial( class { constructor() { constructed = true @@ -515,7 +517,7 @@ describe('SubgraphInputNode connections', () => { expect(() => subgraph.inputNode.connectSlots( - fromAny({}), + fromPartial({}), node, node.inputs[0], undefined @@ -541,7 +543,7 @@ describe('SubgraphInputNode connections', () => { it('falls back to the subgraph slot type for untyped inputs', () => { const subgraph = createIoSubgraph() const node = new LGraphNode('Untyped') - node.addInput('in', fromAny('')) + node.addInput('in', '') subgraph.add(node) const link = subgraph.inputNode.connectSlots( diff --git a/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts b/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts index 5d6c9f5275..3181c5d90a 100644 --- a/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts +++ b/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts @@ -1,9 +1,13 @@ import { createTestingPinia } from '@pinia/testing' import { setActivePinia } from 'pinia' -import { fromAny, fromPartial } from '@total-typescript/shoehorn' +import { fromPartial } from '@total-typescript/shoehorn' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import type { Positionable } from '@/lib/litegraph/src/interfaces' +import type { + INodeInputSlot, + INodeOutputSlot, + Positionable +} from '@/lib/litegraph/src/interfaces' import { LGraph, LGraphGroup, @@ -18,8 +22,11 @@ import type { ResolvedConnection } from '@/lib/litegraph/src/LLink' import type { Reroute } from '@/lib/litegraph/src/Reroute' import type { SerialisableLLink } from '@/lib/litegraph/src/types/serialisation' import { toRerouteId } from '@/types/rerouteId' +import { toLinkId } from '@/types/linkId' import { createMockPositionable } from '@/utils/__tests__/litegraphTestUtils' +import type { SubgraphInput } from './SubgraphInput' + import { getBoundaryLinks, groupResolvedByOutput, @@ -346,7 +353,7 @@ describe('subgraphUtils', () => { const first = fromPartial({ output }) const second = fromPartial({ output }) const bySubgraphInput = fromPartial({ - subgraphInput: fromAny({ name: 'sub' }) + subgraphInput: fromPartial({ name: 'sub' }) }) const unresolvable = fromPartial({}) @@ -358,7 +365,7 @@ describe('subgraphUtils', () => { ]) expect(grouped.size).toBe(3) - expect(grouped.get(fromAny(output))).toEqual([first, second]) + expect(grouped.get(output!)).toEqual([first, second]) }) }) @@ -367,18 +374,15 @@ describe('subgraphUtils', () => { linkId: number, inputOverrides: Record = {} ): { resolved: ResolvedConnection; link: LLink } { - const link = new LLink( - fromAny(linkId), - 'number', - fromAny(1), - 0, - fromAny(2), - 0 - ) + const link = new LLink(toLinkId(linkId), 'number', 1, 0, 2, 0) const resolved = fromPartial({ link, - input: fromAny({ name: 'in', type: 'number', ...inputOverrides }), - output: fromAny({ name: 'out', type: 'number' }) + input: fromPartial({ + name: 'in', + type: 'number', + ...inputOverrides + }), + output: fromPartial({ name: 'out', type: 'number' }) }) return { resolved, link } } @@ -412,10 +416,10 @@ describe('subgraphUtils', () => { }) it('skips connections without a resolved input', () => { - const link = new LLink(fromAny(1), 'number', fromAny(1), 0, fromAny(2), 0) + const link = new LLink(toLinkId(1), 'number', 1, 0, 2, 0) const resolved = fromPartial({ link, - output: fromAny({ name: 'out', type: 'number' }) + output: fromPartial({ name: 'out', type: 'number' }) }) const inputs = mapSubgraphInputsAndLinks([resolved], [], new Map()) @@ -444,18 +448,15 @@ describe('subgraphUtils', () => { linkId: number, outputOverrides: Record = {} ): { resolved: ResolvedConnection; link: LLink } { - const link = new LLink( - fromAny(linkId), - 'number', - fromAny(1), - 0, - fromAny(2), - 0 - ) + const link = new LLink(toLinkId(linkId), 'number', 1, 0, 2, 0) const resolved = fromPartial({ link, - input: fromAny({ name: 'in', type: 'number' }), - output: fromAny({ name: 'out', type: 'number', ...outputOverrides }) + input: fromPartial({ name: 'in', type: 'number' }), + output: fromPartial({ + name: 'out', + type: 'number', + ...outputOverrides + }) }) return { resolved, link } } @@ -488,10 +489,10 @@ describe('subgraphUtils', () => { }) it('skips connections without a resolved output', () => { - const link = new LLink(fromAny(1), 'number', fromAny(1), 0, fromAny(2), 0) + const link = new LLink(toLinkId(1), 'number', 1, 0, 2, 0) const resolved = fromPartial({ link, - input: fromAny({ name: 'in', type: 'number' }) + input: fromPartial({ name: 'in', type: 'number' }) }) const outputs = mapSubgraphOutputsAndLinks([resolved], [], new Map()) @@ -502,9 +503,12 @@ describe('subgraphUtils', () => { describe('reorderSubgraphInputs', () => { it('returns silently when the node has no subgraph', () => { - expect(() => - reorderSubgraphInputs(fromAny({ subgraph: undefined }), []) - ).not.toThrow() + const subgraphNode = createTestSubgraphNode(createTestSubgraph()) + Object.defineProperty(subgraphNode, 'subgraph', { + value: undefined, + configurable: true + }) + expect(() => reorderSubgraphInputs(subgraphNode, [])).not.toThrow() }) it('rejects indices that are not a permutation', () => { diff --git a/src/lib/litegraph/src/utils/arrange.test.ts b/src/lib/litegraph/src/utils/arrange.test.ts index ba61de64ab..2b632bebbb 100644 --- a/src/lib/litegraph/src/utils/arrange.test.ts +++ b/src/lib/litegraph/src/utils/arrange.test.ts @@ -1,5 +1,4 @@ import { describe, expect, it } from 'vitest' -import { fromAny } from '@total-typescript/shoehorn' import { LGraphNode } from '@/lib/litegraph/src/litegraph' import type { Direction } from '@/lib/litegraph/src/interfaces' @@ -16,11 +15,11 @@ function createNode(x: number, y: number, width: number, height: number) { describe('getBoundaryNodes', () => { it('returns null when no nodes are supplied', () => { expect(getBoundaryNodes([])).toBeNull() - expect(getBoundaryNodes(fromAny(undefined))).toBeNull() + expect(getBoundaryNodes(undefined)).toBeNull() }) it('returns null when all nodes are falsy', () => { - expect(getBoundaryNodes(fromAny([undefined, null]))).toBeNull() + expect(getBoundaryNodes([undefined, null])).toBeNull() }) it('returns the same node for all edges with a single node', () => { @@ -51,7 +50,7 @@ describe('getBoundaryNodes', () => { const node = createNode(5, 5, 10, 10) const other = createNode(50, 50, 10, 10) - const boundary = getBoundaryNodes(fromAny([node, undefined, other])) + const boundary = getBoundaryNodes([node, undefined, other]) expect(boundary?.left).toBe(node) expect(boundary?.right).toBe(other) @@ -62,7 +61,7 @@ describe('distributeNodes', () => { it('returns an empty array when fewer than two nodes are supplied', () => { expect(distributeNodes([])).toEqual([]) expect(distributeNodes([createNode(0, 0, 10, 10)])).toEqual([]) - expect(distributeNodes(fromAny(undefined))).toEqual([]) + expect(distributeNodes(undefined)).toEqual([]) }) it('distributes nodes evenly along the horizontal plane', () => { @@ -97,7 +96,7 @@ describe('distributeNodes', () => { describe('alignNodes', () => { it('returns an empty array when nodes are not supplied', () => { - expect(alignNodes(fromAny(undefined), 'left')).toEqual([]) + expect(alignNodes(undefined, 'left')).toEqual([]) }) it('returns an empty array when boundary nodes cannot be determined', () => { diff --git a/src/lib/litegraph/src/utils/collections.test.ts b/src/lib/litegraph/src/utils/collections.test.ts index 052019ff4f..167f28884d 100644 --- a/src/lib/litegraph/src/utils/collections.test.ts +++ b/src/lib/litegraph/src/utils/collections.test.ts @@ -1,5 +1,4 @@ import { describe, expect, it } from 'vitest' -import { fromAny } from '@total-typescript/shoehorn' import type { Positionable } from '@/lib/litegraph/src/interfaces' import { LGraphNode } from '@/lib/litegraph/src/litegraph' @@ -13,7 +12,7 @@ import { describe('getAllNestedItems', () => { it('returns an empty set when items are not supplied', () => { - expect(getAllNestedItems(fromAny(undefined)).size).toBe(0) + expect(getAllNestedItems(undefined).size).toBe(0) }) it('excludes pinned items', () => { @@ -77,13 +76,7 @@ describe('findFreeSlotOfType', () => { it('returns undefined when no slots are supplied', () => { expect(findFreeSlotOfType([], 'A', hasNoLinks)).toBeUndefined() - expect( - findFreeSlotOfType( - fromAny(undefined), - 'A', - hasNoLinks - ) - ).toBeUndefined() + expect(findFreeSlotOfType(undefined, 'A', hasNoLinks)).toBeUndefined() }) it('returns the first free slot with an exact type match', () => {