From a01369f4074f180bdd5a2e1bda708b5ae28c3333 Mon Sep 17 00:00:00 2001 From: Hayden Hargreaves Date: Thu, 19 Mar 2026 17:31:53 -0700 Subject: [PATCH] fix: cleaned up the testing mocking. New single module --- internal/action/command_history_test.go | 92 +- internal/action/find_test.go | 320 ++-- internal/action/mock.go | 133 ++ internal/command/handlers_test.go | 1828 +++++++++++------------ internal/motion/command_test.go | 217 +-- 5 files changed, 1190 insertions(+), 1400 deletions(-) create mode 100644 internal/action/mock.go diff --git a/internal/action/command_history_test.go b/internal/action/command_history_test.go index 277a48d..e6a9054 100644 --- a/internal/action/command_history_test.go +++ b/internal/action/command_history_test.go @@ -7,29 +7,6 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -// mockModelForHistory is a minimal mock for testing command history -type mockModelForHistory struct { - mockModel - commandHistory []string - commandHistoryCursor int -} - -func (m *mockModelForHistory) CommandHistory() []string { - return m.commandHistory -} - -func (m *mockModelForHistory) SetCommandHistory(history []string) { - m.commandHistory = history -} - -func (m *mockModelForHistory) CommandHistoryCursor() int { - return m.commandHistoryCursor -} - -func (m *mockModelForHistory) SetCommandHistoryCursor(cur int) { - m.commandHistoryCursor = cur -} - // mockRegistry for testing command execution without actual command handlers type mockRegistry struct{} @@ -41,14 +18,11 @@ func (r *mockRegistry) Execute(m Model, cmdLine string) (tea.Cmd, error) { // TestCommandExecuteUpdatesHistory tests that executing commands adds them to history func TestCommandExecuteUpdatesHistory(t *testing.T) { t.Run("first command added to empty history", func(t *testing.T) { - m := &mockModelForHistory{ - mockModel: mockModel{ - mode: core.CommandMode, - command: "w test.txt", - }, - commandHistory: []string{}, - commandHistoryCursor: 0, - } + m := NewMockModel() + m.ModeVal = core.CommandMode + m.CommandVal = "w test.txt" + m.CommandHistoryList = []string{} + m.CommandHistoryCur = 0 registry := &mockRegistry{} action := CommandExecute{Registry: registry} @@ -65,14 +39,11 @@ func TestCommandExecuteUpdatesHistory(t *testing.T) { }) t.Run("multiple commands prepended to history", func(t *testing.T) { - m := &mockModelForHistory{ - mockModel: mockModel{ - mode: core.CommandMode, - command: "w file1.txt", - }, - commandHistory: []string{}, - commandHistoryCursor: 0, - } + m := NewMockModel() + m.ModeVal = core.CommandMode + m.CommandVal = "w file1.txt" + m.CommandHistoryList = []string{} + m.CommandHistoryCur = 0 registry := &mockRegistry{} action := CommandExecute{Registry: registry} @@ -81,11 +52,11 @@ func TestCommandExecuteUpdatesHistory(t *testing.T) { action.Execute(m) // Execute second command - m.command = "q" + m.CommandVal = "q" action.Execute(m) // Execute third command - m.command = "set number" + m.CommandVal = "set number" action.Execute(m) history := m.CommandHistory() @@ -103,14 +74,11 @@ func TestCommandExecuteUpdatesHistory(t *testing.T) { }) t.Run("empty command not added to history", func(t *testing.T) { - m := &mockModelForHistory{ - mockModel: mockModel{ - mode: core.CommandMode, - command: "", - }, - commandHistory: []string{"previous command"}, - commandHistoryCursor: 0, - } + m := NewMockModel() + m.ModeVal = core.CommandMode + m.CommandVal = "" + m.CommandHistoryList = []string{"previous command"} + m.CommandHistoryCur = 0 registry := &mockRegistry{} action := CommandExecute{Registry: registry} @@ -127,14 +95,11 @@ func TestCommandExecuteUpdatesHistory(t *testing.T) { }) t.Run("history cursor resets on execute", func(t *testing.T) { - m := &mockModelForHistory{ - mockModel: mockModel{ - mode: core.CommandMode, - command: "w", - }, - commandHistory: []string{}, - commandHistoryCursor: 5, // Set to non-zero - } + m := NewMockModel() + m.ModeVal = core.CommandMode + m.CommandVal = "w" + m.CommandHistoryList = []string{} + m.CommandHistoryCur = 5 // Set to non-zero registry := &mockRegistry{} action := CommandExecute{Registry: registry} @@ -146,14 +111,11 @@ func TestCommandExecuteUpdatesHistory(t *testing.T) { }) t.Run("duplicate commands are added to history", func(t *testing.T) { - m := &mockModelForHistory{ - mockModel: mockModel{ - mode: core.CommandMode, - command: "w", - }, - commandHistory: []string{"w"}, - commandHistoryCursor: 0, - } + m := NewMockModel() + m.ModeVal = core.CommandMode + m.CommandVal = "w" + m.CommandHistoryList = []string{"w"} + m.CommandHistoryCur = 0 registry := &mockRegistry{} action := CommandExecute{Registry: registry} diff --git a/internal/action/find_test.go b/internal/action/find_test.go index e7adb6f..b863a6f 100644 --- a/internal/action/find_test.go +++ b/internal/action/find_test.go @@ -4,130 +4,8 @@ import ( "testing" "git.gophernest.net/azpect/TextEditor/internal/core" - "git.gophernest.net/azpect/TextEditor/internal/style" ) -// ================================================== -// Mock Model Implementation -// ================================================== - -type mockModel struct { - windows []*core.Window - activeWindow *core.Window - buffers []*core.Buffer - settings core.EditorSettings - mode core.Mode - registers map[rune]core.Register - insertKeys []string - command string - commandCursor int - commandOutput *core.CommandOutput - commandHistory []string - commandHistoryCursor int - lastFind core.LastFindCommand - styles style.Styles -} - -func newMockModel() *mockModel { - buf := core.NewBufferBuilder(). - WithLines([]string{""}). - Build() - - win := core.NewWindowBuilder(). - WithBuffer(&buf). - WithHeight(24). - WithWidth(80). - Build() - - return &mockModel{ - windows: []*core.Window{&win}, - activeWindow: &win, - buffers: []*core.Buffer{&buf}, - settings: core.NewDefaultSettings(), - mode: core.NormalMode, - registers: core.DefaultRegisters(), - } -} - -func newMockModelWithBuffer(buf *core.Buffer) *mockModel { - win := core.NewWindowBuilder(). - WithBuffer(buf). - WithHeight(24). - WithWidth(80). - Build() - - return &mockModel{ - windows: []*core.Window{&win}, - activeWindow: &win, - buffers: []*core.Buffer{buf}, - settings: core.NewDefaultSettings(), - mode: core.NormalMode, - registers: core.DefaultRegisters(), - } -} - -func newMockModelWithWindow(win *core.Window) *mockModel { - return &mockModel{ - windows: []*core.Window{win}, - activeWindow: win, - buffers: []*core.Buffer{win.Buffer}, - settings: core.NewDefaultSettings(), - mode: core.NormalMode, - registers: core.DefaultRegisters(), - } -} - -// Core Data Access -func (m *mockModel) Windows() []*core.Window { return m.windows } -func (m *mockModel) ActiveWindow() *core.Window { return m.activeWindow } -func (m *mockModel) Buffers() []*core.Buffer { return m.buffers } -func (m *mockModel) SetBuffers(bufs []*core.Buffer) { m.buffers = bufs } -func (m *mockModel) ActiveBuffer() *core.Buffer { return m.activeWindow.Buffer } - -// Insert Mode State -func (m *mockModel) InsertKeys() []string { return m.insertKeys } -func (m *mockModel) SetInsertKeys(keys []string) { m.insertKeys = keys } -func (m *mockModel) SetInsertRecording(count int, action Action) {} -func (m *mockModel) ExitInsertMode() {} -func (m *mockModel) SetLastFind(char string, forward, inclusive bool) { - m.lastFind = core.LastFindCommand{Char: char, Forward: forward, Inclusive: inclusive} -} -func (m *mockModel) GetLastFind() *core.LastFindCommand { return &m.lastFind } - -// Command Mode State -func (m *mockModel) Command() string { return m.command } -func (m *mockModel) SetCommand(cmd string) { m.command = cmd } -func (m *mockModel) CommandCursor() int { return m.commandCursor } -func (m *mockModel) SetCommandCursor(cur int) { m.commandCursor = cur } -func (m *mockModel) CommandOutput() *core.CommandOutput { return m.commandOutput } -func (m *mockModel) SetCommandOutput(out *core.CommandOutput) { m.commandOutput = out } -func (m *mockModel) CommandHistory() []string { return m.commandHistory } -func (m *mockModel) SetCommandHistory(history []string) { m.commandHistory = history } -func (m *mockModel) CommandHistoryCursor() int { return m.commandHistoryCursor } -func (m *mockModel) SetCommandHistoryCursor(cur int) { m.commandHistoryCursor = cur } - -// Editor-wide State -func (m *mockModel) Mode() core.Mode { return m.mode } -func (m *mockModel) SetMode(mode core.Mode) { m.mode = mode } -func (m *mockModel) Settings() core.EditorSettings { return m.settings } -func (m *mockModel) SetSettings(s core.EditorSettings) { m.settings = s } -func (m *mockModel) Styles() style.Styles { return m.styles } -func (m *mockModel) SetStyles(s style.Styles) { m.styles = s } - -// Registers -func (m *mockModel) Registers() map[rune]core.Register { return m.registers } -func (m *mockModel) GetRegister(name rune) (core.Register, bool) { - reg, ok := m.registers[name] - return reg, ok -} -func (m *mockModel) SetRegister(name rune, t core.RegisterType, cnt []string) error { - m.registers[name] = core.Register{Type: t, Content: cnt} - return nil -} -func (m *mockModel) UpdateDefaultRegister(t core.RegisterType, cnt []string) { - m.registers['"'] = core.Register{Type: t, Content: cnt} -} - // ================================================== // f (find forward inclusive) Tests // ================================================== @@ -143,7 +21,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). // At 'h' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -170,7 +48,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 4). // At first 'o' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -197,7 +75,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "x", @@ -224,7 +102,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "d", @@ -251,7 +129,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 5). // At space after 'hello' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -278,7 +156,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -305,7 +183,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -332,7 +210,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: " ", @@ -359,7 +237,7 @@ func TestFindCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "b", @@ -392,7 +270,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 10). // At 'd' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -419,7 +297,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 7). // At 'o' in 'world' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -446,7 +324,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "x", @@ -473,7 +351,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "h", @@ -500,7 +378,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 6). // At 'w' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -527,7 +405,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -554,7 +432,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -581,7 +459,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: " ", @@ -608,7 +486,7 @@ func TestFindCharBackward(t *testing.T) { WithCursorPos(0, 9). // At last 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -641,7 +519,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). // At 'h' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -668,7 +546,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "x", @@ -695,7 +573,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). // At 'a' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "b", @@ -723,7 +601,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "d", @@ -750,7 +628,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -777,7 +655,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: " ", @@ -804,7 +682,7 @@ func TestTillCharForward(t *testing.T) { WithCursorPos(0, 5). // At space Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -837,7 +715,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 10). // At 'd' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -864,7 +742,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "x", @@ -891,7 +769,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 1). // At 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -919,7 +797,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "h", @@ -946,7 +824,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -973,7 +851,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: " ", @@ -1000,7 +878,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 6). // At 'w' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "o", @@ -1027,7 +905,7 @@ func TestTillCharBackward(t *testing.T) { WithCursorPos(0, 9). // At last 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -1060,7 +938,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). // At 'h' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1091,7 +969,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1122,7 +1000,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1149,7 +1027,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "w", @@ -1176,7 +1054,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -1204,7 +1082,7 @@ func TestFindCharForwardWithCount(t *testing.T) { WithCursorPos(0, 4). // At first 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -1241,7 +1119,7 @@ func TestFindCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). // At 'd' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1272,7 +1150,7 @@ func TestFindCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1304,7 +1182,7 @@ func TestFindCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1331,7 +1209,7 @@ func TestFindCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). // At last 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "b", @@ -1359,7 +1237,7 @@ func TestFindCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 6). // At middle 'b' Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -1396,7 +1274,7 @@ func TestTillCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1423,7 +1301,7 @@ func TestTillCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1450,7 +1328,7 @@ func TestTillCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1477,7 +1355,7 @@ func TestTillCharForwardWithCount(t *testing.T) { WithCursorPos(0, 0). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "a", @@ -1511,7 +1389,7 @@ func TestTillCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1538,7 +1416,7 @@ func TestTillCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1565,7 +1443,7 @@ func TestTillCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "l", @@ -1592,7 +1470,7 @@ func TestTillCharBackwardWithCount(t *testing.T) { WithCursorPos(0, 10). Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) action := FindChar{ Char: "b", @@ -1731,7 +1609,7 @@ func TestRepeatFind_Semicolon_After_f(t *testing.T) { t.Run("basic: lands on next inclusive match", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) FindChar{Char: "o", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1745,7 +1623,7 @@ func TestRepeatFind_Semicolon_After_f(t *testing.T) { t.Run("no further match: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) FindChar{Char: "o", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1759,7 +1637,7 @@ func TestRepeatFind_Semicolon_After_f(t *testing.T) { t.Run("cursor at end of line: no move", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 10).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) FindChar{Char: "o", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1775,7 +1653,7 @@ func TestRepeatFind_Semicolon_After_f(t *testing.T) { t.Run("count=2 skips first match lands on second", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"aXbXcX"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", true, true) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 2, Repeated: true}.Execute(m) @@ -1789,7 +1667,7 @@ func TestRepeatFind_Semicolon_After_f(t *testing.T) { t.Run("does not overwrite lastFind when Repeated", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) FindChar{Char: "o", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1810,7 +1688,7 @@ func TestRepeatFind_Semicolon_After_F(t *testing.T) { t.Run("basic: lands on previous inclusive match", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, true) FindChar{Char: "o", Forward: false, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1824,7 +1702,7 @@ func TestRepeatFind_Semicolon_After_F(t *testing.T) { t.Run("no earlier match: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, true) FindChar{Char: "o", Forward: false, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1838,7 +1716,7 @@ func TestRepeatFind_Semicolon_After_F(t *testing.T) { t.Run("cursor at start of line: no move", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, true) FindChar{Char: "o", Forward: false, Inclusive: true, Count: 1, Repeated: true}.Execute(m) @@ -1853,7 +1731,7 @@ func TestRepeatFind_Semicolon_After_F(t *testing.T) { t.Run("count=2 backward skips one lands on second", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"XaXbX"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", false, true) FindChar{Char: "X", Forward: false, Inclusive: true, Count: 2, Repeated: true}.Execute(m) @@ -1876,7 +1754,7 @@ func TestRepeatFind_Semicolon_After_t(t *testing.T) { t.Run("basic: skips adjacent target, lands before next", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 3).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) FindChar{Char: "o", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -1891,7 +1769,7 @@ func TestRepeatFind_Semicolon_After_t(t *testing.T) { t.Run("no further match after second repeat: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 6).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) FindChar{Char: "o", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -1907,7 +1785,7 @@ func TestRepeatFind_Semicolon_After_t(t *testing.T) { t.Run("col+2 out of bounds: no move", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"Xo"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) FindChar{Char: "o", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -1924,7 +1802,7 @@ func TestRepeatFind_Semicolon_After_t(t *testing.T) { t.Run("three chained repeats advance correctly", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"aXbXcXd"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", true, false) // First repeat @@ -1952,7 +1830,7 @@ func TestRepeatFind_Semicolon_After_t(t *testing.T) { t.Run("count=2 repeated exclusive forward", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"aXbXcX"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", true, false) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 2, Repeated: true}.Execute(m) @@ -1974,7 +1852,7 @@ func TestRepeatFind_Semicolon_After_T(t *testing.T) { t.Run("basic: skips adjacent target, lands after previous", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, false) FindChar{Char: "o", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -1988,7 +1866,7 @@ func TestRepeatFind_Semicolon_After_T(t *testing.T) { t.Run("no earlier match after second repeat: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 5).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, false) FindChar{Char: "o", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -2003,7 +1881,7 @@ func TestRepeatFind_Semicolon_After_T(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"oX"}).Build() // Cursor at col 1 (as if `TX` landed at x+1=1 where x=0). win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -2021,7 +1899,7 @@ func TestRepeatFind_Semicolon_After_T(t *testing.T) { t.Run("three chained repeats advance correctly backward", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"dXcXbXa"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 6).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -2047,7 +1925,7 @@ func TestRepeatFind_Semicolon_After_T(t *testing.T) { t.Run("count=2 repeated exclusive backward", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"dXcXbXa"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 6).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 2, Repeated: true}.Execute(m) @@ -2090,7 +1968,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { // Simulate with two sequential ; presses win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", true, true) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) @@ -2098,7 +1976,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { // Simulate with a single 2; (Count=2) win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", true, true) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 2, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2113,7 +1991,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", true, true) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) @@ -2121,7 +1999,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { threeSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 1).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", true, true) FindChar{Char: "X", Forward: true, Inclusive: true, Count: 3, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2141,14 +2019,14 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", false, true) FindChar{Char: "X", Forward: false, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: false, Inclusive: true, Count: 1, Repeated: true}.Execute(m1) twoSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", false, true) FindChar{Char: "X", Forward: false, Inclusive: true, Count: 2, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2169,14 +2047,14 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", true, false) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) twoSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", true, false) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 2, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2191,7 +2069,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", true, false) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) @@ -2199,7 +2077,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { threeSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 0).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", true, false) FindChar{Char: "X", Forward: true, Inclusive: false, Count: 3, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2219,14 +2097,14 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) twoSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 2, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2241,7 +2119,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{line}).Build() win1 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m1 := newMockModelWithWindow(&win1) + m1 := NewMockModelWithWindow(&win1) m1.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m1) @@ -2249,7 +2127,7 @@ func TestRepeatFind_CountedRepeats(t *testing.T) { threeSemicolons := m1.ActiveWindow().Cursor.Col win2 := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m2 := newMockModelWithWindow(&win2) + m2 := NewMockModelWithWindow(&win2) m2.SetLastFind("X", false, false) FindChar{Char: "X", Forward: false, Inclusive: false, Count: 3, Repeated: true}.Execute(m2) counted := m2.ActiveWindow().Cursor.Col @@ -2276,7 +2154,7 @@ func TestRepeatFind_Comma_After_f(t *testing.T) { t.Run("no previous match after fo: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) // Simulate: lastFind was set by `fo` m.SetLastFind("o", true, true) @@ -2293,7 +2171,7 @@ func TestRepeatFind_Comma_After_f(t *testing.T) { t.Run("after ;, comma returns to previous match", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) // , reversed → backward inclusive from col 7, start at col 6: finds 'o' at 4 @@ -2315,7 +2193,7 @@ func TestRepeatFind_Comma_After_F(t *testing.T) { t.Run("no further match forward: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, true) // , reversed → forward inclusive @@ -2330,7 +2208,7 @@ func TestRepeatFind_Comma_After_F(t *testing.T) { t.Run("after ;, comma returns forward to next match", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, true) // , reversed → forward inclusive from col 4, start at col 5: finds 'o' at 7 @@ -2353,7 +2231,7 @@ func TestRepeatFind_Comma_After_t(t *testing.T) { t.Run("no previous exclusive match: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 3).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) // , reversed → backward exclusive, repeated @@ -2369,7 +2247,7 @@ func TestRepeatFind_Comma_After_t(t *testing.T) { t.Run("after ;, comma goes backward exclusive", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 6).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) FindChar{Char: "o", Forward: false, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -2391,7 +2269,7 @@ func TestRepeatFind_Comma_After_T(t *testing.T) { t.Run("no further exclusive match forward: cursor stays", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, false) // , reversed → forward exclusive, repeated @@ -2407,7 +2285,7 @@ func TestRepeatFind_Comma_After_T(t *testing.T) { t.Run("after ;, comma goes forward exclusive", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 5).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, false) FindChar{Char: "o", Forward: true, Inclusive: false, Count: 1, Repeated: true}.Execute(m) @@ -2423,10 +2301,10 @@ func TestRepeatFind_Comma_After_T(t *testing.T) { // -------------------------------------------------- func TestRepeatFind_Resolve(t *testing.T) { - makeMock := func(char string, forward, inclusive bool) *mockModel { + makeMock := func(char string, forward, inclusive bool) *MockModel { buf := core.NewBufferBuilder().WithLines([]string{"x"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind(char, forward, inclusive) return m } @@ -2548,7 +2426,7 @@ func TestRepeatFind_Execute(t *testing.T) { t.Run("Execute via ; after f moves cursor correctly", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 4).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) // ; = RepeatFind{Reverse: false} @@ -2562,7 +2440,7 @@ func TestRepeatFind_Execute(t *testing.T) { t.Run("Execute via , after f reverses and moves cursor correctly", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 7).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, true) // , = RepeatFind{Reverse: true} @@ -2576,7 +2454,7 @@ func TestRepeatFind_Execute(t *testing.T) { t.Run("Execute via ; after t skips adjacent and moves cursor", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 3).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", true, false) RepeatFind{Count: 1, Reverse: false}.Execute(m) @@ -2589,7 +2467,7 @@ func TestRepeatFind_Execute(t *testing.T) { t.Run("Execute via ; after T skips adjacent backward and moves cursor", func(t *testing.T) { buf := core.NewBufferBuilder().WithLines([]string{"hello world"}).Build() win := core.NewWindowBuilder().WithBuffer(&buf).WithCursorPos(0, 8).Build() - m := newMockModelWithWindow(&win) + m := NewMockModelWithWindow(&win) m.SetLastFind("o", false, false) RepeatFind{Count: 1, Reverse: false}.Execute(m) diff --git a/internal/action/mock.go b/internal/action/mock.go new file mode 100644 index 0000000..97a316d --- /dev/null +++ b/internal/action/mock.go @@ -0,0 +1,133 @@ +package action + +import ( + "git.gophernest.net/azpect/TextEditor/internal/core" + "git.gophernest.net/azpect/TextEditor/internal/style" +) + +// MockModel is a shared test implementation of the Model interface. +// Used by test files across multiple packages to avoid duplication. +// All fields are exported to allow direct manipulation in tests. +type MockModel struct { + WindowsList []*core.Window + ActiveWindowVal *core.Window + BuffersList []*core.Buffer + SettingsVal core.EditorSettings + ModeVal core.Mode + RegistersMap map[rune]core.Register + InsertKeysList []string + CommandVal string + CommandCursorVal int + CommandOutputVal *core.CommandOutput + CommandHistoryList []string + CommandHistoryCur int + LastFindVal core.LastFindCommand + StylesVal style.Styles +} + +// NewMockModel creates a mock with an empty buffer and 24x80 window. +func NewMockModel() *MockModel { + buf := core.NewBufferBuilder(). + WithLines([]string{""}). + Build() + + win := core.NewWindowBuilder(). + WithBuffer(&buf). + WithHeight(24). + WithWidth(80). + Build() + + return &MockModel{ + WindowsList: []*core.Window{&win}, + ActiveWindowVal: &win, + BuffersList: []*core.Buffer{&buf}, + SettingsVal: core.NewDefaultSettings(), + ModeVal: core.NormalMode, + RegistersMap: core.DefaultRegisters(), + } +} + +// NewMockModelWithBuffer creates a mock with a custom buffer. +func NewMockModelWithBuffer(buf *core.Buffer) *MockModel { + win := core.NewWindowBuilder(). + WithBuffer(buf). + WithHeight(24). + WithWidth(80). + Build() + + return &MockModel{ + WindowsList: []*core.Window{&win}, + ActiveWindowVal: &win, + BuffersList: []*core.Buffer{buf}, + SettingsVal: core.NewDefaultSettings(), + ModeVal: core.NormalMode, + RegistersMap: core.DefaultRegisters(), + } +} + +// NewMockModelWithWindow creates a mock with a custom window. +func NewMockModelWithWindow(win *core.Window) *MockModel { + return &MockModel{ + WindowsList: []*core.Window{win}, + ActiveWindowVal: win, + BuffersList: []*core.Buffer{win.Buffer}, + SettingsVal: core.NewDefaultSettings(), + ModeVal: core.NormalMode, + RegistersMap: core.DefaultRegisters(), + } +} + +// ================================================== +// Model Interface Implementation +// ================================================== + +// Core Data Access +func (m *MockModel) Windows() []*core.Window { return m.WindowsList } +func (m *MockModel) ActiveWindow() *core.Window { return m.ActiveWindowVal } +func (m *MockModel) Buffers() []*core.Buffer { return m.BuffersList } +func (m *MockModel) SetBuffers(bufs []*core.Buffer) { m.BuffersList = bufs } +func (m *MockModel) ActiveBuffer() *core.Buffer { return m.ActiveWindowVal.Buffer } + +// Insert Mode State +func (m *MockModel) InsertKeys() []string { return m.InsertKeysList } +func (m *MockModel) SetInsertKeys(keys []string) { m.InsertKeysList = keys } +func (m *MockModel) SetInsertRecording(count int, a Action) {} +func (m *MockModel) ExitInsertMode() {} +func (m *MockModel) SetLastFind(char string, forward, inclusive bool) { + m.LastFindVal = core.LastFindCommand{Char: char, Forward: forward, Inclusive: inclusive} +} +func (m *MockModel) GetLastFind() *core.LastFindCommand { return &m.LastFindVal } + +// Command Mode State +func (m *MockModel) Command() string { return m.CommandVal } +func (m *MockModel) SetCommand(cmd string) { m.CommandVal = cmd } +func (m *MockModel) CommandCursor() int { return m.CommandCursorVal } +func (m *MockModel) SetCommandCursor(cur int) { m.CommandCursorVal = cur } +func (m *MockModel) CommandOutput() *core.CommandOutput { return m.CommandOutputVal } +func (m *MockModel) SetCommandOutput(out *core.CommandOutput) { m.CommandOutputVal = out } +func (m *MockModel) CommandHistory() []string { return m.CommandHistoryList } +func (m *MockModel) SetCommandHistory(history []string) { m.CommandHistoryList = history } +func (m *MockModel) CommandHistoryCursor() int { return m.CommandHistoryCur } +func (m *MockModel) SetCommandHistoryCursor(cur int) { m.CommandHistoryCur = cur } + +// Editor-wide State +func (m *MockModel) Mode() core.Mode { return m.ModeVal } +func (m *MockModel) SetMode(mode core.Mode) { m.ModeVal = mode } +func (m *MockModel) Settings() core.EditorSettings { return m.SettingsVal } +func (m *MockModel) SetSettings(s core.EditorSettings) { m.SettingsVal = s } +func (m *MockModel) Styles() style.Styles { return m.StylesVal } +func (m *MockModel) SetStyles(s style.Styles) { m.StylesVal = s } + +// Registers +func (m *MockModel) Registers() map[rune]core.Register { return m.RegistersMap } +func (m *MockModel) GetRegister(name rune) (core.Register, bool) { + reg, ok := m.RegistersMap[name] + return reg, ok +} +func (m *MockModel) SetRegister(name rune, t core.RegisterType, cnt []string) error { + m.RegistersMap[name] = core.Register{Type: t, Content: cnt} + return nil +} +func (m *MockModel) UpdateDefaultRegister(t core.RegisterType, cnt []string) { + m.RegistersMap['"'] = core.Register{Type: t, Content: cnt} +} diff --git a/internal/command/handlers_test.go b/internal/command/handlers_test.go index 89eaa30..019d5e4 100644 --- a/internal/command/handlers_test.go +++ b/internal/command/handlers_test.go @@ -14,116 +14,6 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -// ================================================== -// Mock Model Implementation -// ================================================== - -type mockModel struct { - windows []*core.Window - activeWindow *core.Window - buffers []*core.Buffer - settings core.EditorSettings - mode core.Mode - registers map[rune]core.Register - insertKeys []string - command string - commandCursor int - commandOutput *core.CommandOutput - commandHistory []string - commandHistoryCursor int - lastFind core.LastFindCommand - styles style.Styles -} - -func newMockModel() *mockModel { - buf := core.NewBufferBuilder(). - WithLines([]string{""}). - Build() - - win := core.NewWindowBuilder(). - WithBuffer(&buf). - WithHeight(24). - WithWidth(80). - Build() - - return &mockModel{ - windows: []*core.Window{&win}, - activeWindow: &win, - buffers: []*core.Buffer{&buf}, - settings: core.NewDefaultSettings(), - mode: core.NormalMode, - registers: core.DefaultRegisters(), - } -} - -func newMockModelWithBuffer(buf *core.Buffer) *mockModel { - win := core.NewWindowBuilder(). - WithBuffer(buf). - WithHeight(24). - WithWidth(80). - Build() - - return &mockModel{ - windows: []*core.Window{&win}, - activeWindow: &win, - buffers: []*core.Buffer{buf}, - settings: core.NewDefaultSettings(), - mode: core.NormalMode, - registers: core.DefaultRegisters(), - } -} - -// Core Data Access -func (m *mockModel) Windows() []*core.Window { return m.windows } -func (m *mockModel) ActiveWindow() *core.Window { return m.activeWindow } -func (m *mockModel) Buffers() []*core.Buffer { return m.buffers } -func (m *mockModel) SetBuffers(bufs []*core.Buffer) { m.buffers = bufs } -func (m *mockModel) ActiveBuffer() *core.Buffer { return m.activeWindow.Buffer } - -// Insert Mode State -func (m *mockModel) InsertKeys() []string { return m.insertKeys } -func (m *mockModel) SetInsertKeys(keys []string) { m.insertKeys = keys } -func (m *mockModel) SetInsertRecording(count int, action action.Action) {} -func (m *mockModel) ExitInsertMode() {} -func (m *mockModel) SetLastFind(char string, forward, inclusive bool) { - m.lastFind = core.LastFindCommand{Char: char, Forward: forward, Inclusive: inclusive} -} -func (m *mockModel) GetLastFind() *core.LastFindCommand { return &m.lastFind } - -// Command Mode State -func (m *mockModel) Command() string { return m.command } -func (m *mockModel) SetCommand(cmd string) { m.command = cmd } -func (m *mockModel) CommandCursor() int { return m.commandCursor } -func (m *mockModel) SetCommandCursor(cur int) { m.commandCursor = cur } -func (m *mockModel) CommandOutput() *core.CommandOutput { return m.commandOutput } -func (m *mockModel) SetCommandOutput(out *core.CommandOutput) { m.commandOutput = out } -func (m *mockModel) CommandHistory() []string { return m.commandHistory } -func (m *mockModel) SetCommandHistory(history []string) { m.commandHistory = history } -func (m *mockModel) CommandHistoryCursor() int { return m.commandHistoryCursor } -func (m *mockModel) SetCommandHistoryCursor(cur int) { m.commandHistoryCursor = cur } - -// Editor-wide State -func (m *mockModel) Mode() core.Mode { return m.mode } -func (m *mockModel) SetMode(mode core.Mode) { m.mode = mode } -func (m *mockModel) Settings() core.EditorSettings { return m.settings } -func (m *mockModel) SetSettings(s core.EditorSettings) { m.settings = s } -func (m *mockModel) Styles() style.Styles { return m.styles } -func (m *mockModel) SetStyles(s style.Styles) { m.styles = s } - -// Registers -func (m *mockModel) Registers() map[rune]core.Register { return m.registers } -func (m *mockModel) GetRegister(name rune) (core.Register, bool) { - reg, ok := m.registers[name] - return reg, ok -} -func (m *mockModel) SetRegister(name rune, t core.RegisterType, cnt []string) error { - m.registers[name] = core.Register{Type: t, Content: cnt} - return nil -} -func (m *mockModel) UpdateDefaultRegister(t core.RegisterType, cnt []string) { - m.registers['"'] = core.Register{Type: t, Content: cnt} -} - // ================================================== // cmdWrite Tests // ================================================== @@ -139,12 +29,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"line 1", "line 2", "line 3"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, err := os.ReadFile(filename) @@ -169,12 +59,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{newFile}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify new file was created @@ -209,12 +99,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"short"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, _ := os.ReadFile(filename) @@ -235,16 +125,16 @@ func TestCmdWrite(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for readonly buffer") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "readonly") { - t.Errorf("error should mention readonly: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "readonly") { + t.Errorf("error should mention readonly: %v", m.CommandOutputVal.Lines) } // Verify file was NOT created @@ -263,16 +153,16 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for scratch buffer") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "ScratchBuffer") { - t.Errorf("error should mention ScratchBuffer: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "ScratchBuffer") { + t.Errorf("error should mention ScratchBuffer: %v", m.CommandOutputVal.Lines) } }) @@ -283,16 +173,16 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when no filename available") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "no file name") { - t.Errorf("error should mention no file name: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "no file name") { + t.Errorf("error should mention no file name: %v", m.CommandOutputVal.Lines) } }) @@ -303,11 +193,11 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for invalid path") } }) @@ -322,12 +212,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, err := os.ReadFile(filename) @@ -351,12 +241,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"line 1", "", "line 3", ""}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, _ := os.ReadFile(filename) @@ -380,12 +270,12 @@ func TestCmdWrite(t *testing.T) { }). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, _ := os.ReadFile(filename) @@ -410,12 +300,12 @@ func TestCmdWrite(t *testing.T) { }). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, _ := os.ReadFile(filename) @@ -440,20 +330,20 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"line 1", "line 2"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || len(m.commandOutput.Lines) == 0 { + if m.CommandOutputVal == nil || len(m.CommandOutputVal.Lines) == 0 { t.Error("expected output message") } // Should contain filename and line count - if !strings.Contains(m.commandOutput.Lines[0], filename) { - t.Errorf("output should contain filename: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], filename) { + t.Errorf("output should contain filename: %q", m.CommandOutputVal.Lines[0]) } - if !strings.Contains(m.commandOutput.Lines[0], "2L") { - t.Errorf("output should contain line count: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "2L") { + t.Errorf("output should contain line count: %q", m.CommandOutputVal.Lines[0]) } }) @@ -473,12 +363,12 @@ func TestCmdWrite(t *testing.T) { WithLines(lines). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } info, err := os.Stat(filename) @@ -503,12 +393,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if _, err := os.Stat(filename); os.IsNotExist(err) { @@ -527,12 +417,12 @@ func TestCmdWrite(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{filename}, false) // Current implementation doesn't create parent dirs, so expect error - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when parent directories don't exist") } }) @@ -548,7 +438,7 @@ func TestCmdWrite(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) if !m.ActiveBuffer().Modified { t.Fatal("precondition: buffer should be modified before write") @@ -556,8 +446,8 @@ func TestCmdWrite(t *testing.T) { cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if m.ActiveBuffer().Modified { @@ -577,12 +467,12 @@ func TestCmdWrite(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{newFile}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Modified flag is cleared even when writing to a different file @@ -605,11 +495,11 @@ func TestCmdWrite(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Fatal("expected error for invalid path") } @@ -626,16 +516,16 @@ func TestCmdWrite(t *testing.T) { func TestCmdEdit(t *testing.T) { t.Run("errors when no argument provided", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when no argument") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "requires an argument") { - t.Errorf("error should mention requires argument: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "requires an argument") { + t.Errorf("error should mention requires argument: %v", m.CommandOutputVal.Lines) } }) @@ -643,34 +533,34 @@ func TestCmdEdit(t *testing.T) { tmpDir := t.TempDir() filename := filepath.Join(tmpDir, "newfile.txt") - m := newMockModel() - initialBufferCount := len(m.buffers) + m := action.NewMockModel() + initialBufferCount := len(m.BuffersList) cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Should have added a new buffer - if len(m.buffers) != initialBufferCount+1 { - t.Errorf("expected %d buffers, got %d", initialBufferCount+1, len(m.buffers)) + if len(m.BuffersList) != initialBufferCount+1 { + t.Errorf("expected %d buffers, got %d", initialBufferCount+1, len(m.BuffersList)) } // Active window should point to new buffer - if m.activeWindow.Buffer.Filename != filename { + if m.ActiveWindowVal.Buffer.Filename != filename { t.Errorf("active buffer filename = %q, want %q", - m.activeWindow.Buffer.Filename, filename) + m.ActiveWindowVal.Buffer.Filename, filename) } // New buffer should be empty - if m.activeWindow.Buffer.LineCount() != 1 || m.activeWindow.Buffer.Line(0) != "" { + if m.ActiveWindowVal.Buffer.LineCount() != 1 || m.ActiveWindowVal.Buffer.Line(0) != "" { t.Errorf("new buffer should have one empty line") } // Buffer should be FileBuffer type - if m.activeWindow.Buffer.Type != core.FileBuffer { - t.Errorf("buffer type = %v, want FileBuffer", m.activeWindow.Buffer.Type) + if m.ActiveWindowVal.Buffer.Type != core.FileBuffer { + t.Errorf("buffer type = %v, want FileBuffer", m.ActiveWindowVal.Buffer.Type) } }) @@ -682,15 +572,15 @@ func TestCmdEdit(t *testing.T) { content := "line 1\nline 2\nline 3\n" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 3 { t.Errorf("expected 3 lines, got %d", buf.LineCount()) } @@ -714,15 +604,15 @@ func TestCmdEdit(t *testing.T) { content := "line 1\nline 2" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 2 { t.Errorf("expected 2 lines, got %d", buf.LineCount()) } @@ -734,15 +624,15 @@ func TestCmdEdit(t *testing.T) { os.WriteFile(filename, []byte(""), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer // Empty file should have 0 lines (scanner produces no lines) if buf.LineCount() != 0 { t.Errorf("expected 0 lines for empty file, got %d", buf.LineCount()) @@ -769,15 +659,15 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, tt.filename) os.WriteFile(filename, []byte("content"), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - if m.activeWindow.Buffer.Filetype != tt.expected { - t.Errorf("filetype = %q, want %q", m.activeWindow.Buffer.Filetype, tt.expected) + if m.ActiveWindowVal.Buffer.Filetype != tt.expected { + t.Errorf("filetype = %q, want %q", m.ActiveWindowVal.Buffer.Filetype, tt.expected) } }) } @@ -791,16 +681,16 @@ func TestCmdEdit(t *testing.T) { content := "\tindented\n\t\tdouble" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() - m.settings.TabStop = 4 + m := action.NewMockModel() + m.SettingsVal.TabStop = 4 cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer // Tab should be converted to 4 spaces expected0 := " indented" @@ -832,14 +722,14 @@ func TestCmdEdit(t *testing.T) { for _, tt := range tests { t.Run(string(rune('0'+tt.tabstop)), func(t *testing.T) { - m := newMockModel() - m.settings.TabStop = tt.tabstop + m := action.NewMockModel() + m.SettingsVal.TabStop = tt.tabstop cmdEdit(m, []string{filename}, false) - if m.activeWindow.Buffer.Line(0) != tt.expected { + if m.ActiveWindowVal.Buffer.Line(0) != tt.expected { t.Errorf("with tabstop=%d: got %q, want %q", - tt.tabstop, m.activeWindow.Buffer.Line(0), tt.expected) + tt.tabstop, m.ActiveWindowVal.Buffer.Line(0), tt.expected) } }) } @@ -852,15 +742,15 @@ func TestCmdEdit(t *testing.T) { content := "Hello \u4e16\u754c\n\u3053\u3093\u306b\u3061\u306f\nEmoji: \U0001F600\n" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 3 { t.Errorf("expected 3 lines, got %d", buf.LineCount()) } @@ -882,15 +772,15 @@ func TestCmdEdit(t *testing.T) { } os.WriteFile(filename, []byte(content.String()), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 10000 { t.Errorf("expected 10000 lines, got %d", buf.LineCount()) } @@ -901,11 +791,11 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "test.txt") os.WriteFile(filename, []byte("content"), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if !buf.Loaded { t.Error("buffer should be marked as loaded") } @@ -918,11 +808,11 @@ func TestCmdEdit(t *testing.T) { tmpDir := t.TempDir() filename := filepath.Join(tmpDir, "newfile.txt") - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if !buf.Loaded { t.Error("new buffer should be marked as loaded") } @@ -944,11 +834,11 @@ func TestCmdEdit(t *testing.T) { os.Chmod(filename, 0000) defer os.Chmod(filename, 0644) // Cleanup - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for permission denied") } }) @@ -962,15 +852,15 @@ func TestCmdEdit(t *testing.T) { content := longLine + "\nshort\n" + longLine os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if len(buf.Line(0)) != 50000 { t.Errorf("long line not preserved: got %d chars", len(buf.Line(0))) } @@ -991,13 +881,13 @@ func TestCmdEdit(t *testing.T) { veryLongLine := strings.Repeat("x", 100000) os.WriteFile(filename, []byte(veryLongLine+"\n"), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) // Currently this will result in 0 lines loaded due to scanner limitation // This test documents the current behavior - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() > 0 && len(buf.Line(0)) == 100000 { t.Log("Scanner handled very long line - limitation may be fixed") } else { @@ -1013,15 +903,15 @@ func TestCmdEdit(t *testing.T) { content := "line 1\r\nline 2\r\nline 3\r\n" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 3 { t.Errorf("expected 3 lines, got %d", buf.LineCount()) } @@ -1054,15 +944,15 @@ func TestCmdEdit(t *testing.T) { content := "unix line\nwindows line\r\nunix again\n" os.WriteFile(filename, []byte(content), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - buf := m.activeWindow.Buffer + buf := m.ActiveWindowVal.Buffer if buf.LineCount() != 3 { t.Errorf("expected 3 lines, got %d", buf.LineCount()) } @@ -1079,20 +969,20 @@ func TestCmdEdit(t *testing.T) { tmpDir := t.TempDir() filename := filepath.Join(tmpDir, "does_not_exist.txt") - m := newMockModel() + m := action.NewMockModel() // This should NOT panic (tests the nil pointer fix) cmdEdit(m, []string{filename}, false) // Should succeed - creates new buffer - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Buffer should be created with the filename - if m.activeWindow.Buffer.Filename != filename { + if m.ActiveWindowVal.Buffer.Filename != filename { t.Errorf("buffer filename = %q, want %q", - m.activeWindow.Buffer.Filename, filename) + m.ActiveWindowVal.Buffer.Filename, filename) } }) @@ -1101,18 +991,18 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "test.txt") os.WriteFile(filename, []byte("content"), 0644) - m := newMockModel() - initialCount := len(m.buffers) + m := action.NewMockModel() + initialCount := len(m.BuffersList) cmdEdit(m, []string{filename}, false) - if len(m.buffers) != initialCount+1 { - t.Errorf("buffer not added: expected %d, got %d", initialCount+1, len(m.buffers)) + if len(m.BuffersList) != initialCount+1 { + t.Errorf("buffer not added: expected %d, got %d", initialCount+1, len(m.BuffersList)) } // Find the new buffer in the list found := false - for _, buf := range m.buffers { + for _, buf := range m.BuffersList { if buf.Filename == filename { found = true break @@ -1128,16 +1018,16 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "file with spaces.txt") os.WriteFile(filename, []byte("content"), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - if m.activeWindow.Buffer.Filename != filename { - t.Errorf("filename = %q, want %q", m.activeWindow.Buffer.Filename, filename) + if m.ActiveWindowVal.Buffer.Filename != filename { + t.Errorf("filename = %q, want %q", m.ActiveWindowVal.Buffer.Filename, filename) } }) @@ -1146,21 +1036,21 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "existing.txt") os.WriteFile(filename, []byte("original content"), 0644) - m := newMockModel() - initialBufferCount := len(m.buffers) + m := action.NewMockModel() + initialBufferCount := len(m.BuffersList) // First edit - loads the file cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error on first edit: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error on first edit: %v", m.CommandOutputVal.Lines) } - if len(m.buffers) != initialBufferCount+1 { - t.Errorf("expected %d buffers after first edit, got %d", initialBufferCount+1, len(m.buffers)) + if len(m.BuffersList) != initialBufferCount+1 { + t.Errorf("expected %d buffers after first edit, got %d", initialBufferCount+1, len(m.BuffersList)) } - firstBuffer := m.activeWindow.Buffer + firstBuffer := m.ActiveWindowVal.Buffer if firstBuffer.Filename != filename { t.Fatalf("first buffer filename = %q, want %q", firstBuffer.Filename, filename) } @@ -1172,26 +1062,26 @@ func TestCmdEdit(t *testing.T) { // Second edit - should switch to existing buffer, not create new one cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error on second edit: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error on second edit: %v", m.CommandOutputVal.Lines) } // Should not have created a new buffer - if len(m.buffers) != initialBufferCount+1 { + if len(m.BuffersList) != initialBufferCount+1 { t.Errorf("expected buffer count to remain %d, got %d (created duplicate buffer)", - initialBufferCount+1, len(m.buffers)) + initialBufferCount+1, len(m.BuffersList)) } // Should be the same buffer instance - if m.activeWindow.Buffer.Id != bufferId { + if m.ActiveWindowVal.Buffer.Id != bufferId { t.Errorf("expected to switch to existing buffer (ID %d), got different buffer (ID %d)", - bufferId, m.activeWindow.Buffer.Id) + bufferId, m.ActiveWindowVal.Buffer.Id) } // Should have our modifications, not reload from disk - if m.activeWindow.Buffer.Line(0) != "modified content" { + if m.ActiveWindowVal.Buffer.Line(0) != "modified content" { t.Errorf("expected modified buffer content %q, got %q (buffer was reloaded from disk)", - "modified content", m.activeWindow.Buffer.Line(0)) + "modified content", m.ActiveWindowVal.Buffer.Line(0)) } }) @@ -1200,17 +1090,17 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "file.txt") os.WriteFile(filename, []byte("version 1"), 0644) - m := newMockModel() + m := action.NewMockModel() // First edit cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } - bufferId := m.activeWindow.Buffer.Id - originalLine := m.activeWindow.Buffer.Line(0) + bufferId := m.ActiveWindowVal.Buffer.Id + originalLine := m.ActiveWindowVal.Buffer.Line(0) // Modify file on disk os.WriteFile(filename, []byte("version 2 - changed on disk"), 0644) @@ -1219,14 +1109,14 @@ func TestCmdEdit(t *testing.T) { cmdEdit(m, []string{filename}, false) // Should still be the same buffer - if m.activeWindow.Buffer.Id != bufferId { - t.Errorf("expected same buffer ID %d, got %d", bufferId, m.activeWindow.Buffer.Id) + if m.ActiveWindowVal.Buffer.Id != bufferId { + t.Errorf("expected same buffer ID %d, got %d", bufferId, m.ActiveWindowVal.Buffer.Id) } // Should have old content, not reload - if m.activeWindow.Buffer.Line(0) != originalLine { + if m.ActiveWindowVal.Buffer.Line(0) != originalLine { t.Errorf("buffer was reloaded from disk, expected %q, got %q", - originalLine, m.activeWindow.Buffer.Line(0)) + originalLine, m.ActiveWindowVal.Buffer.Line(0)) } // Note: Real vim would warn about file change, but for now we just switch to buffer @@ -1240,20 +1130,20 @@ func TestCmdEdit(t *testing.T) { os.WriteFile(file1, []byte("file 1"), 0644) os.WriteFile(file2, []byte("file 2"), 0644) - m := newMockModel() + m := action.NewMockModel() cmdEdit(m, []string{file1}, false) - bufferCount := len(m.buffers) + bufferCount := len(m.BuffersList) cmdEdit(m, []string{file2}, false) // Should have created a new buffer for different file - if len(m.buffers) != bufferCount+1 { - t.Errorf("expected new buffer for different file, buffer count = %d", len(m.buffers)) + if len(m.BuffersList) != bufferCount+1 { + t.Errorf("expected new buffer for different file, buffer count = %d", len(m.BuffersList)) } - if m.activeWindow.Buffer.Filename != file2 { - t.Errorf("active buffer filename = %q, want %q", m.activeWindow.Buffer.Filename, file2) + if m.ActiveWindowVal.Buffer.Filename != file2 { + t.Errorf("active buffer filename = %q, want %q", m.ActiveWindowVal.Buffer.Filename, file2) } }) @@ -1262,22 +1152,22 @@ func TestCmdEdit(t *testing.T) { filename := filepath.Join(tmpDir, "file.txt") os.WriteFile(filename, []byte("content"), 0644) - m := newMockModel() + m := action.NewMockModel() // First edit with absolute path cmdEdit(m, []string{filename}, false) - bufferId := m.activeWindow.Buffer.Id - bufferCount := len(m.buffers) + bufferId := m.ActiveWindowVal.Buffer.Id + bufferCount := len(m.BuffersList) // Second edit with same absolute path - should match cmdEdit(m, []string{filename}, false) - if len(m.buffers) != bufferCount { + if len(m.BuffersList) != bufferCount { t.Error("created duplicate buffer for same absolute path") } - if m.activeWindow.Buffer.Id != bufferId { + if m.ActiveWindowVal.Buffer.Id != bufferId { t.Error("did not switch to existing buffer") } }) @@ -1295,18 +1185,18 @@ func TestEditWriteRoundTrip(t *testing.T) { original := "line 1\nline 2\nline 3\n" os.WriteFile(filename, []byte(original), 0644) - m := newMockModel() + m := action.NewMockModel() // Edit cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("edit error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("edit error: %v", m.CommandOutputVal.Lines) } // Write cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("write error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("write error: %v", m.CommandOutputVal.Lines) } // Read back @@ -1320,21 +1210,21 @@ func TestEditWriteRoundTrip(t *testing.T) { tmpDir := t.TempDir() filename := filepath.Join(tmpDir, "newfile.txt") - m := newMockModel() + m := action.NewMockModel() // Edit (creates new buffer) cmdEdit(m, []string{filename}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("edit error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("edit error: %v", m.CommandOutputVal.Lines) } // Add content to buffer - m.activeWindow.Buffer.InsertLine(0, "hello world") + m.ActiveWindowVal.Buffer.InsertLine(0, "hello world") // Write cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("write error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("write error: %v", m.CommandOutputVal.Lines) } // Verify file exists @@ -1356,21 +1246,21 @@ func TestEditWriteRoundTrip(t *testing.T) { os.WriteFile(original, []byte("content\n"), 0644) - m := newMockModel() + m := action.NewMockModel() // Edit original cmdEdit(m, []string{original}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("edit error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("edit error: %v", m.CommandOutputVal.Lines) } // Modify - m.activeWindow.Buffer.SetLine(0, "modified content") + m.ActiveWindowVal.Buffer.SetLine(0, "modified content") // Write to new file cmdWrite(m, []string{newFile}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("write error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("write error: %v", m.CommandOutputVal.Lines) } // Verify new file has modified content @@ -1428,12 +1318,12 @@ func TestCmdQuit(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1454,11 +1344,11 @@ func TestCmdQuit(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for modified buffer") } @@ -1474,16 +1364,16 @@ func TestCmdQuit(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Fatal("expected error") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "important_file.txt") { - t.Errorf("error should mention filename: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "important_file.txt") { + t.Errorf("error should mention filename: %v", m.CommandOutputVal.Lines) } }) @@ -1502,12 +1392,12 @@ func TestCmdQuit(t *testing.T) { Build() modifiedBuf.Modified = true - m := newMockModelWithBuffer(&activeBuf) - m.buffers = append(m.buffers, &modifiedBuf) + m := action.NewMockModelWithBuffer(&activeBuf) + m.BuffersList = append(m.BuffersList, &modifiedBuf) cmd := cmdQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when any buffer is modified") } @@ -1529,15 +1419,15 @@ func TestCmdQuit(t *testing.T) { Build() modifiedBuf.Modified = true - m := newMockModelWithBuffer(&activeBuf) - m.buffers = append(m.buffers, &modifiedBuf) + m := action.NewMockModelWithBuffer(&activeBuf) + m.BuffersList = append(m.BuffersList, &modifiedBuf) cmdQuit(m, []string{}, false) // Should switch active window to show the modified buffer - if m.activeWindow.Buffer.Filename != "modified.txt" { + if m.ActiveWindowVal.Buffer.Filename != "modified.txt" { t.Errorf("should switch to modified buffer, got %q", - m.activeWindow.Buffer.Filename) + m.ActiveWindowVal.Buffer.Filename) } }) @@ -1548,17 +1438,17 @@ func TestCmdQuit(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for modified buffer without filename") } // Error message should still be meaningful - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "unsaved") { - t.Logf("Note: error message for unnamed buffer: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "unsaved") { + t.Logf("Note: error message for unnamed buffer: %v", m.CommandOutputVal.Lines) } }) @@ -1581,13 +1471,13 @@ func TestCmdQuit(t *testing.T) { Build() buf3.Modified = false - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2, &buf3) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2, &buf3) cmd := cmdQuit(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1607,12 +1497,12 @@ func TestCmdQuitAll(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuitAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1638,12 +1528,12 @@ func TestCmdQuitAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when any buffer is modified") } @@ -1663,13 +1553,13 @@ func TestCmdQuitAll(t *testing.T) { Build() buf2.Modified = false - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1684,16 +1574,16 @@ func TestCmdQuitAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdQuitAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Fatal("expected error") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "important_document.txt") { - t.Errorf("error should mention filename: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "important_document.txt") { + t.Errorf("error should mention filename: %v", m.CommandOutputVal.Lines) } }) @@ -1708,18 +1598,18 @@ func TestCmdQuitAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdQuitAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Fatal("expected error") } // Should report first modified buffer - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "first_modified.txt") { - t.Errorf("should report first modified buffer: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "first_modified.txt") { + t.Errorf("should report first modified buffer: %v", m.CommandOutputVal.Lines) } }) } @@ -1736,13 +1626,13 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, true) // Should NOT error - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Should return quit command @@ -1764,13 +1654,13 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, true) // Force quit should work even with readonly modified buffer - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1802,14 +1692,14 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2, &buf3) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2, &buf3) cmd := cmdQuit(m, []string{}, true) // Should quit regardless of multiple modified buffers - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1828,13 +1718,13 @@ func TestCmdQuitForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, false) // Should work with unmodified buffers too - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1854,13 +1744,13 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, true) // Force quit works even without filename - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1881,13 +1771,13 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, true) // Force quit works with scratch buffers - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1919,14 +1809,14 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&modifiedBuf) - m.buffers = append(m.buffers, &unmodifiedBuf, &readonlyModifiedBuf) + m := action.NewMockModelWithBuffer(&modifiedBuf) + m.BuffersList = append(m.BuffersList, &unmodifiedBuf, &readonlyModifiedBuf) cmd := cmdQuit(m, []string{}, true) // Should quit regardless of buffer states - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -1951,17 +1841,17 @@ func TestCmdQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&activeBuf) - m.buffers = append(m.buffers, &modifiedBuf) + m := action.NewMockModelWithBuffer(&activeBuf) + m.BuffersList = append(m.BuffersList, &modifiedBuf) // Remember active buffer - activeFilename := m.activeWindow.Buffer.Filename + activeFilename := m.ActiveWindowVal.Buffer.Filename cmdQuit(m, []string{}, true) // Should NOT switch to modified buffer (unlike regular quit) - if m.activeWindow.Buffer.Filename != activeFilename { - t.Errorf("should not switch buffers, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != activeFilename { + t.Errorf("should not switch buffers, got %q", m.ActiveWindowVal.Buffer.Filename) } }) } @@ -1984,14 +1874,14 @@ func TestCmdQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) // Should quit even with all buffers modified - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2016,13 +1906,13 @@ func TestCmdQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2049,14 +1939,14 @@ func TestCmdQuitAllForce(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) // Force quit should work with readonly buffers - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2083,14 +1973,14 @@ func TestCmdQuitAllForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) // Should quit with scratch buffers - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2116,14 +2006,14 @@ func TestCmdQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) // Force quit works even without filenames - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2137,15 +2027,15 @@ func TestCmdQuitAllForce(t *testing.T) { }) t.Run("quits with no buffers", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() // Clear buffers - m.buffers = []*core.Buffer{} + m.BuffersList = []*core.Buffer{} cmd := cmdQuitAll(m, []string{}, true) // Should quit even with no buffers - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2195,14 +2085,14 @@ func TestCmdQuitAllForce(t *testing.T) { WithLines([]string{"saved content"}). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2, &buf3, &buf4, &buf5) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2, &buf3, &buf4, &buf5) cmd := cmdQuitAll(m, []string{}, true) // Force quit should work regardless of any buffer state - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2226,14 +2116,14 @@ func TestCmdQuitAllForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdQuitAll(m, []string{}, true) // Should work with unmodified buffers too - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2271,13 +2161,13 @@ func TestCmdWriteAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdWriteAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify both files were written @@ -2315,8 +2205,8 @@ func TestCmdWriteAll(t *testing.T) { Build() unmodifiedBuf.Modified = false - m := newMockModelWithBuffer(&modifiedBuf) - m.buffers = append(m.buffers, &unmodifiedBuf) + m := action.NewMockModelWithBuffer(&modifiedBuf) + m.BuffersList = append(m.BuffersList, &unmodifiedBuf) cmdWriteAll(m, []string{}, false) @@ -2342,12 +2232,12 @@ func TestCmdWriteAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if buf.Modified { @@ -2364,16 +2254,16 @@ func TestCmdWriteAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Fatal("expected error for modified readonly buffer") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "readonly") { - t.Errorf("error should mention readonly: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "readonly") { + t.Errorf("error should mention readonly: %v", m.CommandOutputVal.Lines) } }) @@ -2397,14 +2287,14 @@ func TestCmdWriteAll(t *testing.T) { Build() // NOT modified! - m := newMockModelWithBuffer(&writableBuf) - m.buffers = append(m.buffers, &readonlyBuf) + m := action.NewMockModelWithBuffer(&writableBuf) + m.BuffersList = append(m.BuffersList, &readonlyBuf) cmdWriteAll(m, []string{}, false) // Should succeed - readonly buffer not modified, so skip it - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("should not error for unmodified readonly buffer: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("should not error for unmodified readonly buffer: %v", m.CommandOutputVal.Lines) } // Writable file should be written @@ -2422,11 +2312,11 @@ func TestCmdWriteAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for scratch buffer") } }) @@ -2439,17 +2329,17 @@ func TestCmdWriteAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for buffer without filename") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "no file name") || - !strings.Contains(strings.ToLower(strings.Join(m.commandOutput.Lines, " ")), "name") { - t.Logf("error message: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "no file name") || + !strings.Contains(strings.ToLower(strings.Join(m.CommandOutputVal.Lines, " ")), "name") { + t.Logf("error message: %v", m.CommandOutputVal.Lines) } }) @@ -2460,13 +2350,13 @@ func TestCmdWriteAll(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, false) // Should succeed even with nothing to write - if m.commandOutput != nil && m.commandOutput.IsError { - t.Errorf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Errorf("unexpected error: %v", m.CommandOutputVal.Lines) } }) @@ -2489,16 +2379,16 @@ func TestCmdWriteAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdWriteAll(m, []string{}, false) // Should have some output indicating what was written - if m.commandOutput == nil || len(m.commandOutput.Lines) == 0 { + if m.CommandOutputVal == nil || len(m.CommandOutputVal.Lines) == 0 { t.Log("Note: cmdWriteAll doesn't set output message") - } else if !strings.Contains(m.commandOutput.Lines[0], "2") { - t.Logf("Output message: %q", m.commandOutput.Lines[0]) + } else if !strings.Contains(m.CommandOutputVal.Lines[0], "2") { + t.Logf("Output message: %q", m.CommandOutputVal.Lines[0]) } }) @@ -2522,12 +2412,12 @@ func TestCmdWriteAll(t *testing.T) { Build() invalidBuf.Modified = true - m := newMockModelWithBuffer(&invalidBuf) // Invalid first - m.buffers = append(m.buffers, &validBuf) + m := action.NewMockModelWithBuffer(&invalidBuf) // Invalid first + m.BuffersList = append(m.BuffersList, &validBuf) cmdWriteAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error") } @@ -2551,12 +2441,12 @@ func TestCmdWriteQuit(t *testing.T) { WithLines([]string{"content to save"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify file was written @@ -2586,11 +2476,11 @@ func TestCmdWriteQuit(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for readonly buffer") } @@ -2606,11 +2496,11 @@ func TestCmdWriteQuit(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for scratch buffer") } @@ -2626,11 +2516,11 @@ func TestCmdWriteQuit(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for buffer without filename") } @@ -2646,11 +2536,11 @@ func TestCmdWriteQuit(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for invalid path") } @@ -2670,12 +2560,12 @@ func TestCmdWriteQuit(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{newFile}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // New file should exist @@ -2704,7 +2594,7 @@ func TestCmdWriteQuit(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteQuit(m, []string{}, false) @@ -2741,13 +2631,13 @@ func TestCmdWriteQuitAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdWriteQuitAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify files were written @@ -2791,13 +2681,13 @@ func TestCmdWriteQuitAll(t *testing.T) { Build() unmodifiedBuf.Modified = false - m := newMockModelWithBuffer(&modifiedBuf) - m.buffers = append(m.buffers, &unmodifiedBuf) + m := action.NewMockModelWithBuffer(&modifiedBuf) + m.BuffersList = append(m.BuffersList, &unmodifiedBuf) cmd := cmdWriteQuitAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Should still quit even if some buffers unmodified @@ -2826,17 +2716,17 @@ func TestCmdWriteQuitAll(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&validBuf) - m.buffers = append(m.buffers, &readonlyBuf) + m := action.NewMockModelWithBuffer(&validBuf) + m.BuffersList = append(m.BuffersList, &readonlyBuf) cmd := cmdWriteQuitAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for modified readonly buffer") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "readonly") { - t.Errorf("error should mention readonly: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "readonly") { + t.Errorf("error should mention readonly: %v", m.CommandOutputVal.Lines) } if cmd != nil { @@ -2864,13 +2754,13 @@ func TestCmdWriteQuitAll(t *testing.T) { Build() // NOT modified - this is the key - m := newMockModelWithBuffer(&writableBuf) - m.buffers = append(m.buffers, &readonlyBuf) + m := action.NewMockModelWithBuffer(&writableBuf) + m.BuffersList = append(m.BuffersList, &readonlyBuf) cmd := cmdWriteQuitAll(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("should not error for unmodified readonly buffer: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("should not error for unmodified readonly buffer: %v", m.CommandOutputVal.Lines) } // Should write the modified writable buffer @@ -2893,11 +2783,11 @@ func TestCmdWriteQuitAll(t *testing.T) { Build() noNameBuf.Modified = true - m := newMockModelWithBuffer(&noNameBuf) + m := action.NewMockModelWithBuffer(&noNameBuf) cmd := cmdWriteQuitAll(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for buffer without filename") } @@ -2913,13 +2803,13 @@ func TestCmdWriteQuitAll(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuitAll(m, []string{}, false) // Should still quit even if nothing to write - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -2946,8 +2836,8 @@ func TestCmdWriteQuitAll(t *testing.T) { Build() buf2.Modified = true - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdWriteQuitAll(m, []string{}, false) @@ -2976,13 +2866,13 @@ func TestCmdWriteForce(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, true) // Force should bypass readonly check - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify file was written @@ -3010,13 +2900,13 @@ func TestCmdWriteForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{newFile}, true) // Should succeed with force - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify new file was created @@ -3047,13 +2937,13 @@ func TestCmdWriteForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{targetFile}, true) // Force with filename should work for scratch buffer - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify file was written @@ -3081,13 +2971,13 @@ func TestCmdWriteForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{targetFile}, true) // Force should bypass BOTH readonly AND scratch checks - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error with force: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error with force: %v", m.CommandOutputVal.Lines) } // Verify file was written @@ -3114,17 +3004,17 @@ func TestCmdWriteForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, true) // Force doesn't help if there's no filename to write to - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when no filename provided") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "no file name") { - t.Errorf("error should mention no file name: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "no file name") { + t.Errorf("error should mention no file name: %v", m.CommandOutputVal.Lines) } }) @@ -3136,12 +3026,12 @@ func TestCmdWriteForce(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, true) // Force bypasses buffer checks but not OS-level checks - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for invalid path even with force") } }) @@ -3157,17 +3047,17 @@ func TestCmdWriteForce(t *testing.T) { ReadOnly(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) // force=false should still prevent write cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for readonly without force flag") } - if !strings.Contains(strings.Join(m.commandOutput.Lines, " "), "readonly") { - t.Errorf("error should mention readonly: %v", m.commandOutput.Lines) + if !strings.Contains(strings.Join(m.CommandOutputVal.Lines, " "), "readonly") { + t.Errorf("error should mention readonly: %v", m.CommandOutputVal.Lines) } }) @@ -3183,7 +3073,7 @@ func TestCmdWriteForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) if !buf.Modified { t.Fatal("precondition: buffer should be modified") @@ -3191,8 +3081,8 @@ func TestCmdWriteForce(t *testing.T) { cmdWrite(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Modified flag should be cleared @@ -3211,7 +3101,7 @@ func TestCmdWriteForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{targetFile}, true) @@ -3236,12 +3126,12 @@ func TestCmdWriteForce(t *testing.T) { WithLines([]string{}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{filename}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Should create empty file @@ -3282,14 +3172,14 @@ func TestCmdWriteAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdWriteAll(m, []string{}, true) // Should succeed with force - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Both files should be written @@ -3316,13 +3206,13 @@ func TestCmdWriteAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, true) // Force can bypass scratch type check, but if buffer has no filename // it should still error with "no file name provided" - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for scratch buffer without filename") } }) @@ -3353,13 +3243,13 @@ func TestCmdWriteAllForce(t *testing.T) { WithLines([]string{"unchanged"}). Build() - m := newMockModelWithBuffer(&readonlyBuf) - m.buffers = append(m.buffers, &normalBuf, &unmodifiedBuf) + m := action.NewMockModelWithBuffer(&readonlyBuf) + m.BuffersList = append(m.BuffersList, &normalBuf, &unmodifiedBuf) cmdWriteAll(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Both modified files should be written @@ -3389,12 +3279,12 @@ func TestCmdWriteAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWriteAll(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } if buf.Modified { @@ -3420,12 +3310,12 @@ func TestCmdWriteQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // File should be written @@ -3458,12 +3348,12 @@ func TestCmdWriteQuitForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{filename}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // File should be written @@ -3486,12 +3376,12 @@ func TestCmdWriteQuitForce(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdWriteQuit(m, []string{}, true) // Can't write without a filename even with force - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error when no filename") } @@ -3527,13 +3417,13 @@ func TestCmdWriteQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdWriteQuitAll(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Both files should be written @@ -3584,13 +3474,13 @@ func TestCmdWriteQuitAllForce(t *testing.T) { WithLines([]string{"unchanged"}). Build() - m := newMockModelWithBuffer(&readonlyBuf) - m.buffers = append(m.buffers, &normalBuf, &unmodifiedBuf) + m := action.NewMockModelWithBuffer(&readonlyBuf) + m.BuffersList = append(m.BuffersList, &normalBuf, &unmodifiedBuf) cmd := cmdWriteQuitAll(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Modified buffers should be written @@ -3624,13 +3514,13 @@ func TestCmdWriteQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&validBuf) - m.buffers = append(m.buffers, &noNameBuf) + m := action.NewMockModelWithBuffer(&validBuf) + m.BuffersList = append(m.BuffersList, &noNameBuf) cmd := cmdWriteQuitAll(m, []string{}, true) // Force can't help when there's no filename - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for buffer without filename") } @@ -3659,8 +3549,8 @@ func TestCmdWriteQuitAllForce(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdWriteQuitAll(m, []string{}, true) @@ -3700,12 +3590,12 @@ func TestEdgeCases(t *testing.T) { os.Chmod(filename, 0444) defer os.Chmod(filename, 0644) // Cleanup - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) // Regular write should fail (OS permission denied) cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error for OS-level readonly file") } }) @@ -3722,13 +3612,13 @@ func TestEdgeCases(t *testing.T) { Build() buf.Modified = false - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, true) // Force write should work even for unmodified readonly - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } content, _ := os.ReadFile(filename) @@ -3749,19 +3639,19 @@ func TestEdgeCases(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) // Without force - should error cmdWrite(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error without force") } // With force - should succeed - m.commandOutput = nil + m.CommandOutputVal = nil cmdWrite(m, []string{}, true) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Errorf("force write failed: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Errorf("force write failed: %v", m.CommandOutputVal.Lines) } // Modified flag should be cleared @@ -3782,12 +3672,12 @@ func TestEdgeCases(t *testing.T) { WithLines([]string{"content"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify file exists @@ -3806,12 +3696,12 @@ func TestEdgeCases(t *testing.T) { WithLines([]string{"unicode filename test"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("unexpected error: %v", m.CommandOutputVal.Lines) } // Verify file exists and content is correct @@ -3835,12 +3725,12 @@ func TestEdgeCases(t *testing.T) { WithLines([]string{"version 1"}). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) // First write cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("first write failed: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("first write failed: %v", m.CommandOutputVal.Lines) } // Modify buffer @@ -3849,8 +3739,8 @@ func TestEdgeCases(t *testing.T) { // Second write cmdWrite(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { - t.Fatalf("second write failed: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Fatalf("second write failed: %v", m.CommandOutputVal.Lines) } // Verify final content @@ -3871,13 +3761,13 @@ func TestEdgeCases(t *testing.T) { Modified(). Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmd := cmdQuit(m, []string{}, true) // Should quit without error - if m.commandOutput != nil && m.commandOutput.IsError { - t.Errorf("unexpected error: %v", m.commandOutput.Lines) + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { + t.Errorf("unexpected error: %v", m.CommandOutputVal.Lines) } if cmd == nil { @@ -3905,13 +3795,13 @@ func TestCmdNextBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -3920,14 +3810,14 @@ func TestCmdNextBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() // Start active on buf2 (index 1, the last) - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected wrap to a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected wrap to a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -3936,34 +3826,34 @@ func TestCmdNextBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("step 1: expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("step 1: expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "c.txt" { - t.Errorf("step 2: expected c.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "c.txt" { + t.Errorf("step 2: expected c.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("step 3: expected wrap to a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("step 3: expected wrap to a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("stays on same buffer when only one buffer", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdNextBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -3972,8 +3862,8 @@ func TestCmdNextBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("unlisted.txt").Build() // NOT listed buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} // NOTE: The current implementation uses a flat index into bufs[] rather // than filtering to listed-only before computing nextId, so it does NOT @@ -3982,9 +3872,9 @@ func TestCmdNextBuffer(t *testing.T) { cmdNextBuffer(m, []string{}, false) // Actual behavior: advances to index 1 regardless of Listed flag. - if m.activeWindow.Buffer.Filename != "unlisted.txt" { + if m.ActiveWindowVal.Buffer.Filename != "unlisted.txt" { t.Logf("note: unlisted skip behavior differs from expectation, got %q", - m.activeWindow.Buffer.Filename) + m.ActiveWindowVal.Buffer.Filename) } }) @@ -3992,14 +3882,14 @@ func TestCmdNextBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) // Should behave identically regardless of args/force values cmdNextBuffer(m, []string{"ignored", "args"}, true) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4007,8 +3897,8 @@ func TestCmdNextBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = append(m.buffers, &buf2) + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = append(m.BuffersList, &buf2) cmd := cmdNextBuffer(m, []string{}, false) @@ -4028,14 +3918,14 @@ func TestCmdPrevBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() // Start active on buf2 (index 1) - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmdPrevBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4044,8 +3934,8 @@ func TestCmdPrevBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() // Start at index 0 (buf1). prevId = (0-1) % 2 = -1 in Go → panic. - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} defer func() { if r := recover(); r != nil { @@ -4057,8 +3947,8 @@ func TestCmdPrevBuffer(t *testing.T) { cmdPrevBuffer(m, []string{}, false) // If we reach here the bug is fixed — verify it wrapped to the last buffer. - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected wrap to b.txt (last), got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected wrap to b.txt (last), got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4068,32 +3958,32 @@ func TestCmdPrevBuffer(t *testing.T) { buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() // Start at index 2 (buf3) to avoid the wrap-around bug - m := newMockModelWithBuffer(&buf3) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} - m.activeWindow.Buffer = &buf3 + m := action.NewMockModelWithBuffer(&buf3) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} + m.ActiveWindowVal.Buffer = &buf3 cmdPrevBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("step 1: expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("step 1: expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } cmdPrevBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("step 2: expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("step 2: expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("stays on same buffer when only one buffer", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) // (0-1) % 1 == 0 in Go (modulo of -1 by 1 is 0), so single-buffer case // does not panic and correctly stays on the same buffer. cmdPrevBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4103,14 +3993,14 @@ func TestCmdPrevBuffer(t *testing.T) { buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() // Start at index 2 to avoid the wrap-around bug - m := newMockModelWithBuffer(&buf3) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} - m.activeWindow.Buffer = &buf3 + m := action.NewMockModelWithBuffer(&buf3) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} + m.ActiveWindowVal.Buffer = &buf3 cmdPrevBuffer(m, []string{"ignored"}, true) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4119,9 +4009,9 @@ func TestCmdPrevBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() // Start at index 1 to avoid the wrap-around bug - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmd := cmdPrevBuffer(m, []string{}, false) @@ -4141,16 +4031,16 @@ func TestCmdListBuffers(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdListBuffers(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected command output, got nil") } - if len(m.commandOutput.Lines) != 3 { - t.Errorf("expected 3 lines, got %d: %v", len(m.commandOutput.Lines), m.commandOutput.Lines) + if len(m.CommandOutputVal.Lines) != 3 { + t.Errorf("expected 3 lines, got %d: %v", len(m.CommandOutputVal.Lines), m.CommandOutputVal.Lines) } }) @@ -4158,16 +4048,16 @@ func TestCmdListBuffers(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("foo.go").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("bar.go").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdListBuffers(m, []string{}, false) - if !strings.Contains(m.commandOutput.Lines[0], "foo.go") { - t.Errorf("line 0 should contain foo.go: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "foo.go") { + t.Errorf("line 0 should contain foo.go: %q", m.CommandOutputVal.Lines[0]) } - if !strings.Contains(m.commandOutput.Lines[1], "bar.go") { - t.Errorf("line 1 should contain bar.go: %q", m.commandOutput.Lines[1]) + if !strings.Contains(m.CommandOutputVal.Lines[1], "bar.go") { + t.Errorf("line 1 should contain bar.go: %q", m.CommandOutputVal.Lines[1]) } }) @@ -4176,16 +4066,16 @@ func TestCmdListBuffers(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() // buf1 is active - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdListBuffers(m, []string{}, false) - if !strings.Contains(m.commandOutput.Lines[0], "%") { - t.Errorf("current buffer line should contain %%: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "%") { + t.Errorf("current buffer line should contain %%: %q", m.CommandOutputVal.Lines[0]) } - if strings.Contains(m.commandOutput.Lines[1], "%") { - t.Errorf("non-current buffer line should not contain %%: %q", m.commandOutput.Lines[1]) + if strings.Contains(m.CommandOutputVal.Lines[1], "%") { + t.Errorf("non-current buffer line should not contain %%: %q", m.CommandOutputVal.Lines[1]) } }) @@ -4193,16 +4083,16 @@ func TestCmdListBuffers(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdListBuffers(m, []string{}, false) - if !strings.Contains(m.commandOutput.Lines[0], "+") { - t.Errorf("modified buffer line should contain +: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "+") { + t.Errorf("modified buffer line should contain +: %q", m.CommandOutputVal.Lines[0]) } - if strings.Contains(m.commandOutput.Lines[1], "+") { - t.Errorf("unmodified buffer line should not contain +: %q", m.commandOutput.Lines[1]) + if strings.Contains(m.CommandOutputVal.Lines[1], "+") { + t.Errorf("unmodified buffer line should not contain +: %q", m.CommandOutputVal.Lines[1]) } }) @@ -4210,16 +4100,16 @@ func TestCmdListBuffers(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().ReadOnly().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdListBuffers(m, []string{}, false) - if !strings.Contains(m.commandOutput.Lines[0], "-") { - t.Errorf("readonly buffer line should contain -: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "-") { + t.Errorf("readonly buffer line should contain -: %q", m.CommandOutputVal.Lines[0]) } - if strings.Contains(m.commandOutput.Lines[1], "-") { - t.Errorf("writable buffer line should not contain -: %q", m.commandOutput.Lines[1]) + if strings.Contains(m.CommandOutputVal.Lines[1], "-") { + t.Errorf("writable buffer line should not contain -: %q", m.CommandOutputVal.Lines[1]) } }) @@ -4229,107 +4119,107 @@ func TestCmdListBuffers(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf2.Loaded = false - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdListBuffers(m, []string{}, false) - if !strings.Contains(m.commandOutput.Lines[0], "l") { - t.Errorf("loaded buffer line should contain l: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "l") { + t.Errorf("loaded buffer line should contain l: %q", m.CommandOutputVal.Lines[0]) } - if strings.Contains(m.commandOutput.Lines[1], "l") { - t.Errorf("unloaded buffer line should not contain l: %q", m.commandOutput.Lines[1]) + if strings.Contains(m.CommandOutputVal.Lines[1], "l") { + t.Errorf("unloaded buffer line should not contain l: %q", m.CommandOutputVal.Lines[1]) } }) t.Run("each line contains the buffer id", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdListBuffers(m, []string{}, false) idStr := fmt.Sprintf("%d", buf.Id) - if !strings.Contains(m.commandOutput.Lines[0], idStr) { - t.Errorf("line should contain buffer id %s: %q", idStr, m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], idStr) { + t.Errorf("line should contain buffer id %s: %q", idStr, m.CommandOutputVal.Lines[0]) } }) t.Run("title is :buffers", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListBuffers(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected command output") } - if m.commandOutput.Title != ":buffers" { - t.Errorf("title = %q, want %q", m.commandOutput.Title, ":buffers") + if m.CommandOutputVal.Title != ":buffers" { + t.Errorf("title = %q, want %q", m.CommandOutputVal.Title, ":buffers") } }) t.Run("output is not inline", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListBuffers(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected command output") } - if m.commandOutput.Inline { + if m.CommandOutputVal.Inline { t.Error("expected Inline=false (overlay window, not command bar)") } }) t.Run("output is not an error", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListBuffers(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected command output") } - if m.commandOutput.IsError { + if m.CommandOutputVal.IsError { t.Error("expected IsError=false") } }) t.Run("sets mode to CommandOutputMode", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListBuffers(m, []string{}, false) - if m.mode != core.CommandOutputMode { - t.Errorf("mode = %v, want CommandOutputMode", m.mode) + if m.ModeVal != core.CommandOutputMode { + t.Errorf("mode = %v, want CommandOutputMode", m.ModeVal) } }) t.Run("single buffer lists just that buffer", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdListBuffers(m, []string{}, false) - if len(m.commandOutput.Lines) != 1 { - t.Errorf("expected 1 line, got %d", len(m.commandOutput.Lines)) + if len(m.CommandOutputVal.Lines) != 1 { + t.Errorf("expected 1 line, got %d", len(m.CommandOutputVal.Lines)) } - if !strings.Contains(m.commandOutput.Lines[0], "%") { - t.Errorf("single buffer should be marked current: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "%") { + t.Errorf("single buffer should be marked current: %q", m.CommandOutputVal.Lines[0]) } - if !strings.Contains(m.commandOutput.Lines[0], "only.txt") { - t.Errorf("line should contain filename: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "only.txt") { + t.Errorf("line should contain filename: %q", m.CommandOutputVal.Lines[0]) } }) t.Run("buffer with both modified and readonly shows both flags", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().ReadOnly().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdListBuffers(m, []string{}, false) - line := m.commandOutput.Lines[0] + line := m.CommandOutputVal.Lines[0] if !strings.Contains(line, "+") { t.Errorf("line should contain + (modified): %q", line) } @@ -4339,17 +4229,17 @@ func TestCmdListBuffers(t *testing.T) { }) t.Run("args and force are ignored", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListBuffers(m, []string{"ignored"}, true) - if m.commandOutput == nil || m.commandOutput.IsError { + if m.CommandOutputVal == nil || m.CommandOutputVal.IsError { t.Error("args/force should have no effect") } }) t.Run("returns nil tea.Cmd", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmd := cmdListBuffers(m, []string{}, false) @@ -4361,16 +4251,16 @@ func TestCmdListBuffers(t *testing.T) { t.Run("buffer with no filename shows empty string in quotes", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdListBuffers(m, []string{}, false) // Should still produce a line (not panic or skip) - if len(m.commandOutput.Lines) != 1 { - t.Fatalf("expected 1 line, got %d", len(m.commandOutput.Lines)) + if len(m.CommandOutputVal.Lines) != 1 { + t.Fatalf("expected 1 line, got %d", len(m.CommandOutputVal.Lines)) } - if !strings.Contains(m.commandOutput.Lines[0], "\"\"") { - t.Errorf("unnamed buffer should show empty quoted filename: %q", m.commandOutput.Lines[0]) + if !strings.Contains(m.CommandOutputVal.Lines[0], "\"\"") { + t.Errorf("unnamed buffer should show empty quoted filename: %q", m.CommandOutputVal.Lines[0]) } }) } @@ -4386,14 +4276,14 @@ func TestCmdFirstBuffer(t *testing.T) { buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() // Start active on buf3 - m := newMockModelWithBuffer(&buf3) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} - m.activeWindow.Buffer = &buf3 + m := action.NewMockModelWithBuffer(&buf3) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} + m.ActiveWindowVal.Buffer = &buf3 cmdFirstBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4401,25 +4291,25 @@ func TestCmdFirstBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdFirstBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("works with a single buffer", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdFirstBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4430,14 +4320,14 @@ func TestCmdFirstBuffer(t *testing.T) { buf4 := core.NewBufferBuilder().WithFilename("d.txt").Listed().Build() // Start active on buf2 (middle) - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3, &buf4} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3, &buf4} + m.ActiveWindowVal.Buffer = &buf2 cmdFirstBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4445,14 +4335,14 @@ func TestCmdFirstBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmdFirstBuffer(m, []string{"ignored"}, true) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4460,9 +4350,9 @@ func TestCmdFirstBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmd := cmdFirstBuffer(m, []string{}, false) @@ -4483,13 +4373,13 @@ func TestCmdLastBuffer(t *testing.T) { buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() // Start active on buf1 - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdLastBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "c.txt" { - t.Errorf("expected c.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "c.txt" { + t.Errorf("expected c.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4497,26 +4387,26 @@ func TestCmdLastBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmdLastBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("works with a single buffer", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdLastBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4527,14 +4417,14 @@ func TestCmdLastBuffer(t *testing.T) { buf4 := core.NewBufferBuilder().WithFilename("d.txt").Listed().Build() // Start active on buf2 (middle) - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3, &buf4} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3, &buf4} + m.ActiveWindowVal.Buffer = &buf2 cmdLastBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Filename != "d.txt" { - t.Errorf("expected d.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "d.txt" { + t.Errorf("expected d.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4542,13 +4432,13 @@ func TestCmdLastBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdLastBuffer(m, []string{"ignored"}, true) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4556,8 +4446,8 @@ func TestCmdLastBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdLastBuffer(m, []string{}, false) @@ -4579,13 +4469,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdSelectBuffer(m, []string{"b.txt"}, false) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4593,14 +4483,14 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf2) - m.buffers = []*core.Buffer{&buf1, &buf2} - m.activeWindow.Buffer = &buf2 + m := action.NewMockModelWithBuffer(&buf2) + m.BuffersList = []*core.Buffer{&buf1, &buf2} + m.ActiveWindowVal.Buffer = &buf2 cmdSelectBuffer(m, []string{"a.txt"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4608,25 +4498,25 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"a.txt"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("works with a single buffer by filename", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdSelectBuffer(m, []string{"only.txt"}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4637,13 +4527,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdSelectBuffer(m, []string{fmt.Sprintf("%d", buf3.Id)}, false) - if m.activeWindow.Buffer.Filename != "c.txt" { - t.Errorf("expected c.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "c.txt" { + t.Errorf("expected c.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4651,25 +4541,25 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{fmt.Sprintf("%d", buf1.Id)}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("works with a single buffer by ID", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("only.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdSelectBuffer(m, []string{fmt.Sprintf("%d", buf.Id)}, false) - if m.activeWindow.Buffer.Filename != "only.txt" { - t.Errorf("expected only.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "only.txt" { + t.Errorf("expected only.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4679,12 +4569,12 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"nope.txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for unknown filename") } }) @@ -4693,13 +4583,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"nope.txt"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected active buffer to remain a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected active buffer to remain a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4707,12 +4597,12 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"99999"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for unknown buffer ID") } }) @@ -4721,24 +4611,24 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"99999"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected active buffer to remain a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected active buffer to remain a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) t.Run("negative number is treated as unknown and sets error output", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdSelectBuffer(m, []string{"-1"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for negative buffer ID") } }) @@ -4746,11 +4636,11 @@ func TestCmdSelectBuffer(t *testing.T) { t.Run("non-numeric non-filename arg sets error output", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdSelectBuffer(m, []string{"???"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for invalid arg") } }) @@ -4759,8 +4649,8 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdSelectBuffer(m, []string{"b.txt"}, false) @@ -4773,8 +4663,8 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdSelectBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) @@ -4787,13 +4677,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"b.txt"}, true) - if m.activeWindow.Buffer.Filename != "b.txt" { - t.Errorf("expected b.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "b.txt" { + t.Errorf("expected b.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4803,14 +4693,14 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("alpha.go").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("beta.go").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // "lpha" is a unique substring of "alpha.go" cmdSelectBuffer(m, []string{"lpha"}, false) - if m.activeWindow.Buffer.Filename != "alpha.go" { - t.Errorf("expected alpha.go, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "alpha.go" { + t.Errorf("expected alpha.go, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4818,14 +4708,14 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("src/foo/main.go").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("src/bar/main.go").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // "foo" uniquely identifies the first buffer cmdSelectBuffer(m, []string{"foo"}, false) - if m.activeWindow.Buffer.Filename != "src/foo/main.go" { - t.Errorf("expected src/foo/main.go, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "src/foo/main.go" { + t.Errorf("expected src/foo/main.go, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4833,13 +4723,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // ".txt" matches both buffers cmdSelectBuffer(m, []string{".txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for ambiguous substring") } }) @@ -4848,13 +4738,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{".txt"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected active buffer to remain a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected active buffer to remain a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4863,15 +4753,15 @@ func TestCmdSelectBuffer(t *testing.T) { t.Run("no args is a no-op and sets no error", func(t *testing.T) { buf := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf) + m := action.NewMockModelWithBuffer(&buf) cmdSelectBuffer(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { t.Error("expected no error CommandOutput when no args provided") } - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected active buffer to remain a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected active buffer to remain a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) @@ -4881,12 +4771,12 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"a.txt", "b.txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for multiple args") } }) @@ -4895,13 +4785,13 @@ func TestCmdSelectBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdSelectBuffer(m, []string{"a.txt", "b.txt"}, false) - if m.activeWindow.Buffer.Filename != "a.txt" { - t.Errorf("expected active buffer to remain a.txt, got %q", m.activeWindow.Buffer.Filename) + if m.ActiveWindowVal.Buffer.Filename != "a.txt" { + t.Errorf("expected active buffer to remain a.txt, got %q", m.ActiveWindowVal.Buffer.Filename) } }) } @@ -4920,8 +4810,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) @@ -4930,24 +4820,24 @@ func TestCmdDeleteBuffer(t *testing.T) { } }) - t.Run("no-args keeps buffer in m.buffers", func(t *testing.T) { + t.Run("no-args keeps buffer in m.BuffersList", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) found := false - for _, b := range m.buffers { + for _, b := range m.BuffersList { if b.Id == buf1.Id { found = true break } } if !found { - t.Error("expected buf1 to remain in m.buffers after unlisting") + t.Error("expected buf1 to remain in m.BuffersList after unlisting") } }) @@ -4955,8 +4845,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) @@ -4969,16 +4859,16 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) - if m.activeWindow.Buffer.Id == buf1.Id { + if m.ActiveWindowVal.Buffer.Id == buf1.Id { t.Error("expected active window to switch away from unlisted buf1") } - if m.activeWindow.Buffer.Id != buf2.Id { - t.Errorf("expected active window to show buf2, got buffer id %d", m.activeWindow.Buffer.Id) + if m.ActiveWindowVal.Buffer.Id != buf2.Id { + t.Errorf("expected active window to show buf2, got buffer id %d", m.ActiveWindowVal.Buffer.Id) } }) @@ -4986,12 +4876,12 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for modified buffer without force") } if !buf1.Listed { @@ -5003,8 +4893,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, true) @@ -5017,12 +4907,12 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { t.Error("expected no error CommandOutput on successful unlisting") } }) @@ -5031,8 +4921,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdDeleteBuffer(m, []string{}, false) @@ -5045,8 +4935,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdDeleteBuffer(m, []string{}, false) @@ -5059,15 +4949,15 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Modified().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected commandOutput to be set") } - if !m.commandOutput.Inline { + if !m.CommandOutputVal.Inline { t.Error("expected commandOutput.Inline to be true") } }) @@ -5081,8 +4971,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) @@ -5091,25 +4981,25 @@ func TestCmdDeleteBuffer(t *testing.T) { } }) - t.Run("unlist by ID keeps buffer in m.buffers", func(t *testing.T) { + t.Run("unlist by ID keeps buffer in m.BuffersList", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) found := false - for _, b := range m.buffers { + for _, b := range m.BuffersList { if b.Id == buf2.Id { found = true break } } if !found { - t.Error("expected buf2 to remain in m.buffers after unlisting") + t.Error("expected buf2 to remain in m.BuffersList after unlisting") } }) @@ -5118,8 +5008,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) @@ -5136,24 +5026,24 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) - if m.activeWindow.Buffer.Id != buf1.Id { - t.Errorf("expected active window to remain on buf1, got buffer id %d", m.activeWindow.Buffer.Id) + if m.ActiveWindowVal.Buffer.Id != buf1.Id { + t.Errorf("expected active window to remain on buf1, got buffer id %d", m.ActiveWindowVal.Buffer.Id) } }) t.Run("unknown numeric ID sets error output", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) cmdDeleteBuffer(m, []string{"99999"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for unknown buffer ID") } }) @@ -5161,7 +5051,7 @@ func TestCmdDeleteBuffer(t *testing.T) { t.Run("unknown numeric ID does not unlist any buffer", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) cmdDeleteBuffer(m, []string{"99999"}, false) @@ -5174,12 +5064,12 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Modified().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for modified buffer without force") } if !buf2.Listed { @@ -5191,8 +5081,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Modified().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, true) @@ -5205,8 +5095,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdDeleteBuffer(m, []string{fmt.Sprintf("%d", buf2.Id)}, false) @@ -5223,8 +5113,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{"b.txt"}, false) @@ -5233,24 +5123,24 @@ func TestCmdDeleteBuffer(t *testing.T) { } }) - t.Run("unlist by exact filename keeps buffer in m.buffers", func(t *testing.T) { + t.Run("unlist by exact filename keeps buffer in m.BuffersList", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{"b.txt"}, false) found := false - for _, b := range m.buffers { + for _, b := range m.BuffersList { if b.Id == buf2.Id { found = true break } } if !found { - t.Error("expected buf2 to remain in m.buffers after unlisting") + t.Error("expected buf2 to remain in m.BuffersList after unlisting") } }) @@ -5258,8 +5148,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("alpha.go").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("beta.go").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // "lpha" uniquely identifies alpha.go cmdDeleteBuffer(m, []string{"lpha"}, false) @@ -5273,8 +5163,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("src/foo/main.go").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("src/bar/main.go").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // "foo" uniquely identifies src/foo/main.go cmdDeleteBuffer(m, []string{"foo"}, false) @@ -5288,13 +5178,13 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} // ".txt" matches both buffers cmdDeleteBuffer(m, []string{".txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for ambiguous substring") } }) @@ -5303,8 +5193,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{".txt"}, false) @@ -5319,11 +5209,11 @@ func TestCmdDeleteBuffer(t *testing.T) { t.Run("unknown filename sets error output", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) cmdDeleteBuffer(m, []string{"nope.txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for unknown filename") } }) @@ -5331,7 +5221,7 @@ func TestCmdDeleteBuffer(t *testing.T) { t.Run("unknown filename does not unlist any buffer", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) cmdDeleteBuffer(m, []string{"nope.txt"}, false) @@ -5344,13 +5234,13 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{"b.txt"}, false) - if m.activeWindow.Buffer.Id != buf1.Id { - t.Errorf("expected active window to remain on buf1, got buffer id %d", m.activeWindow.Buffer.Id) + if m.ActiveWindowVal.Buffer.Id != buf1.Id { + t.Errorf("expected active window to remain on buf1, got buffer id %d", m.ActiveWindowVal.Buffer.Id) } }) @@ -5358,8 +5248,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmd := cmdDeleteBuffer(m, []string{"b.txt"}, false) @@ -5377,8 +5267,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{ fmt.Sprintf("%d", buf2.Id), @@ -5398,8 +5288,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{"b.txt", "c.txt"}, false) @@ -5416,8 +5306,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{ fmt.Sprintf("%d", buf2.Id), @@ -5437,8 +5327,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Modified().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Modified().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{"b.txt", "c.txt"}, true) @@ -5455,12 +5345,12 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Modified().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Modified().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmdDeleteBuffer(m, []string{"b.txt", "c.txt"}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected an error CommandOutput for modified buffers without force") } if !buf2.Listed { @@ -5476,8 +5366,8 @@ func TestCmdDeleteBuffer(t *testing.T) { buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() buf3 := core.NewBufferBuilder().WithFilename("c.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2, &buf3} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2, &buf3} cmd := cmdDeleteBuffer(m, []string{"b.txt", "c.txt"}, false) @@ -5509,7 +5399,7 @@ func TestCmdDeleteBuffer(t *testing.T) { // // cmdDeleteBuffer(m, []string{}, false) // - // if m.activeWindow.Buffer.Id == buf1.Id { + // if m.ActiveWindowVal.Buffer.Id == buf1.Id { // t.Error("expected active window to switch away from unlisted buf1") // } // }) @@ -5573,7 +5463,7 @@ func TestCmdDeleteBuffer(t *testing.T) { t.Run("returns nil tea.Cmd in all error cases", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) // Error case: unknown ID cmd := cmdDeleteBuffer(m, []string{"99999"}, false) @@ -5586,12 +5476,12 @@ func TestCmdDeleteBuffer(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() buf2 := core.NewBufferBuilder().WithFilename("b.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) - m.buffers = []*core.Buffer{&buf1, &buf2} + m := action.NewMockModelWithBuffer(&buf1) + m.BuffersList = []*core.Buffer{&buf1, &buf2} cmdDeleteBuffer(m, []string{"b.txt"}, false) - if m.commandOutput != nil && m.commandOutput.IsError { + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { t.Error("expected no error CommandOutput on successful unlist by filename") } }) @@ -5599,15 +5489,15 @@ func TestCmdDeleteBuffer(t *testing.T) { t.Run("all errors use inline output", func(t *testing.T) { buf1 := core.NewBufferBuilder().WithFilename("a.txt").Listed().Build() - m := newMockModelWithBuffer(&buf1) + m := action.NewMockModelWithBuffer(&buf1) // Error case: unknown filename cmdDeleteBuffer(m, []string{"nope.txt"}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected commandOutput to be set") } - if !m.commandOutput.Inline { + if !m.CommandOutputVal.Inline { t.Error("expected commandOutput.Inline to be true for all errors") } }) @@ -5624,7 +5514,7 @@ func TestCmdColorscheme(t *testing.T) { // -------------------------------------------------- t.Run("valid name updates styles on model", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"onedark"}, false) @@ -5635,13 +5525,13 @@ func TestCmdColorscheme(t *testing.T) { }) t.Run("same valid name applied twice produces same styles", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"monokai"}, false) - first := m.styles.BackgroundStyle.Render(" ") + first := m.StylesVal.BackgroundStyle.Render(" ") cmdColorscheme(m, []string{"monokai"}, false) - second := m.styles.BackgroundStyle.Render(" ") + second := m.StylesVal.BackgroundStyle.Render(" ") if first != second { t.Error("expected applying the same colorscheme twice to produce identical styles") @@ -5649,17 +5539,17 @@ func TestCmdColorscheme(t *testing.T) { }) t.Run("valid name sets no error output", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"monokai"}, false) - if m.commandOutput != nil && m.commandOutput.IsError { + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { t.Error("expected no error output for a valid colorscheme name") } }) t.Run("valid name returns nil tea.Cmd", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmd := cmdColorscheme(m, []string{"monokai"}, false) @@ -5673,48 +5563,48 @@ func TestCmdColorscheme(t *testing.T) { // -------------------------------------------------- t.Run("unknown name sets error output", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"not-a-real-theme"}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected commandOutput to be set for unknown colorscheme") } - if !m.commandOutput.IsError { + if !m.CommandOutputVal.IsError { t.Error("expected commandOutput.IsError to be true for unknown colorscheme") } }) t.Run("unknown name does not change styles", func(t *testing.T) { - m := newMockModel() - before := m.styles.BackgroundStyle.Render(" ") + m := action.NewMockModel() + before := m.StylesVal.BackgroundStyle.Render(" ") cmdColorscheme(m, []string{"not-a-real-theme"}, false) - if m.styles.BackgroundStyle.Render(" ") != before { + if m.StylesVal.BackgroundStyle.Render(" ") != before { t.Error("expected styles to remain unchanged after unknown colorscheme") } }) t.Run("empty string name sets error output", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{""}, false) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error output for empty colorscheme name") } }) t.Run("unknown name error output is inline", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"not-a-real-theme"}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected commandOutput to be set") } - if !m.commandOutput.Inline { + if !m.CommandOutputVal.Inline { t.Error("expected error commandOutput to be inline") } }) @@ -5724,28 +5614,28 @@ func TestCmdColorscheme(t *testing.T) { // -------------------------------------------------- t.Run("no args sets no error output", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{}, false) - if m.commandOutput != nil && m.commandOutput.IsError { + if m.CommandOutputVal != nil && m.CommandOutputVal.IsError { t.Error("expected no error output when called with no args") } }) t.Run("no args does not change styles", func(t *testing.T) { - m := newMockModel() - before := m.styles.BackgroundStyle.Render(" ") + m := action.NewMockModel() + before := m.StylesVal.BackgroundStyle.Render(" ") cmdColorscheme(m, []string{}, false) - if m.styles.BackgroundStyle.Render(" ") != before { + if m.StylesVal.BackgroundStyle.Render(" ") != before { t.Error("expected styles to remain unchanged when no args given") } }) t.Run("no args returns nil tea.Cmd", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmd := cmdColorscheme(m, []string{}, false) @@ -5759,7 +5649,7 @@ func TestCmdColorscheme(t *testing.T) { // -------------------------------------------------- t.Run("extra args beyond name do not panic", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"monokai", "extra", "args"}, false) }) @@ -5769,7 +5659,7 @@ func TestCmdColorscheme(t *testing.T) { // -------------------------------------------------- t.Run("force flag with valid name still sets styles", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"monokai"}, true) @@ -5780,11 +5670,11 @@ func TestCmdColorscheme(t *testing.T) { }) t.Run("force flag with invalid name still sets error output", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdColorscheme(m, []string{"not-a-real-theme"}, true) - if m.commandOutput == nil || !m.commandOutput.IsError { + if m.CommandOutputVal == nil || !m.CommandOutputVal.IsError { t.Error("expected error output for unknown colorscheme even with force=true") } }) @@ -5797,61 +5687,61 @@ func TestCmdColorscheme(t *testing.T) { func TestCmdListColorschemes(t *testing.T) { t.Run("sets mode to CommandOutputMode", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - if m.mode != core.CommandOutputMode { - t.Errorf("expected mode CommandOutputMode, got %v", m.mode) + if m.ModeVal != core.CommandOutputMode { + t.Errorf("expected mode CommandOutputMode, got %v", m.ModeVal) } }) t.Run("sets commandOutput", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - if m.commandOutput == nil { + if m.CommandOutputVal == nil { t.Fatal("expected commandOutput to be set") } }) t.Run("commandOutput is not an error", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - if m.commandOutput.IsError { + if m.CommandOutputVal.IsError { t.Error("expected commandOutput.IsError to be false") } }) t.Run("commandOutput is not inline", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - if m.commandOutput.Inline { + if m.CommandOutputVal.Inline { t.Error("expected commandOutput.Inline to be false") } }) t.Run("commandOutput title is :colorschemes", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - if m.commandOutput.Title != ":colorschemes" { - t.Errorf("expected title ':colorschemes', got %q", m.commandOutput.Title) + if m.CommandOutputVal.Title != ":colorschemes" { + t.Errorf("expected title ':colorschemes', got %q", m.CommandOutputVal.Title) } }) t.Run("commandOutput lines contains known built-in styles", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - lines := m.commandOutput.Lines + lines := m.CommandOutputVal.Lines known := []string{"monokai", "github-dark", "dracula"} for _, name := range known { found := false @@ -5868,22 +5758,22 @@ func TestCmdListColorschemes(t *testing.T) { }) t.Run("commandOutput lines matches styles.Names()", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) expected := cStyles.Names() - if len(m.commandOutput.Lines) != len(expected) { - t.Errorf("expected %d colorschemes, got %d", len(expected), len(m.commandOutput.Lines)) + if len(m.CommandOutputVal.Lines) != len(expected) { + t.Errorf("expected %d colorschemes, got %d", len(expected), len(m.CommandOutputVal.Lines)) } }) t.Run("commandOutput lines are non-empty strings", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmdListColorschemes(m, []string{}, false) - for i, l := range m.commandOutput.Lines { + for i, l := range m.CommandOutputVal.Lines { if strings.TrimSpace(l) == "" { t.Errorf("commandOutput.Lines[%d] is blank", i) } @@ -5891,19 +5781,19 @@ func TestCmdListColorschemes(t *testing.T) { }) t.Run("args and force are ignored", func(t *testing.T) { - m1 := newMockModel() - m2 := newMockModel() + m1 := action.NewMockModel() + m2 := action.NewMockModel() cmdListColorschemes(m1, []string{}, false) cmdListColorschemes(m2, []string{"monokai", "extra"}, true) - if len(m1.commandOutput.Lines) != len(m2.commandOutput.Lines) { + if len(m1.CommandOutputVal.Lines) != len(m2.CommandOutputVal.Lines) { t.Error("expected args and force to have no effect on list output") } }) t.Run("returns nil tea.Cmd", func(t *testing.T) { - m := newMockModel() + m := action.NewMockModel() cmd := cmdListColorschemes(m, []string{}, false) diff --git a/internal/motion/command_test.go b/internal/motion/command_test.go index 2bcf740..7ae3f42 100644 --- a/internal/motion/command_test.go +++ b/internal/motion/command_test.go @@ -5,92 +5,19 @@ import ( "git.gophernest.net/azpect/TextEditor/internal/action" "git.gophernest.net/azpect/TextEditor/internal/core" - "git.gophernest.net/azpect/TextEditor/internal/style" ) -// ================================================== -// Mock Model Implementation -// ================================================== - -type mockModel struct { - windows []*core.Window - activeWindow *core.Window - buffers []*core.Buffer - settings core.EditorSettings - mode core.Mode - registers map[rune]core.Register - insertKeys []string - command string - commandCursor int - commandOutput *core.CommandOutput - commandHistory []string - commandHistoryCursor int - lastFind core.LastFindCommand - styles style.Styles -} - -// Core Data Access -func (m *mockModel) Windows() []*core.Window { return m.windows } -func (m *mockModel) ActiveWindow() *core.Window { return m.activeWindow } -func (m *mockModel) Buffers() []*core.Buffer { return m.buffers } -func (m *mockModel) SetBuffers(bufs []*core.Buffer) { m.buffers = bufs } -func (m *mockModel) ActiveBuffer() *core.Buffer { return m.activeWindow.Buffer } - -// Insert Mode State -func (m *mockModel) InsertKeys() []string { return m.insertKeys } -func (m *mockModel) SetInsertKeys(keys []string) { m.insertKeys = keys } -func (m *mockModel) SetInsertRecording(count int, action action.Action) {} -func (m *mockModel) ExitInsertMode() {} -func (m *mockModel) SetLastFind(char string, forward, inclusive bool) { - m.lastFind = core.LastFindCommand{Char: char, Forward: forward, Inclusive: inclusive} -} -func (m *mockModel) GetLastFind() *core.LastFindCommand { return &m.lastFind } - -// Command Mode State -func (m *mockModel) Command() string { return m.command } -func (m *mockModel) SetCommand(cmd string) { m.command = cmd } -func (m *mockModel) CommandCursor() int { return m.commandCursor } -func (m *mockModel) SetCommandCursor(cur int) { m.commandCursor = cur } -func (m *mockModel) CommandOutput() *core.CommandOutput { return m.commandOutput } -func (m *mockModel) SetCommandOutput(out *core.CommandOutput) { m.commandOutput = out } -func (m *mockModel) CommandHistory() []string { return m.commandHistory } -func (m *mockModel) SetCommandHistory(history []string) { m.commandHistory = history } -func (m *mockModel) CommandHistoryCursor() int { return m.commandHistoryCursor } -func (m *mockModel) SetCommandHistoryCursor(cur int) { m.commandHistoryCursor = cur } - -// Editor-wide State -func (m *mockModel) Mode() core.Mode { return m.mode } -func (m *mockModel) SetMode(mode core.Mode) { m.mode = mode } -func (m *mockModel) Settings() core.EditorSettings { return m.settings } -func (m *mockModel) SetSettings(s core.EditorSettings) { m.settings = s } -func (m *mockModel) Styles() style.Styles { return m.styles } -func (m *mockModel) SetStyles(s style.Styles) { m.styles = s } - -// Registers -func (m *mockModel) Registers() map[rune]core.Register { return m.registers } -func (m *mockModel) GetRegister(name rune) (core.Register, bool) { - reg, ok := m.registers[name] - return reg, ok -} -func (m *mockModel) SetRegister(name rune, t core.RegisterType, cnt []string) error { - m.registers[name] = core.Register{Type: t, Content: cnt} - return nil -} -func (m *mockModel) UpdateDefaultRegister(t core.RegisterType, cnt []string) { - m.registers['"'] = core.Register{Type: t, Content: cnt} -} - // ================================================== // MoveCommandHistoryUp Tests // ================================================== func TestMoveCommandHistoryUp(t *testing.T) { t.Run("navigate up from start", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 0, } action := MoveCommandHistoryUp{} @@ -113,11 +40,11 @@ func TestMoveCommandHistoryUp(t *testing.T) { }) t.Run("navigate up multiple times", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 0, } action := MoveCommandHistoryUp{} @@ -146,11 +73,11 @@ func TestMoveCommandHistoryUp(t *testing.T) { }) t.Run("cannot navigate past end of history", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 3, // Already at end + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 3, // Already at end } action := MoveCommandHistoryUp{} @@ -168,11 +95,11 @@ func TestMoveCommandHistoryUp(t *testing.T) { }) t.Run("empty history does nothing", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "current", - commandHistory: []string{}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "current", + CommandHistoryList: []string{}, + CommandHistoryCur: 0, } action := MoveCommandHistoryUp{} @@ -189,12 +116,12 @@ func TestMoveCommandHistoryUp(t *testing.T) { }) t.Run("command cursor moves to end", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandCursor: 0, - commandHistory: []string{"long command here"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandCursorVal: 0, + CommandHistoryList: []string{"long command here"}, + CommandHistoryCur: 0, } action := MoveCommandHistoryUp{} @@ -213,11 +140,11 @@ func TestMoveCommandHistoryUp(t *testing.T) { func TestMoveCommandHistoryDown(t *testing.T) { t.Run("navigate down from middle of history", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "cmd2", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 2, // At cmd2 + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "cmd2", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 2, // At cmd2 } action := MoveCommandHistoryDown{} @@ -235,11 +162,11 @@ func TestMoveCommandHistoryDown(t *testing.T) { }) t.Run("navigate down to empty command", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "cmd3", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 1, // At first command + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "cmd3", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 1, // At first command } action := MoveCommandHistoryDown{} @@ -260,11 +187,11 @@ func TestMoveCommandHistoryDown(t *testing.T) { }) t.Run("navigate down from cursor 0 does nothing", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 0, // Already at bottom + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 0, // Already at bottom } action := MoveCommandHistoryDown{} @@ -281,12 +208,12 @@ func TestMoveCommandHistoryDown(t *testing.T) { }) t.Run("command cursor moves to end", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandCursor: 0, - commandHistory: []string{"cmd3", "long command here"}, - commandHistoryCursor: 2, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandCursorVal: 0, + CommandHistoryList: []string{"cmd3", "long command here"}, + CommandHistoryCur: 2, } action := MoveCommandHistoryDown{} @@ -305,11 +232,11 @@ func TestMoveCommandHistoryDown(t *testing.T) { func TestCommandHistoryIntegration(t *testing.T) { t.Run("up down up sequence", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd3", "cmd2", "cmd1"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd3", "cmd2", "cmd1"}, + CommandHistoryCur: 0, } upAction := MoveCommandHistoryUp{} @@ -334,11 +261,11 @@ func TestCommandHistoryIntegration(t *testing.T) { }) t.Run("navigate up past end does not crash", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd1", "cmd2"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd1", "cmd2"}, + CommandHistoryCur: 0, } upAction := MoveCommandHistoryUp{} @@ -356,11 +283,11 @@ func TestCommandHistoryIntegration(t *testing.T) { }) t.Run("navigate down past bottom does not crash", func(t *testing.T) { - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: []string{"cmd1"}, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: []string{"cmd1"}, + CommandHistoryCur: 0, } downAction := MoveCommandHistoryDown{} @@ -392,11 +319,11 @@ func TestCommandHistoryWithLongHistory(t *testing.T) { history[i] = string(rune('A' + i)) } - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: history, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: history, + CommandHistoryCur: 0, } upAction := MoveCommandHistoryUp{} @@ -421,11 +348,11 @@ func TestCommandHistoryWithLongHistory(t *testing.T) { history[i] = string(rune('0' + (i % 10))) } - m := &mockModel{ - mode: core.CommandMode, - command: "", - commandHistory: history, - commandHistoryCursor: 0, + m := &action.MockModel{ + ModeVal: core.CommandMode, + CommandVal: "", + CommandHistoryList: history, + CommandHistoryCur: 0, } upAction := MoveCommandHistoryUp{}