Files
TUIkit/Tests/TUIkitTests/TextFieldHandlerTests.swift
T
phranck db8ea40c0a Refactor: Fix SwiftLint warnings and refactor StatusBar to _StatusBarCore pattern
- Fix 80 SwiftLint warnings (159 -> 79): vertical_whitespace, prefer_self_in_static_references, modifier_order, trailing_newline, trailing_whitespace, prefer_for_where, unneeded_synthesized_initializer, redundant_type_annotation, implicit_optional_initialization, superfluous_disable_command, shorthand_optional_binding, syntactic_sugar, empty_string, vertical_whitespace_closing_braces, identifier_name in BadgeModifier
- Refactor StatusBar from direct Renderable to _StatusBarCore pattern (public View with real body wrapping private Renderable core)
2026-02-15 02:35:18 +01:00

351 lines
11 KiB
Swift

// TUIKit - Terminal UI Kit for Swift
// TextFieldHandlerTests.swift
//
// Created by LAYERED.work
// License: MIT
import Testing
@testable import TUIkit
// MARK: - TextFieldHandler Tests
@MainActor
@Suite("TextFieldHandler Tests")
struct TextFieldHandlerTests {
// MARK: - Initialization
@Test("Handler initializes with correct defaults")
func initializationDefaults() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
#expect(handler.focusID == "test")
#expect(handler.canBeFocused == true)
#expect(handler.cursorPosition == 5) // End of "Hello"
}
@Test("Handler initializes with custom cursor position")
func initializationWithCursorPosition() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 2)
#expect(handler.cursorPosition == 2)
}
@Test("Handler initializes with empty text")
func initializationEmptyText() {
var text = ""
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
#expect(handler.cursorPosition == 0)
}
// MARK: - Character Insertion
@Test("Insert character at end")
func insertCharacterAtEnd() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
handler.insertCharacter("!")
#expect(text == "Hello!")
#expect(handler.cursorPosition == 6)
}
@Test("Insert character in middle")
func insertCharacterInMiddle() {
var text = "Hllo"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 1)
handler.insertCharacter("e")
#expect(text == "Hello")
#expect(handler.cursorPosition == 2)
}
@Test("Insert character at start")
func insertCharacterAtStart() {
var text = "ello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
handler.insertCharacter("H")
#expect(text == "Hello")
#expect(handler.cursorPosition == 1)
}
@Test("Insert space character")
func insertSpaceCharacter() {
var text = "HelloWorld"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 5)
handler.insertCharacter(" ")
#expect(text == "Hello World")
#expect(handler.cursorPosition == 6)
}
// MARK: - Delete Backward (Backspace)
@Test("Delete backward removes character before cursor")
func deleteBackward() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
handler.deleteBackward()
#expect(text == "Hell")
#expect(handler.cursorPosition == 4)
}
@Test("Delete backward in middle of text")
func deleteBackwardMiddle() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 3)
handler.deleteBackward()
#expect(text == "Helo")
#expect(handler.cursorPosition == 2)
}
@Test("Delete backward at start does nothing")
func deleteBackwardAtStart() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
handler.deleteBackward()
#expect(text == "Hello")
#expect(handler.cursorPosition == 0)
}
// MARK: - Delete Forward (Delete Key)
@Test("Delete forward removes character at cursor")
func deleteForward() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
handler.deleteForward()
#expect(text == "ello")
#expect(handler.cursorPosition == 0)
}
@Test("Delete forward in middle of text")
func deleteForwardMiddle() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 2)
handler.deleteForward()
#expect(text == "Helo")
#expect(handler.cursorPosition == 2)
}
@Test("Delete forward at end does nothing")
func deleteForwardAtEnd() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding) // Cursor at end
handler.deleteForward()
#expect(text == "Hello")
#expect(handler.cursorPosition == 5)
}
// MARK: - Cursor Movement
@Test("Move cursor left")
func moveCursorLeft() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
handler.moveCursorLeft()
#expect(handler.cursorPosition == 4)
}
@Test("Move cursor left at start stays at 0")
func moveCursorLeftAtStart() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
handler.moveCursorLeft()
#expect(handler.cursorPosition == 0)
}
@Test("Move cursor right")
func moveCursorRight() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 2)
handler.moveCursorRight()
#expect(handler.cursorPosition == 3)
}
@Test("Move cursor right at end stays at end")
func moveCursorRightAtEnd() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding) // Cursor at end
handler.moveCursorRight()
#expect(handler.cursorPosition == 5)
}
// MARK: - Key Event Handling
@Test("Character key event inserts character")
func handleCharacterKeyEvent() {
var text = ""
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
let handled = handler.handleKeyEvent(KeyEvent(key: .character("A")))
#expect(handled == true)
#expect(text == "A")
}
@Test("Backspace key event deletes backward")
func handleBackspaceKeyEvent() {
var text = "AB"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
let handled = handler.handleKeyEvent(KeyEvent(key: .backspace))
#expect(handled == true)
#expect(text == "A")
}
@Test("Delete key event deletes forward")
func handleDeleteKeyEvent() {
var text = "AB"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
let handled = handler.handleKeyEvent(KeyEvent(key: .delete))
#expect(handled == true)
#expect(text == "B")
}
@Test("Left arrow key event moves cursor left")
func handleLeftArrowKeyEvent() {
var text = "AB"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
let handled = handler.handleKeyEvent(KeyEvent(key: .left))
#expect(handled == true)
#expect(handler.cursorPosition == 1)
}
@Test("Right arrow key event moves cursor right")
func handleRightArrowKeyEvent() {
var text = "AB"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
let handled = handler.handleKeyEvent(KeyEvent(key: .right))
#expect(handled == true)
#expect(handler.cursorPosition == 1)
}
@Test("Home key event moves cursor to start")
func handleHomeKeyEvent() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
let handled = handler.handleKeyEvent(KeyEvent(key: .home))
#expect(handled == true)
#expect(handler.cursorPosition == 0)
}
@Test("End key event moves cursor to end")
func handleEndKeyEvent() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding, cursorPosition: 0)
let handled = handler.handleKeyEvent(KeyEvent(key: .end))
#expect(handled == true)
#expect(handler.cursorPosition == 5)
}
@Test("Enter key event triggers onSubmit")
func handleEnterKeyEvent() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
var submitCalled = false
handler.onSubmit = { submitCalled = true }
let handled = handler.handleKeyEvent(KeyEvent(key: .enter))
#expect(handled == true)
#expect(submitCalled == true)
}
@Test("Unhandled key event returns false")
func handleUnhandledKeyEvent() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
let handled = handler.handleKeyEvent(KeyEvent(key: .f1))
#expect(handled == false)
}
// MARK: - Cursor Clamping
@Test("Clamp cursor position when text shrinks")
func clampCursorPosition() {
var text = "Hello"
let binding = Binding(get: { text }, set: { text = $0 })
let handler = TextFieldHandler(focusID: "test", text: binding)
// Simulate external text change
text = "Hi"
handler.text = binding
handler.clampCursorPosition()
#expect(handler.cursorPosition == 2) // Clamped to "Hi".count
}
}