mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 14:54:37 +00:00
186 lines
5.9 KiB
TypeScript
186 lines
5.9 KiB
TypeScript
import { describe, expect, it, vi } from "vitest"
|
|
|
|
import { Rectangle } from "@/infrastructure/Rectangle"
|
|
import { LGraphButton } from "@/LGraphButton"
|
|
|
|
describe("LGraphButton", () => {
|
|
describe("Constructor", () => {
|
|
it("should create a button with default options", () => {
|
|
const button = new LGraphButton({})
|
|
expect(button).toBeInstanceOf(LGraphButton)
|
|
expect(button.name).toBeUndefined()
|
|
expect(button._last_area).toBeInstanceOf(Rectangle)
|
|
})
|
|
|
|
it("should create a button with custom name", () => {
|
|
const button = new LGraphButton({ name: "test_button" })
|
|
expect(button.name).toBe("test_button")
|
|
})
|
|
|
|
it("should inherit badge properties", () => {
|
|
const button = new LGraphButton({
|
|
text: "Test",
|
|
fgColor: "#FF0000",
|
|
bgColor: "#0000FF",
|
|
fontSize: 16,
|
|
})
|
|
expect(button.text).toBe("Test")
|
|
expect(button.fgColor).toBe("#FF0000")
|
|
expect(button.bgColor).toBe("#0000FF")
|
|
expect(button.fontSize).toBe(16)
|
|
expect(button.visible).toBe(true) // visible is computed based on text length
|
|
})
|
|
})
|
|
|
|
describe("draw", () => {
|
|
it("should not draw if not visible", () => {
|
|
const button = new LGraphButton({ text: "" }) // Empty text makes it invisible
|
|
const ctx = {
|
|
measureText: vi.fn().mockReturnValue({ width: 100 }),
|
|
} as unknown as CanvasRenderingContext2D
|
|
|
|
const superDrawSpy = vi.spyOn(Object.getPrototypeOf(Object.getPrototypeOf(button)), "draw")
|
|
|
|
button.draw(ctx, 50, 100)
|
|
|
|
expect(superDrawSpy).not.toHaveBeenCalled()
|
|
expect(button._last_area.width).toBe(0) // Rectangle default width
|
|
})
|
|
|
|
it("should draw and update last area when visible", () => {
|
|
const button = new LGraphButton({
|
|
text: "Click",
|
|
xOffset: 5,
|
|
yOffset: 10,
|
|
})
|
|
|
|
const ctx = {
|
|
measureText: vi.fn().mockReturnValue({ width: 60 }),
|
|
fillRect: vi.fn(),
|
|
fillText: vi.fn(),
|
|
beginPath: vi.fn(),
|
|
roundRect: vi.fn(),
|
|
fill: vi.fn(),
|
|
font: "",
|
|
fillStyle: "",
|
|
globalAlpha: 1,
|
|
} as unknown as CanvasRenderingContext2D
|
|
|
|
const mockGetWidth = vi.fn().mockReturnValue(80)
|
|
button.getWidth = mockGetWidth
|
|
|
|
const x = 100
|
|
const y = 50
|
|
|
|
button.draw(ctx, x, y)
|
|
|
|
// Check that last area was updated correctly
|
|
expect(button._last_area[0]).toBe(x + button.xOffset) // 100 + 5 = 105
|
|
expect(button._last_area[1]).toBe(y + button.yOffset) // 50 + 10 = 60
|
|
expect(button._last_area[2]).toBe(80)
|
|
expect(button._last_area[3]).toBe(button.height)
|
|
})
|
|
|
|
it("should calculate last area without offsets", () => {
|
|
const button = new LGraphButton({
|
|
text: "Test",
|
|
})
|
|
|
|
const ctx = {
|
|
measureText: vi.fn().mockReturnValue({ width: 40 }),
|
|
fillRect: vi.fn(),
|
|
fillText: vi.fn(),
|
|
beginPath: vi.fn(),
|
|
roundRect: vi.fn(),
|
|
fill: vi.fn(),
|
|
font: "",
|
|
fillStyle: "",
|
|
globalAlpha: 1,
|
|
} as unknown as CanvasRenderingContext2D
|
|
|
|
const mockGetWidth = vi.fn().mockReturnValue(50)
|
|
button.getWidth = mockGetWidth
|
|
|
|
button.draw(ctx, 200, 100)
|
|
|
|
expect(button._last_area[0]).toBe(200)
|
|
expect(button._last_area[1]).toBe(100)
|
|
expect(button._last_area[2]).toBe(50)
|
|
})
|
|
})
|
|
|
|
describe("isPointInside", () => {
|
|
it("should return true when point is inside button area", () => {
|
|
const button = new LGraphButton({ text: "Test" })
|
|
// Set the last area manually
|
|
button._last_area[0] = 100
|
|
button._last_area[1] = 50
|
|
button._last_area[2] = 80
|
|
button._last_area[3] = 20
|
|
|
|
// Test various points inside
|
|
expect(button.isPointInside(100, 50)).toBe(true) // Top-left corner
|
|
expect(button.isPointInside(179, 69)).toBe(true) // Bottom-right corner
|
|
expect(button.isPointInside(140, 60)).toBe(true) // Center
|
|
})
|
|
|
|
it("should return false when point is outside button area", () => {
|
|
const button = new LGraphButton({ text: "Test" })
|
|
// Set the last area manually
|
|
button._last_area[0] = 100
|
|
button._last_area[1] = 50
|
|
button._last_area[2] = 80
|
|
button._last_area[3] = 20
|
|
|
|
// Test various points outside
|
|
expect(button.isPointInside(99, 50)).toBe(false) // Just left
|
|
expect(button.isPointInside(181, 50)).toBe(false) // Just right
|
|
expect(button.isPointInside(100, 49)).toBe(false) // Just above
|
|
expect(button.isPointInside(100, 71)).toBe(false) // Just below
|
|
expect(button.isPointInside(0, 0)).toBe(false) // Far away
|
|
})
|
|
|
|
it("should work with buttons that have not been drawn yet", () => {
|
|
const button = new LGraphButton({ text: "Test" })
|
|
// _last_area has default values (0, 0, 0, 0)
|
|
|
|
expect(button.isPointInside(10, 10)).toBe(false)
|
|
expect(button.isPointInside(0, 0)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe("Integration with LGraphBadge", () => {
|
|
it("should properly inherit and use badge functionality", () => {
|
|
const button = new LGraphButton({
|
|
text: "→",
|
|
fontSize: 20,
|
|
color: "#FFFFFF",
|
|
backgroundColor: "#333333",
|
|
xOffset: -10,
|
|
yOffset: 5,
|
|
})
|
|
|
|
const ctx = {
|
|
measureText: vi.fn().mockReturnValue({ width: 20 }),
|
|
fillRect: vi.fn(),
|
|
fillText: vi.fn(),
|
|
beginPath: vi.fn(),
|
|
roundRect: vi.fn(),
|
|
fill: vi.fn(),
|
|
font: "",
|
|
fillStyle: "",
|
|
globalAlpha: 1,
|
|
} as unknown as CanvasRenderingContext2D
|
|
|
|
// Draw the button
|
|
button.draw(ctx, 100, 50)
|
|
|
|
// Verify button draws text without background
|
|
expect(ctx.beginPath).not.toHaveBeenCalled() // No background
|
|
expect(ctx.roundRect).not.toHaveBeenCalled() // No background
|
|
expect(ctx.fill).not.toHaveBeenCalled() // No background
|
|
expect(ctx.fillText).toHaveBeenCalledWith("→", expect.any(Number), expect.any(Number)) // Just text
|
|
})
|
|
})
|
|
})
|