package main import ( "testing" "time" tea "github.com/charmbracelet/bubbletea" ) type compareFunc[T comparable] func(T, T) bool func assertFunc[T comparable](t *testing.T, compare compareFunc[T], actual, expected T, msg string) { t.Helper() if !compare(actual, expected) { t.Errorf("%s: expected %v, got %v", msg, expected, actual) } } // assertEqual checks if two values are equal and reports an error if they are not. func assertEqual(t *testing.T, actual, expected interface{}, msg string) { t.Helper() if actual != expected { t.Errorf("%s: expected %v, got %v", msg, expected, actual) } } // assertNotEqual checks if two values are not equal and reports an error if they are. func assertNotEqual(t *testing.T, actual, expected interface{}, msg string) { t.Helper() if actual == expected { t.Errorf("%s: expected %v to be different from %v", msg, actual, expected) } } // TestParseDuration tests the parseDuration function func TestParseDuration(t *testing.T) { tests := []struct { input string expected time.Duration hasError bool }{ {"10", 10 * time.Minute, false}, {"1h", 1 * time.Hour, false}, {"invalid", 0, true}, } for _, test := range tests { result, err := parseDuration(test.input) if test.hasError { assertNotEqual(t, err, nil, "Expected an error for input "+test.input) } else { assertEqual(t, err, nil, "Did not expect an error for input "+test.input) assertEqual(t, result, test.expected, "Expected duration for input "+test.input) } } } // TestRunCommands tests the runCommands function func TestRunCommands(t *testing.T) { m := initialModel(false, "#ffdd57", "#57ddff") m.shellrunner.Start() m.startCommands([]string{"echo Hello, World!"}) m.shellrunner.Stop() } // TestInputView tests the Update method of the model for the input view func TestInputView(t *testing.T) { m := initialModel(false, "#ffdd57", "#57ddff") m.View() assertEqual(t, m.currentScreen, inputScreen, "Expected currentScreen to be inputScreen") assertEqual(t, m.focusIndex, 0, "Expected focusIndex to be 0") m.inputs[m.focusIndex].SetValue("10") var msg tea.Msg // Test tab key press msg = tea.KeyMsg{Type: tea.KeyTab} updatedModel, _ := m.Update(msg) m = updatedModel.(model) assertEqual(t, m.focusIndex, 1, "Expected focusIndex to be 1") // Test shift+tab key press msg = tea.KeyMsg{Type: tea.KeyShiftTab} updatedModel, _ = m.Update(msg) m = updatedModel.(model) assertEqual(t, m.focusIndex, 0, "Expected focusIndex to be 0") // Enter last value and test enter key press for i := m.focusIndex; i < 2; i++ { msg = tea.KeyMsg{Type: tea.KeyTab} updatedModel, _ = m.Update(msg) m = updatedModel.(model) m.inputs[m.focusIndex].SetValue("10") } msg = tea.KeyMsg{Type: tea.KeyEnter} updatedModel, resultCmd := m.Update(msg) m = updatedModel.(model) assertEqual(t, m.err, nil, "Expected no error") assertNotEqual(t, resultCmd, nil, "Expected resultCmd to be not nil") assertEqual(t, m.currentScreen, timerScreen, "Expected currentScreen to be timerScreen") assertEqual(t, m.remaining.Round(time.Second), 10*time.Minute, "Expected remaining to be 10 minutes") // Test timer view m.View() oneSec := timeMsg(time.Now().Add(1 * time.Second)) updatedModel, _ = m.Update(oneSec) m = updatedModel.(model) assertEqual(t, m.state, "Focus", "Expected state to be 'Focus'") // Test switch to break time m.startTime = m.startTime.Add(-10 * time.Minute) updatedModel, _ = m.Update(oneSec) m = updatedModel.(model) assertEqual(t, m.state, "Break", "Expected state to be 'Break'") // Switch back to focus time m.startTime = m.startTime.Add(-10 * time.Minute) updatedModel, _ = m.Update(oneSec) m = updatedModel.(model) assertEqual(t, m.state, "Focus", "Expected state to be 'Focus'") }