package main import ( "bytes" "io" "os" "strings" "testing" "time" tea "github.com/charmbracelet/bubbletea" ) // 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) { r, w, err := os.Pipe() if err != nil { t.Fatal(err) } // Redirect stdout and stderr to the pipe oldStdout := os.Stdout oldStderr := os.Stderr os.Stdout = w os.Stderr = w t.Cleanup(func() { os.Stdout = oldStdout os.Stderr = oldStderr w.Close() }) m := model{} m.runCommands([]string{"echo Hello, World!"}) w.Close() var buf bytes.Buffer if _, err = io.Copy(&buf, r); err != nil { t.Fatal(err) } output := buf.String() assertEqual(t, strings.Contains(output, "Hello, World!"), true, "Expected output to contain 'Hello, World!'") } // 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, 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'") assertEqual(t, m.remaining, 9*time.Minute+59*time.Second, "Expected remaining to be 9 minutes 59 seconds") // Test switch to break time m.remaining = 0 updatedModel, _ = m.Update(oneSec) m = updatedModel.(model) assertEqual(t, m.state, "Break", "Expected state to be 'Break'") assertEqual(t, m.remaining, 9*time.Minute+59*time.Second, "Expected remaining to be 9 minutes 59 seconds") // Switch back to focus time m.remaining = 0 updatedModel, _ = m.Update(oneSec) m = updatedModel.(model) assertEqual(t, m.state, "Focus", "Expected state to be 'Focus'") assertEqual(t, m.remaining, 9*time.Minute+59*time.Second, "Expected remaining to be 9 minutes 59 seconds") }