1922 lines
58 KiB
Lua
1922 lines
58 KiB
Lua
-- Comprehensive test suite for TextEditor module
|
|
-- Consolidated from multiple test files for complete coverage
|
|
package.path = package.path .. ";./?.lua;./modules/?.lua"
|
|
|
|
require("testing.loveStub")
|
|
local luaunit = require("testing.luaunit")
|
|
local ErrorHandler = require("modules.ErrorHandler")
|
|
|
|
-- Initialize ErrorHandler
|
|
ErrorHandler.init({})
|
|
|
|
local TextEditor = require("modules.TextEditor")
|
|
local Color = require("modules.Color")
|
|
local utils = require("modules.utils")
|
|
|
|
-- ============================================================================
|
|
-- Mock Dependencies and Helpers
|
|
-- ============================================================================
|
|
|
|
-- Mock Context
|
|
local MockContext = {
|
|
_immediateMode = false,
|
|
_focusedElement = nil,
|
|
setFocusedElement = function(self, element)
|
|
self._focusedElement = element
|
|
end,
|
|
}
|
|
|
|
-- Mock StateManager
|
|
local MockStateManager = {
|
|
getState = function(id) return nil end,
|
|
updateState = function(id, state) end,
|
|
saveState = function(id, state) end,
|
|
}
|
|
|
|
-- Helper to create TextEditor with dependencies
|
|
local function createTextEditor(config)
|
|
config = config or {}
|
|
return TextEditor.new(config, {
|
|
Context = MockContext,
|
|
StateManager = MockStateManager,
|
|
Color = Color,
|
|
utils = utils,
|
|
})
|
|
end
|
|
|
|
-- Helper to create mock element with full renderer support
|
|
local function createMockElement(width, height)
|
|
return {
|
|
_stateId = "test-element-1",
|
|
width = width or 200,
|
|
height = height or 30,
|
|
x = 10,
|
|
y = 10,
|
|
_absoluteX = 10,
|
|
_absoluteY = 10,
|
|
padding = {top = 5, right = 5, bottom = 5, left = 5},
|
|
_borderBoxWidth = (width or 200) + 10,
|
|
_borderBoxHeight = (height or 30) + 10,
|
|
getScaledContentPadding = function(self)
|
|
return self.padding
|
|
end,
|
|
_renderer = {
|
|
getFont = function(self, element)
|
|
return {
|
|
getWidth = function(text) return #text * 8 end,
|
|
getHeight = function() return 16 end,
|
|
}
|
|
end,
|
|
wrapLine = function(element, line, maxWidth)
|
|
-- Simple word wrapping simulation
|
|
line = tostring(line or "")
|
|
maxWidth = tonumber(maxWidth) or 1000
|
|
local words = {}
|
|
for word in line:gmatch("%S+") do
|
|
table.insert(words, word)
|
|
end
|
|
|
|
local wrapped = {}
|
|
local currentLine = ""
|
|
local startIdx = 0
|
|
|
|
for i, word in ipairs(words) do
|
|
local testLine = currentLine == "" and word or (currentLine .. " " .. word)
|
|
if #testLine * 8 <= maxWidth then
|
|
currentLine = testLine
|
|
else
|
|
if currentLine ~= "" then
|
|
table.insert(wrapped, {text = currentLine, startIdx = startIdx, endIdx = startIdx + #currentLine})
|
|
startIdx = startIdx + #currentLine + 1
|
|
end
|
|
currentLine = word
|
|
end
|
|
end
|
|
|
|
if currentLine ~= "" then
|
|
table.insert(wrapped, {text = currentLine, startIdx = startIdx, endIdx = startIdx + #currentLine})
|
|
end
|
|
|
|
return #wrapped > 0 and wrapped or {{text = line, startIdx = 0, endIdx = #line}}
|
|
end,
|
|
},
|
|
}
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Constructor and Initialization Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorConstructor = {}
|
|
|
|
function TestTextEditorConstructor:test_new_creates_with_defaults()
|
|
local editor = createTextEditor()
|
|
|
|
luaunit.assertNotNil(editor)
|
|
luaunit.assertFalse(editor.editable)
|
|
luaunit.assertFalse(editor.multiline)
|
|
luaunit.assertFalse(editor.passwordMode)
|
|
luaunit.assertEquals(editor.inputType, "text")
|
|
luaunit.assertEquals(editor._textBuffer, "")
|
|
luaunit.assertEquals(editor._cursorPosition, 0)
|
|
luaunit.assertFalse(editor._focused)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_new_accepts_config()
|
|
local editor = createTextEditor({
|
|
editable = true,
|
|
multiline = true,
|
|
passwordMode = true,
|
|
text = "Hello",
|
|
placeholder = "Enter text",
|
|
maxLength = 100,
|
|
inputType = "email",
|
|
})
|
|
|
|
luaunit.assertTrue(editor.editable)
|
|
luaunit.assertTrue(editor.multiline)
|
|
luaunit.assertTrue(editor.passwordMode)
|
|
luaunit.assertEquals(editor._textBuffer, "Hello")
|
|
luaunit.assertEquals(editor.placeholder, "Enter text")
|
|
luaunit.assertEquals(editor.maxLength, 100)
|
|
luaunit.assertEquals(editor.inputType, "email")
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_new_sanitizes_initial_text()
|
|
local editor = createTextEditor({
|
|
text = "Hello\n\nWorld",
|
|
multiline = false,
|
|
allowNewlines = false,
|
|
})
|
|
|
|
-- Newlines should be removed for single-line
|
|
luaunit.assertNotEquals(editor._textBuffer, "Hello\n\nWorld")
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_initialize_sets_element()
|
|
local editor = createTextEditor()
|
|
local element = createMockElement()
|
|
|
|
editor:initialize(element)
|
|
|
|
luaunit.assertEquals(editor._element, element)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_cursorBlinkRate_default()
|
|
local editor = createTextEditor()
|
|
luaunit.assertEquals(editor.cursorBlinkRate, 0.5)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_selectOnFocus_default()
|
|
local editor = createTextEditor()
|
|
luaunit.assertFalse(editor.selectOnFocus)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_allowTabs_default()
|
|
local editor = createTextEditor()
|
|
luaunit.assertTrue(editor.allowTabs)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_allowNewlines_follows_multiline()
|
|
local editor = createTextEditor({multiline = true})
|
|
luaunit.assertTrue(editor.allowNewlines)
|
|
|
|
editor = createTextEditor({multiline = false})
|
|
luaunit.assertFalse(editor.allowNewlines)
|
|
end
|
|
|
|
function TestTextEditorConstructor:test_allowNewlines_override()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
allowNewlines = false,
|
|
})
|
|
luaunit.assertFalse(editor.allowNewlines)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Text Buffer Operations Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorBufferOps = {}
|
|
|
|
function TestTextEditorBufferOps:test_getText_returns_text()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_getText_returns_empty_for_nil()
|
|
local editor = createTextEditor()
|
|
editor._textBuffer = nil
|
|
luaunit.assertEquals(editor:getText(), "")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_setText_updates_buffer()
|
|
local editor = createTextEditor()
|
|
editor:setText("New text")
|
|
luaunit.assertEquals(editor:getText(), "New text")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_setText_sanitizes()
|
|
local editor = createTextEditor({
|
|
multiline = false,
|
|
allowNewlines = false,
|
|
})
|
|
|
|
editor:setText("Line1\nLine2")
|
|
|
|
-- Should remove newlines for single-line
|
|
local text = editor:getText()
|
|
luaunit.assertFalse(text:find("\n") ~= nil)
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_setText_skips_sanitization()
|
|
local editor = createTextEditor({
|
|
multiline = false,
|
|
allowNewlines = false,
|
|
})
|
|
|
|
editor:setText("Line1\nLine2", true) -- skipSanitization = true
|
|
luaunit.assertEquals(editor:getText(), "Line1\nLine2")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_setText_with_empty_string()
|
|
local editor = createTextEditor()
|
|
editor:setText("")
|
|
luaunit.assertEquals(editor:getText(), "")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_setText_with_nil()
|
|
local editor = createTextEditor({text = "initial"})
|
|
editor:setText(nil)
|
|
luaunit.assertEquals(editor:getText(), "") -- Should default to empty string
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_at_position()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:insertText(" World", 5)
|
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_at_start()
|
|
local editor = createTextEditor({text = "World"})
|
|
editor:insertText("Hello ", 0)
|
|
luaunit.assertEquals(editor:getText(), "Hello World")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_with_empty_string()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:insertText("", 2)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should remain unchanged
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_at_invalid_position()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
-- Insert at negative position (should treat as 0)
|
|
editor:insertText("X", -10)
|
|
luaunit.assertStrContains(editor:getText(), "X")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_beyond_length()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:insertText("X", 1000)
|
|
luaunit.assertStrContains(editor:getText(), "X")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_when_at_maxLength()
|
|
local editor = createTextEditor({text = "Hello", maxLength = 5})
|
|
editor:insertText("X", 5)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not insert
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_insertText_updates_cursor()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(5)
|
|
editor:insertText(" World")
|
|
|
|
luaunit.assertEquals(editor:getCursorPosition(), 11)
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_deleteText_removes_range()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:deleteText(5, 11) -- Remove " World"
|
|
luaunit.assertEquals(editor:getText(), "Hello")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_deleteText_handles_reversed()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:deleteText(11, 5) -- Reversed: should swap
|
|
luaunit.assertEquals(editor:getText(), "Hello")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_deleteText_with_inverted_range()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:deleteText(10, 2) -- End before start
|
|
-- Should swap and delete
|
|
luaunit.assertEquals(#editor:getText(), 3) -- Deleted 8 characters
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_deleteText_beyond_bounds()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:deleteText(10, 20) -- Beyond text length
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should clamp to bounds
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_deleteText_with_negative_positions()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:deleteText(-5, -1) -- Negative positions
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should clamp to 0
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_replaceText_replaces_range()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:replaceText(6, 11, "Lua")
|
|
luaunit.assertEquals(editor:getText(), "Hello Lua")
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_replaceText_with_empty_string()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:replaceText(0, 5, "")
|
|
luaunit.assertEquals(editor:getText(), " World") -- Should just delete
|
|
end
|
|
|
|
function TestTextEditorBufferOps:test_replaceText_beyond_bounds()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:replaceText(10, 20, "X")
|
|
luaunit.assertStrContains(editor:getText(), "X")
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Cursor Position Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorCursor = {}
|
|
|
|
function TestTextEditorCursor:test_setCursorPosition()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(3)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 3)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_setCursorPosition_clamps()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(100) -- Beyond text length
|
|
luaunit.assertEquals(editor:getCursorPosition(), 5)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_setCursorPosition_negative()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(-10)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0) -- Should clamp to 0
|
|
end
|
|
|
|
function TestTextEditorCursor:test_setCursorPosition_with_non_number()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor._cursorPosition = "invalid" -- Corrupt state
|
|
editor:setCursorPosition(3)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 3) -- Should validate and fix
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorBy()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(2)
|
|
editor:moveCursorBy(2)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 4)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorBy_zero()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(2)
|
|
editor:moveCursorBy(0)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 2) -- Should stay same
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorBy_large_negative()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(2)
|
|
editor:moveCursorBy(-1000)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0) -- Should clamp to 0
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorBy_large_positive()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(2)
|
|
editor:moveCursorBy(1000)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 5) -- Should clamp to length
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorToStart()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setCursorPosition(3)
|
|
editor:moveCursorToStart()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursorToEnd()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:moveCursorToEnd()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 5)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_moveCursor_with_empty_buffer()
|
|
local editor = createTextEditor({text = ""})
|
|
editor:moveCursorToStart()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0)
|
|
editor:moveCursorToEnd()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_getCursorScreenPosition_single_line()
|
|
local editor = createTextEditor({text = "Hello", multiline = false})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(3)
|
|
local x, y = editor:_getCursorScreenPosition()
|
|
|
|
luaunit.assertNotNil(x)
|
|
luaunit.assertNotNil(y)
|
|
luaunit.assertTrue(x >= 0)
|
|
luaunit.assertEquals(y, 0)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_getCursorScreenPosition_multiline()
|
|
local editor = createTextEditor({text = "Line 1\nLine 2", multiline = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(10) -- Second line
|
|
local x, y = editor:_getCursorScreenPosition()
|
|
|
|
luaunit.assertNotNil(x)
|
|
luaunit.assertNotNil(y)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_getCursorScreenPosition_password_mode()
|
|
local editor = createTextEditor({
|
|
text = "password123",
|
|
passwordMode = true
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(8)
|
|
local x, y = editor:_getCursorScreenPosition()
|
|
|
|
luaunit.assertNotNil(x)
|
|
luaunit.assertEquals(y, 0)
|
|
end
|
|
|
|
function TestTextEditorCursor:test_getCursorScreenPosition_without_element()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local x, y = editor:_getCursorScreenPosition()
|
|
luaunit.assertEquals(x, 0)
|
|
luaunit.assertEquals(y, 0)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Word Navigation Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorWordNav = {}
|
|
|
|
function TestTextEditorWordNav:test_moveCursorToNextWord()
|
|
local editor = createTextEditor({text = "Hello World Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(0)
|
|
editor:moveCursorToNextWord()
|
|
|
|
luaunit.assertTrue(editor:getCursorPosition() > 0)
|
|
end
|
|
|
|
function TestTextEditorWordNav:test_moveCursorToPreviousWord()
|
|
local editor = createTextEditor({text = "Hello World Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(16)
|
|
editor:moveCursorToPreviousWord()
|
|
|
|
luaunit.assertTrue(editor:getCursorPosition() < 16)
|
|
end
|
|
|
|
function TestTextEditorWordNav:test_moveCursorToPreviousWord_at_start()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:moveCursorToStart()
|
|
editor:moveCursorToPreviousWord()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0) -- Should stay at start
|
|
end
|
|
|
|
function TestTextEditorWordNav:test_moveCursorToNextWord_at_end()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:moveCursorToEnd()
|
|
editor:moveCursorToNextWord()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 11) -- Should stay at end
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Selection Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorSelection = {}
|
|
|
|
function TestTextEditorSelection:test_setSelection()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:setSelection(0, 5)
|
|
|
|
local start, endPos = editor:getSelection()
|
|
luaunit.assertEquals(start, 0)
|
|
luaunit.assertEquals(endPos, 5)
|
|
end
|
|
|
|
function TestTextEditorSelection:test_setSelection_inverted_range()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:setSelection(10, 2) -- End before start
|
|
local start, endPos = editor:getSelection()
|
|
luaunit.assertTrue(start <= endPos) -- Should be swapped
|
|
end
|
|
|
|
function TestTextEditorSelection:test_setSelection_beyond_bounds()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setSelection(0, 1000)
|
|
local start, endPos = editor:getSelection()
|
|
luaunit.assertEquals(endPos, 5) -- Should clamp to length
|
|
end
|
|
|
|
function TestTextEditorSelection:test_setSelection_negative_positions()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setSelection(-5, -1)
|
|
local start, endPos = editor:getSelection()
|
|
luaunit.assertEquals(start, 0) -- Should clamp to 0
|
|
luaunit.assertEquals(endPos, 0)
|
|
end
|
|
|
|
function TestTextEditorSelection:test_setSelection_same_start_end()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setSelection(2, 2) -- Same position
|
|
luaunit.assertFalse(editor:hasSelection()) -- Should be no selection
|
|
end
|
|
|
|
function TestTextEditorSelection:test_hasSelection_true()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setSelection(0, 5)
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_hasSelection_false()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
luaunit.assertFalse(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_clearSelection()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:setSelection(0, 5)
|
|
editor:clearSelection()
|
|
luaunit.assertFalse(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_getSelectedText()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:setSelection(0, 5)
|
|
luaunit.assertEquals(editor:getSelectedText(), "Hello")
|
|
end
|
|
|
|
function TestTextEditorSelection:test_getSelectedText_with_no_selection()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
luaunit.assertNil(editor:getSelectedText())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_deleteSelection()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:setSelection(0, 6)
|
|
editor:deleteSelection()
|
|
luaunit.assertEquals(editor:getText(), "World")
|
|
luaunit.assertFalse(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_deleteSelection_with_no_selection()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local deleted = editor:deleteSelection()
|
|
luaunit.assertFalse(deleted) -- Should return false
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Text unchanged
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectAll()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:selectAll()
|
|
|
|
local start, endPos = editor:getSelection()
|
|
luaunit.assertEquals(start, 0)
|
|
luaunit.assertEquals(endPos, 11)
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectAll_with_empty_buffer()
|
|
local editor = createTextEditor({text = ""})
|
|
editor:selectAll()
|
|
luaunit.assertFalse(editor:hasSelection()) -- No selection on empty text
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectWordAtPosition()
|
|
local editor = createTextEditor({text = "Hello World Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_selectWordAtPosition(7) -- "World"
|
|
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
local selected = editor:getSelectedText()
|
|
luaunit.assertEquals(selected, "World")
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectWordAtPosition_with_punctuation()
|
|
local editor = createTextEditor({text = "Hello, World!"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_selectWordAtPosition(7) -- "World"
|
|
|
|
local selected = editor:getSelectedText()
|
|
luaunit.assertEquals(selected, "World")
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectWordAtPosition_empty()
|
|
local editor = createTextEditor({text = ""})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_selectWordAtPosition(0)
|
|
luaunit.assertFalse(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorSelection:test_selectWordAtPosition_on_whitespace()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
editor:_selectWordAtPosition(7) -- In whitespace
|
|
-- Behavior depends on implementation
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Selection Rectangle Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorSelectionRects = {}
|
|
|
|
function TestTextEditorSelectionRects:test_getSelectionRects_single_line()
|
|
local editor = createTextEditor({text = "Hello World", multiline = false})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setSelection(0, 5)
|
|
local rects = editor:_getSelectionRects(0, 5)
|
|
|
|
luaunit.assertNotNil(rects)
|
|
luaunit.assertTrue(#rects > 0)
|
|
luaunit.assertNotNil(rects[1].x)
|
|
luaunit.assertNotNil(rects[1].y)
|
|
luaunit.assertNotNil(rects[1].width)
|
|
luaunit.assertNotNil(rects[1].height)
|
|
end
|
|
|
|
function TestTextEditorSelectionRects:test_getSelectionRects_multiline()
|
|
local editor = createTextEditor({text = "Line 1\nLine 2\nLine 3", multiline = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Select across lines
|
|
editor:setSelection(0, 14) -- "Line 1\nLine 2"
|
|
local rects = editor:_getSelectionRects(0, 14)
|
|
|
|
luaunit.assertNotNil(rects)
|
|
luaunit.assertTrue(#rects > 0)
|
|
end
|
|
|
|
function TestTextEditorSelectionRects:test_getSelectionRects_password_mode()
|
|
local editor = createTextEditor({
|
|
text = "secret",
|
|
passwordMode = true,
|
|
multiline = false
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setSelection(0, 6)
|
|
local rects = editor:_getSelectionRects(0, 6)
|
|
|
|
luaunit.assertNotNil(rects)
|
|
luaunit.assertTrue(#rects > 0)
|
|
end
|
|
|
|
function TestTextEditorSelectionRects:test_getSelectionRects_empty_buffer()
|
|
local editor = createTextEditor({text = ""})
|
|
local mockElement = createMockElement()
|
|
editor:initialize(mockElement)
|
|
|
|
editor:setSelection(0, 0)
|
|
local rects = editor:_getSelectionRects(0, 0)
|
|
luaunit.assertEquals(#rects, 0) -- No rects for empty selection
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Focus and Blur Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorFocus = {}
|
|
|
|
function TestTextEditorFocus:test_focus()
|
|
local focusCalled = false
|
|
local editor = createTextEditor({
|
|
text = "Test",
|
|
onFocus = function() focusCalled = true end
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
luaunit.assertTrue(editor:isFocused())
|
|
luaunit.assertTrue(focusCalled)
|
|
end
|
|
|
|
function TestTextEditorFocus:test_blur()
|
|
local blurCalled = false
|
|
local editor = createTextEditor({
|
|
text = "Test",
|
|
onBlur = function() blurCalled = true end
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:blur()
|
|
luaunit.assertFalse(editor:isFocused())
|
|
luaunit.assertTrue(blurCalled)
|
|
end
|
|
|
|
function TestTextEditorFocus:test_selectOnFocus()
|
|
local editor = createTextEditor({
|
|
text = "Hello World",
|
|
selectOnFocus = true
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
luaunit.assertEquals(editor:getSelectedText(), "Hello World")
|
|
end
|
|
|
|
function TestTextEditorFocus:test_focus_without_element()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
luaunit.assertTrue(editor:isFocused())
|
|
end
|
|
|
|
function TestTextEditorFocus:test_blur_without_element()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
editor:blur()
|
|
luaunit.assertFalse(editor:isFocused())
|
|
end
|
|
|
|
function TestTextEditorFocus:test_focus_twice()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
editor:focus() -- Focus again
|
|
luaunit.assertTrue(editor:isFocused()) -- Should remain focused
|
|
end
|
|
|
|
function TestTextEditorFocus:test_blur_twice()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
editor:blur()
|
|
editor:blur() -- Blur again
|
|
luaunit.assertFalse(editor:isFocused()) -- Should remain blurred
|
|
end
|
|
|
|
function TestTextEditorFocus:test_focus_blurs_previous()
|
|
local editor1 = createTextEditor({text = "Editor 1"})
|
|
local editor2 = createTextEditor({text = "Editor 2"})
|
|
|
|
local element1 = createMockElement()
|
|
local element2 = createMockElement()
|
|
|
|
element1._textEditor = editor1
|
|
element2._textEditor = editor2
|
|
|
|
editor1:initialize(element1)
|
|
editor2:initialize(element2)
|
|
|
|
MockContext._focusedElement = element1
|
|
editor1:focus()
|
|
|
|
-- Focus second editor
|
|
editor2:focus()
|
|
|
|
luaunit.assertFalse(editor1:isFocused())
|
|
luaunit.assertTrue(editor2:isFocused())
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Keyboard Input Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorKeyboard = {}
|
|
|
|
function TestTextEditorKeyboard:test_handleTextInput()
|
|
local editor = createTextEditor({text = "", editable = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleTextInput("H")
|
|
editor:handleTextInput("i")
|
|
|
|
luaunit.assertEquals(editor:getText(), "Hi")
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleTextInput_without_focus()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:handleTextInput("X")
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not insert
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleTextInput_empty_string()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:handleTextInput("")
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not modify
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleTextInput_newline_in_singleline()
|
|
local editor = createTextEditor({text = "Hello", multiline = false, allowNewlines = false})
|
|
editor:focus()
|
|
editor:handleTextInput("\n")
|
|
-- Should sanitize newline in single-line mode
|
|
luaunit.assertFalse(editor:getText():find("\n") ~= nil)
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleTextInput_callback_returns_false()
|
|
local editor = createTextEditor({
|
|
text = "Hello",
|
|
onTextInput = function(element, text)
|
|
return false -- Reject input
|
|
end,
|
|
})
|
|
local mockElement = createMockElement()
|
|
editor:initialize(mockElement)
|
|
editor:focus()
|
|
editor:handleTextInput("X")
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not insert
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_backspace()
|
|
local editor = createTextEditor({text = "Hello", editable = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(5)
|
|
editor:handleKeyPress("backspace", "backspace", false)
|
|
|
|
luaunit.assertEquals(editor:getText(), "Hell")
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_backspace_at_start()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:moveCursorToStart()
|
|
editor:handleKeyPress("backspace", "backspace", false)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not delete
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_delete()
|
|
local editor = createTextEditor({text = "Hello", editable = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(0)
|
|
editor:handleKeyPress("delete", "delete", false)
|
|
|
|
luaunit.assertEquals(editor:getText(), "ello")
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_delete_at_end()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:moveCursorToEnd()
|
|
editor:handleKeyPress("delete", "delete", false)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not delete
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_return_multiline()
|
|
local editor = createTextEditor({text = "Hello", editable = true, multiline = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(5)
|
|
editor:handleKeyPress("return", "return", false)
|
|
editor:handleTextInput("World")
|
|
|
|
luaunit.assertEquals(editor:getText(), "Hello\nWorld")
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_return_singleline()
|
|
local onEnterCalled = false
|
|
local editor = createTextEditor({
|
|
text = "Hello",
|
|
editable = true,
|
|
multiline = false,
|
|
onEnter = function() onEnterCalled = true end
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleKeyPress("return", "return", false)
|
|
|
|
luaunit.assertTrue(onEnterCalled)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not add newline
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_home_end()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(5)
|
|
|
|
-- Home key
|
|
editor:handleKeyPress("home", "home", false)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0)
|
|
|
|
-- End key
|
|
editor:handleKeyPress("end", "end", false)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 11)
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_arrow_keys()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(2)
|
|
|
|
-- Right arrow
|
|
editor:handleKeyPress("right", "right", false)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 3)
|
|
|
|
-- Left arrow
|
|
editor:handleKeyPress("left", "left", false)
|
|
luaunit.assertEquals(editor:getCursorPosition(), 2)
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_without_focus()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:handleKeyPress("backspace", "backspace", false)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should not modify
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_unknown_key()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:handleKeyPress("unknownkey", "unknownkey", false)
|
|
luaunit.assertEquals(editor:getText(), "Hello") -- Should ignore
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_escape_with_selection()
|
|
local editor = createTextEditor({text = "Select me"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:selectAll()
|
|
|
|
editor:handleKeyPress("escape", "escape", false)
|
|
|
|
luaunit.assertFalse(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_escape_without_selection()
|
|
local editor = createTextEditor({text = "Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleKeyPress("escape", "escape", false)
|
|
|
|
luaunit.assertFalse(editor:isFocused())
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_arrow_with_shift()
|
|
local editor = createTextEditor({text = "Select this"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(0)
|
|
|
|
-- Simulate shift+right arrow
|
|
love.keyboard.setDown("lshift", true)
|
|
editor:handleKeyPress("right", "right", false)
|
|
love.keyboard.setDown("lshift", false)
|
|
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
end
|
|
|
|
function TestTextEditorKeyboard:test_handleKeyPress_ctrl_backspace()
|
|
local editor = createTextEditor({text = "Delete this"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(11)
|
|
|
|
-- Simulate ctrl+backspace
|
|
love.keyboard.setDown("lctrl", true)
|
|
editor:handleKeyPress("backspace", "backspace", false)
|
|
love.keyboard.setDown("lctrl", false)
|
|
|
|
luaunit.assertEquals(editor:getText(), "")
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Mouse Interaction Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorMouse = {}
|
|
|
|
function TestTextEditorMouse:test_mouseToTextPosition()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Click in middle of text (approximate)
|
|
local pos = editor:mouseToTextPosition(40, 10)
|
|
luaunit.assertNotNil(pos)
|
|
luaunit.assertTrue(pos >= 0 and pos <= 11)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_mouseToTextPosition_without_element()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local pos = editor:mouseToTextPosition(10, 10)
|
|
luaunit.assertEquals(pos, 0) -- Should return 0 without element
|
|
end
|
|
|
|
function TestTextEditorMouse:test_mouseToTextPosition_with_nil_buffer()
|
|
local editor = createTextEditor()
|
|
local mockElement = createMockElement()
|
|
mockElement.x = 0
|
|
mockElement.y = 0
|
|
editor:initialize(mockElement)
|
|
editor._textBuffer = nil
|
|
|
|
local pos = editor:mouseToTextPosition(10, 10)
|
|
luaunit.assertEquals(pos, 0) -- Should handle nil buffer
|
|
end
|
|
|
|
function TestTextEditorMouse:test_mouseToTextPosition_negative_coords()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
local mockElement = createMockElement()
|
|
mockElement.x = 100
|
|
mockElement.y = 100
|
|
editor:initialize(mockElement)
|
|
|
|
local pos = editor:mouseToTextPosition(-10, -10)
|
|
luaunit.assertTrue(pos >= 0) -- Should clamp to valid position
|
|
end
|
|
|
|
function TestTextEditorMouse:test_mouseToTextPosition_multiline()
|
|
local editor = createTextEditor({text = "Line 1\nLine 2\nLine 3", multiline = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Click on second line
|
|
local pos = editor:mouseToTextPosition(20, 25)
|
|
|
|
luaunit.assertNotNil(pos)
|
|
luaunit.assertTrue(pos >= 0) -- Valid position
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextClick_single_click()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:handleTextClick(40, 10, 1)
|
|
luaunit.assertTrue(editor:getCursorPosition() >= 0)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextClick_double_click()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
-- Double click on first word
|
|
editor:handleTextClick(20, 10, 2)
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
local selected = editor:getSelectedText()
|
|
luaunit.assertTrue(selected == "Hello" or selected == "World")
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextClick_triple_click()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleTextClick(20, 10, 3)
|
|
luaunit.assertTrue(editor:hasSelection())
|
|
luaunit.assertEquals(editor:getSelectedText(), "Hello World")
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextClick_without_focus()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:handleTextClick(10, 10, 1)
|
|
-- Should not error, but also won't do anything without focus
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextClick_zero_count()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:handleTextClick(10, 10, 0)
|
|
-- Should not error
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextDrag()
|
|
local editor = createTextEditor({text = "Hello World"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
-- Start at text beginning (element x=10 + padding left=5 = 15)
|
|
editor:handleTextClick(15, 15, 1)
|
|
|
|
-- Verify mouseDownPosition was set
|
|
luaunit.assertNotNil(editor._mouseDownPosition)
|
|
|
|
-- Drag to position much further right (should be different position)
|
|
editor:handleTextDrag(100, 15)
|
|
|
|
-- If still no selection, the positions might be the same - just verify drag was called
|
|
luaunit.assertTrue(editor:hasSelection() or editor._mouseDownPosition ~= nil)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextDrag_without_mousedown()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:focus()
|
|
editor:handleTextDrag(20, 10) -- Drag without mouseDownPosition
|
|
-- Should not error
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorMouse:test_handleTextDrag_sets_flag()
|
|
local editor = createTextEditor({text = "Drag me"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleTextClick(10, 10, 1)
|
|
editor:handleTextDrag(50, 10)
|
|
|
|
luaunit.assertTrue(editor._textDragOccurred or not editor:hasSelection())
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Multiline Text Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorMultiline = {}
|
|
|
|
function TestTextEditorMultiline:test_multiline_split_lines()
|
|
local editor = createTextEditor({multiline = true, text = "Line 1\nLine 2\nLine 3"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_splitLines()
|
|
luaunit.assertNotNil(editor._lines)
|
|
luaunit.assertEquals(#editor._lines, 3)
|
|
luaunit.assertEquals(editor._lines[1], "Line 1")
|
|
luaunit.assertEquals(editor._lines[2], "Line 2")
|
|
luaunit.assertEquals(editor._lines[3], "Line 3")
|
|
end
|
|
|
|
function TestTextEditorMultiline:test_multiline_cursor_movement()
|
|
local editor = createTextEditor({multiline = true, text = "Line 1\nLine 2"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Move to end
|
|
editor:moveCursorToEnd()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 13) -- "Line 1\nLine 2" = 13 chars
|
|
|
|
-- Move to start
|
|
editor:moveCursorToStart()
|
|
luaunit.assertEquals(editor:getCursorPosition(), 0)
|
|
end
|
|
|
|
function TestTextEditorMultiline:test_multiline_insert_newline()
|
|
local editor = createTextEditor({multiline = true, text = "Hello"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setCursorPosition(5)
|
|
editor:insertText("\n", 5)
|
|
editor:insertText("World", 6)
|
|
|
|
luaunit.assertEquals(editor:getText(), "Hello\nWorld")
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Text Wrapping Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorWrapping = {}
|
|
|
|
function TestTextEditorWrapping:test_word_wrapping()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
textWrap = "word",
|
|
text = "This is a long line that should wrap"
|
|
})
|
|
local element = createMockElement(50, 100) -- Very narrow width to force wrapping
|
|
editor:initialize(element)
|
|
|
|
editor._textDirty = true
|
|
editor:_updateTextIfDirty()
|
|
luaunit.assertNotNil(editor._wrappedLines)
|
|
luaunit.assertTrue(#editor._wrappedLines >= 1) -- Should have wrapped lines
|
|
end
|
|
|
|
function TestTextEditorWrapping:test_char_wrapping()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
textWrap = "char",
|
|
text = "Verylongwordwithoutspaces"
|
|
})
|
|
local element = createMockElement(100, 100)
|
|
editor:initialize(element)
|
|
|
|
editor:_calculateWrapping()
|
|
luaunit.assertNotNil(editor._wrappedLines)
|
|
end
|
|
|
|
function TestTextEditorWrapping:test_no_wrapping()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
textWrap = false,
|
|
text = "This is a long line that should not wrap"
|
|
})
|
|
local element = createMockElement(100, 100)
|
|
editor:initialize(element)
|
|
|
|
editor:_calculateWrapping()
|
|
-- With textWrap = false, _wrappedLines should be nil
|
|
luaunit.assertNil(editor._wrappedLines)
|
|
end
|
|
|
|
function TestTextEditorWrapping:test_wrapLine_empty_line()
|
|
local editor = createTextEditor({multiline = true, textWrap = "word"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
local wrapped = editor:_wrapLine("", 100)
|
|
|
|
luaunit.assertNotNil(wrapped)
|
|
luaunit.assertTrue(#wrapped > 0)
|
|
end
|
|
|
|
function TestTextEditorWrapping:test_calculateWrapping_empty_lines()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
textWrap = "word",
|
|
text = "Line 1\n\nLine 3"
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_calculateWrapping()
|
|
|
|
luaunit.assertNotNil(editor._wrappedLines)
|
|
end
|
|
|
|
function TestTextEditorWrapping:test_calculateWrapping_no_element()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
textWrap = "word",
|
|
text = "Test"
|
|
})
|
|
|
|
-- No element initialized
|
|
editor:_calculateWrapping()
|
|
|
|
luaunit.assertNil(editor._wrappedLines)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Sanitization Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorSanitization = {}
|
|
|
|
function TestTextEditorSanitization:test_sanitize_max_length()
|
|
local editor = createTextEditor({maxLength = 5})
|
|
editor:setText("HelloWorld")
|
|
luaunit.assertEquals(editor:getText(), "Hello")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_sanitize_zero_maxLength()
|
|
local editor = createTextEditor({maxLength = 0})
|
|
editor:setText("test")
|
|
luaunit.assertEquals(editor:getText(), "") -- Should be empty
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_sanitization_disabled()
|
|
local editor = createTextEditor({
|
|
sanitize = false,
|
|
multiline = false,
|
|
allowNewlines = false,
|
|
})
|
|
|
|
editor:setText("Line1\nLine2")
|
|
|
|
-- Should NOT sanitize newlines when disabled
|
|
luaunit.assertEquals(editor:getText(), "Line1\nLine2")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_custom_sanitizer()
|
|
local editor = createTextEditor({
|
|
customSanitizer = function(text)
|
|
return text:upper()
|
|
end,
|
|
})
|
|
|
|
editor:setText("hello")
|
|
luaunit.assertEquals(editor:getText(), "HELLO")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_custom_sanitizer_via_sanitizeText()
|
|
local editor = createTextEditor({
|
|
customSanitizer = function(text)
|
|
return text:upper()
|
|
end,
|
|
})
|
|
|
|
local result = editor:_sanitizeText("hello world")
|
|
luaunit.assertEquals(result, "HELLO WORLD")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_custom_sanitizer_returns_nil()
|
|
local editor = createTextEditor({
|
|
customSanitizer = function(text)
|
|
return nil
|
|
end,
|
|
})
|
|
|
|
editor:setText("test")
|
|
-- Should fallback to original text when sanitizer returns nil
|
|
luaunit.assertEquals(editor:getText(), "test")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_custom_sanitizer_throws_error()
|
|
-- Should error when creating editor with faulty sanitizer that throws during initial sanitization
|
|
luaunit.assertErrorMsgContains("Intentional error", function()
|
|
createTextEditor({
|
|
text = "initial",
|
|
customSanitizer = function(text)
|
|
error("Intentional error")
|
|
end,
|
|
})
|
|
end)
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_sanitize_disabled_via_flag()
|
|
local editor = createTextEditor({
|
|
sanitize = false,
|
|
maxLength = 5,
|
|
})
|
|
|
|
local result = editor:_sanitizeText("This is a very long text")
|
|
-- Should not be truncated since sanitize is false
|
|
luaunit.assertEquals(result, "This is a very long text")
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_disallow_newlines()
|
|
local editor = createTextEditor({
|
|
text = "",
|
|
editable = true,
|
|
multiline = false,
|
|
allowNewlines = false
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setText("Hello\nWorld")
|
|
-- Newlines should be removed or replaced
|
|
luaunit.assertNil(editor:getText():find("\n"))
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_disallow_tabs()
|
|
local editor = createTextEditor({
|
|
text = "",
|
|
editable = true,
|
|
allowTabs = false
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setText("Hello\tWorld")
|
|
-- Tabs should be removed or replaced
|
|
luaunit.assertNil(editor:getText():find("\t"))
|
|
end
|
|
|
|
function TestTextEditorSanitization:test_onSanitize_callback()
|
|
local callbackCalled = false
|
|
local originalText = nil
|
|
local sanitizedText = nil
|
|
|
|
local editor = createTextEditor({
|
|
maxLength = 5,
|
|
onSanitize = function(element, original, sanitized)
|
|
callbackCalled = true
|
|
originalText = original
|
|
sanitizedText = sanitized
|
|
end,
|
|
})
|
|
|
|
local mockElement = createMockElement()
|
|
editor:initialize(mockElement)
|
|
|
|
-- Insert text that exceeds maxLength
|
|
editor:_sanitizeText("This is a long text that exceeds max length")
|
|
|
|
luaunit.assertTrue(callbackCalled)
|
|
luaunit.assertEquals(originalText, "This is a long text that exceeds max length")
|
|
luaunit.assertEquals(sanitizedText, "This ")
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Password Mode Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorPassword = {}
|
|
|
|
function TestTextEditorPassword:test_password_mode_masks_text()
|
|
local editor = createTextEditor({text = "secret123", passwordMode = true})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Password mode should be enabled
|
|
luaunit.assertTrue(editor.passwordMode)
|
|
|
|
-- The actual text should still be stored
|
|
luaunit.assertEquals(editor:getText(), "secret123")
|
|
end
|
|
|
|
function TestTextEditorPassword:test_password_mode_empty_text()
|
|
local editor = createTextEditor({passwordMode = true, text = ""})
|
|
luaunit.assertEquals(editor:getText(), "")
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Input Validation Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorValidation = {}
|
|
|
|
function TestTextEditorValidation:test_number_input_type()
|
|
local editor = createTextEditor({text = "", editable = true, inputType = "number"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:handleTextInput("123")
|
|
luaunit.assertEquals(editor:getText(), "123")
|
|
|
|
-- Non-numeric input should be sanitized
|
|
editor:handleTextInput("abc")
|
|
-- Sanitization behavior depends on implementation
|
|
end
|
|
|
|
function TestTextEditorValidation:test_max_length()
|
|
local editor = createTextEditor({text = "", editable = true, maxLength = 5})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:setText("12345")
|
|
luaunit.assertEquals(editor:getText(), "12345")
|
|
|
|
editor:setText("123456789")
|
|
luaunit.assertEquals(editor:getText(), "12345") -- Should be truncated
|
|
end
|
|
|
|
function TestTextEditorValidation:test_invalid_input_type()
|
|
-- Invalid input type (not validated by constructor)
|
|
local editor = createTextEditor({inputType = "invalid"})
|
|
luaunit.assertEquals(editor.inputType, "invalid")
|
|
end
|
|
|
|
function TestTextEditorValidation:test_negative_maxLength()
|
|
-- Negative maxLength should be ignored
|
|
local editor = createTextEditor({maxLength = -10})
|
|
luaunit.assertEquals(editor.maxLength, -10) -- Module doesn't validate, just stores
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Cursor Blink and Update Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorUpdate = {}
|
|
|
|
function TestTextEditorUpdate:test_update_cursor_blink()
|
|
local editor = createTextEditor({text = "Test", cursorBlinkRate = 0.5})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
|
|
-- Initial state
|
|
local initialVisible = editor._cursorVisible
|
|
|
|
-- Update for half the blink rate
|
|
editor:update(0.25)
|
|
luaunit.assertEquals(editor._cursorVisible, initialVisible)
|
|
|
|
-- Update to complete blink cycle
|
|
editor:update(0.26)
|
|
luaunit.assertNotEquals(editor._cursorVisible, initialVisible)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_pause()
|
|
local editor = createTextEditor({text = "Test", cursorBlinkRate = 0.5})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:_resetCursorBlink(true) -- Pause blink
|
|
|
|
luaunit.assertTrue(editor._cursorBlinkPaused)
|
|
luaunit.assertTrue(editor._cursorVisible)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_pause_resume()
|
|
local editor = createTextEditor({text = "Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:_resetCursorBlink(true) -- Pause
|
|
|
|
luaunit.assertTrue(editor._cursorBlinkPaused)
|
|
|
|
-- Update to resume blink
|
|
editor:update(0.6) -- More than 0.5 second pause
|
|
|
|
luaunit.assertFalse(editor._cursorBlinkPaused)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_update_not_focused()
|
|
local editor = createTextEditor({text = "Test"})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
-- Not focused - update should exit early
|
|
editor:update(0.1)
|
|
luaunit.assertTrue(true) -- Should not crash
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_update_without_focus()
|
|
local editor = createTextEditor()
|
|
editor:update(1.0) -- Should not update cursor blink
|
|
luaunit.assertTrue(true) -- Should not error
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_update_negative_dt()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
editor:update(-1.0) -- Negative delta time
|
|
-- Should not error
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_update_zero_dt()
|
|
local editor = createTextEditor()
|
|
editor:focus()
|
|
editor:update(0) -- Zero delta time
|
|
-- Should not error
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_cycle()
|
|
local editor = createTextEditor({text = "Test", cursorBlinkRate = 0.5})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
local initialVisible = editor._cursorVisible
|
|
|
|
-- Complete a full blink cycle
|
|
editor:update(0.5)
|
|
luaunit.assertNotEquals(editor._cursorVisible, initialVisible)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_rate_negative()
|
|
-- Negative blink rate
|
|
local editor = createTextEditor({cursorBlinkRate = -1})
|
|
luaunit.assertEquals(editor.cursorBlinkRate, -1) -- Should accept any value
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_rate_zero()
|
|
-- Zero blink rate (would cause rapid blinking)
|
|
local editor = createTextEditor({cursorBlinkRate = 0})
|
|
luaunit.assertEquals(editor.cursorBlinkRate, 0)
|
|
end
|
|
|
|
function TestTextEditorUpdate:test_cursor_blink_rate_large()
|
|
-- Very large blink rate
|
|
local editor = createTextEditor({cursorBlinkRate = 1000})
|
|
luaunit.assertEquals(editor.cursorBlinkRate, 1000)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Text Scroll Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorScroll = {}
|
|
|
|
function TestTextEditorScroll:test_updateTextScroll()
|
|
local editor = createTextEditor({text = "This is very long text that needs scrolling"})
|
|
local element = createMockElement(100, 30)
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:moveCursorToEnd()
|
|
editor:_updateTextScroll()
|
|
|
|
-- Scroll should be updated
|
|
luaunit.assertTrue(editor._textScrollX >= 0)
|
|
end
|
|
|
|
function TestTextEditorScroll:test_updateTextScroll_keeps_cursor_visible()
|
|
local editor = createTextEditor({text = "Long text here"})
|
|
local element = createMockElement(50, 30)
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor:setCursorPosition(10)
|
|
editor:_updateTextScroll()
|
|
|
|
local scrollX = editor._textScrollX
|
|
luaunit.assertTrue(scrollX >= 0)
|
|
end
|
|
|
|
function TestTextEditorScroll:test_mouseToTextPosition_with_scroll()
|
|
local editor = createTextEditor({text = "Very long scrolling text"})
|
|
local element = createMockElement(100, 30)
|
|
editor:initialize(element)
|
|
|
|
editor:focus()
|
|
editor._textScrollX = 50
|
|
|
|
local pos = editor:mouseToTextPosition(30, 15)
|
|
luaunit.assertNotNil(pos)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Auto-grow Height Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorAutoGrow = {}
|
|
|
|
function TestTextEditorAutoGrow:test_updateAutoGrowHeight_single_line()
|
|
local editor = createTextEditor({
|
|
multiline = false,
|
|
autoGrow = true,
|
|
text = "Single line"
|
|
})
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:updateAutoGrowHeight()
|
|
-- Single line should not trigger height change
|
|
luaunit.assertNotNil(element.height)
|
|
end
|
|
|
|
function TestTextEditorAutoGrow:test_updateAutoGrowHeight_multiline()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
autoGrow = true,
|
|
text = "Line 1\nLine 2\nLine 3"
|
|
})
|
|
local element = createMockElement(200, 50)
|
|
editor:initialize(element)
|
|
|
|
local initialHeight = element.height
|
|
editor:updateAutoGrowHeight()
|
|
|
|
-- Height should be updated based on line count
|
|
luaunit.assertNotNil(element.height)
|
|
end
|
|
|
|
function TestTextEditorAutoGrow:test_updateAutoGrowHeight_with_wrapping()
|
|
local editor = createTextEditor({
|
|
multiline = true,
|
|
autoGrow = true,
|
|
textWrap = "word",
|
|
text = "This is a very long line that will wrap multiple times when displayed"
|
|
})
|
|
local element = createMockElement(100, 50)
|
|
editor:initialize(element)
|
|
|
|
editor:updateAutoGrowHeight()
|
|
-- Should account for wrapped lines
|
|
luaunit.assertNotNil(element.height)
|
|
end
|
|
|
|
function TestTextEditorAutoGrow:test_autoGrow_without_element()
|
|
local editor = createTextEditor({autoGrow = true, multiline = true})
|
|
editor:updateAutoGrowHeight()
|
|
-- Should not error without element
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
function TestTextEditorAutoGrow:test_textWrap_zero_width()
|
|
local editor = createTextEditor({textWrap = true})
|
|
local mockElement = createMockElement()
|
|
mockElement.width = 0
|
|
editor:initialize(mockElement)
|
|
editor:setText("Hello World")
|
|
-- Should handle zero width gracefully
|
|
luaunit.assertTrue(true)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- UTF-8 Edge Cases
|
|
-- ============================================================================
|
|
|
|
TestTextEditorUTF8 = {}
|
|
|
|
function TestTextEditorUTF8:test_setText_with_emoji()
|
|
local editor = createTextEditor()
|
|
editor:setText("Hello 👋 World 🌍")
|
|
luaunit.assertStrContains(editor:getText(), "👋")
|
|
luaunit.assertStrContains(editor:getText(), "🌍")
|
|
end
|
|
|
|
function TestTextEditorUTF8:test_insertText_with_utf8()
|
|
local editor = createTextEditor({text = "Hello"})
|
|
editor:insertText("世界", 5) -- Chinese characters
|
|
luaunit.assertStrContains(editor:getText(), "世界")
|
|
end
|
|
|
|
function TestTextEditorUTF8:test_cursorPosition_with_utf8()
|
|
local editor = createTextEditor({text = "Hello👋World"})
|
|
-- Cursor positions should be in characters, not bytes
|
|
editor:setCursorPosition(6) -- After emoji
|
|
luaunit.assertEquals(editor:getCursorPosition(), 6)
|
|
end
|
|
|
|
function TestTextEditorUTF8:test_deleteText_with_utf8()
|
|
local editor = createTextEditor({text = "Hello👋World"})
|
|
editor:deleteText(5, 6) -- Delete emoji
|
|
luaunit.assertEquals(editor:getText(), "HelloWorld")
|
|
end
|
|
|
|
function TestTextEditorUTF8:test_maxLength_with_utf8()
|
|
local editor = createTextEditor({maxLength = 10})
|
|
editor:setText("Hello👋👋👋👋👋") -- 10 characters including emojis
|
|
local len = utf8.len(editor:getText())
|
|
luaunit.assertNotNil(len, "UTF-8 length should not be nil")
|
|
luaunit.assertTrue(len <= 10)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- State Management Tests
|
|
-- ============================================================================
|
|
|
|
TestTextEditorStateSaving = {}
|
|
|
|
function TestTextEditorStateSaving:test_initialize_immediate_mode_with_state()
|
|
local mockStateManager = {
|
|
getState = function(id)
|
|
return {
|
|
_focused = true,
|
|
_textBuffer = "restored text",
|
|
_cursorPosition = 10,
|
|
_selectionStart = 2,
|
|
_selectionEnd = 5,
|
|
_cursorBlinkTimer = 0.3,
|
|
_cursorVisible = false,
|
|
_cursorBlinkPaused = true,
|
|
_cursorBlinkPauseTimer = 1.0,
|
|
}
|
|
end,
|
|
saveState = function(id, state) end,
|
|
}
|
|
|
|
local mockContext = {
|
|
_immediateMode = true,
|
|
_focusedElement = nil,
|
|
}
|
|
|
|
local editor = TextEditor.new({}, {
|
|
Context = mockContext,
|
|
StateManager = mockStateManager,
|
|
Color = Color,
|
|
utils = utils,
|
|
})
|
|
|
|
local mockElement = createMockElement()
|
|
editor:initialize(mockElement)
|
|
|
|
-- State should be fully restored
|
|
luaunit.assertEquals(editor._textBuffer, "restored text")
|
|
luaunit.assertEquals(editor._cursorPosition, 10)
|
|
luaunit.assertEquals(editor._selectionStart, 2)
|
|
luaunit.assertEquals(editor._selectionEnd, 5)
|
|
luaunit.assertEquals(editor._cursorBlinkTimer, 0.3)
|
|
luaunit.assertEquals(editor._cursorVisible, false)
|
|
luaunit.assertEquals(editor._cursorBlinkPaused, true)
|
|
luaunit.assertEquals(editor._cursorBlinkPauseTimer, 1.0)
|
|
luaunit.assertTrue(editor._focused)
|
|
luaunit.assertEquals(mockContext._focusedElement, mockElement)
|
|
end
|
|
|
|
function TestTextEditorStateSaving:test_saveState_immediate_mode()
|
|
local savedState = nil
|
|
local mockStateManager = {
|
|
getState = function(id) return nil end,
|
|
updateState = function(id, state)
|
|
savedState = state
|
|
end,
|
|
}
|
|
|
|
local mockContext = {
|
|
_immediateMode = true,
|
|
_focusedElement = nil,
|
|
}
|
|
|
|
local editor = TextEditor.new({text = "Test"}, {
|
|
Context = mockContext,
|
|
StateManager = mockStateManager,
|
|
Color = Color,
|
|
utils = utils,
|
|
})
|
|
|
|
local element = createMockElement()
|
|
element._stateId = "test-state-id"
|
|
editor:initialize(element)
|
|
|
|
editor:setText("New text")
|
|
|
|
luaunit.assertNotNil(savedState)
|
|
luaunit.assertEquals(savedState._textBuffer, "New text")
|
|
end
|
|
|
|
function TestTextEditorStateSaving:test_saveState_not_immediate_mode()
|
|
local saveCalled = false
|
|
local mockStateManager = {
|
|
getState = function(id) return nil end,
|
|
updateState = function(id, state)
|
|
saveCalled = true
|
|
end,
|
|
}
|
|
|
|
local mockContext = {
|
|
_immediateMode = false,
|
|
_focusedElement = nil,
|
|
}
|
|
|
|
local editor = TextEditor.new({text = "Test"}, {
|
|
Context = mockContext,
|
|
StateManager = mockStateManager,
|
|
Color = Color,
|
|
utils = utils,
|
|
})
|
|
|
|
local element = createMockElement()
|
|
editor:initialize(element)
|
|
|
|
editor:_saveState()
|
|
|
|
-- Should not save in retained mode
|
|
luaunit.assertFalse(saveCalled)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- Run Tests
|
|
-- ============================================================================
|
|
|
|
if not _G.RUNNING_ALL_TESTS then
|
|
os.exit(luaunit.LuaUnit.run())
|
|
end
|