summaryrefslogtreecommitdiff
path: root/internal/repl/tty_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-23 20:54:36 +0300
committerPaul Buetow <paul@buetow.org>2026-05-23 20:54:36 +0300
commit174b313c5ea475ff0baadf409f226d3e7b65738a (patch)
tree50e8503294a02faec07366e5fbef8aba2c4edbe7 /internal/repl/tty_test.go
parent54de2315861cdac384183623e1b466f83f397dfc (diff)
test: add unit tests for REPL subsystems
Add dedicated unit tests for four REPL components that lacked test coverage: - SignalHandler (signal_test.go): 5 tests covering constructor, Stop() without Start, callback execution, goroutine semantics, and single-shot signal handling behavior - TTYChecker (tty_test.go): 5 tests covering EnsureTTY error in non-TTY context, error message content, IsTTY return value, IsTTY/EnsureTTY consistency, and idempotent behavior - HistoryManager (history_test.go): 11 tests covering constructor, Path() with default and custom baseDir, Save/Load roundtrip, maxEntries truncation, non-existent file, empty file/slice, special characters, and file overwrite behavior. Added WithBaseDir() method to enable testing with temp directories. - AutoCompleteAdapter (completer_adapter_test.go): 5 tests covering Do() with empty/whitespace input, exact/partial/no matches, case-insensitive matching, multi-word completion, cursor position, common prefix calculation, and command order preservation
Diffstat (limited to 'internal/repl/tty_test.go')
-rw-r--r--internal/repl/tty_test.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/internal/repl/tty_test.go b/internal/repl/tty_test.go
new file mode 100644
index 0000000..3f04860
--- /dev/null
+++ b/internal/repl/tty_test.go
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2026 Paul Buetow
+
+package repl
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestTTYCheckerEnsureTTYNotATerminal(t *testing.T) {
+ // In test context, stdin is never a terminal
+ checker := &TTYChecker{}
+ err := checker.EnsureTTY()
+ if err == nil {
+ t.Error("EnsureTTY should return an error when stdin is not a TTY")
+ }
+}
+
+func TestTTYCheckerEnsureTTYErrorMessage(t *testing.T) {
+ checker := &TTYChecker{}
+ err := checker.EnsureTTY()
+ if err == nil {
+ t.Skip("stdin appears to be a TTY; skipping error message check")
+ }
+ if !strings.Contains(err.Error(), "TTY") {
+ t.Errorf("error message should mention TTY, got: %q", err.Error())
+ }
+}
+
+func TestTTYCheckerIsTTYReturnsFalseInTests(t *testing.T) {
+ // In test context, stdin is not a terminal
+ checker := &TTYChecker{}
+ if checker.IsTTY() {
+ t.Skip("stdin appears to be a TTY (e.g., interactive terminal); skipping")
+ }
+ // Good — IsTTY correctly returned false
+}
+
+func TestTTYCheckerIsTTYConsistentWithEnsureTTY(t *testing.T) {
+ checker := &TTYChecker{}
+ isTTY := checker.IsTTY()
+ err := checker.EnsureTTY()
+
+ if isTTY && err != nil {
+ t.Error("IsTTY returned true but EnsureTTY returned an error")
+ }
+ if !isTTY && err == nil {
+ t.Error("IsTTY returned false but EnsureTTY returned nil")
+ }
+}
+
+func TestTTYCheckerMultipleCalls(t *testing.T) {
+ checker := &TTYChecker{}
+ // Multiple calls should be consistent
+ result1 := checker.IsTTY()
+ result2 := checker.IsTTY()
+ if result1 != result2 {
+ t.Errorf("IsTTY returned inconsistent results: %v, %v", result1, result2)
+ }
+
+ err1 := checker.EnsureTTY()
+ err2 := checker.EnsureTTY()
+ // Both errors should be the same type (both nil or both non-nil)
+ bothNil := err1 == nil && err2 == nil
+ bothNonNil := err1 != nil && err2 != nil
+ if !bothNil && !bothNonNil {
+ t.Errorf("EnsureTTY returned inconsistent results: %v, %v", err1, err2)
+ }
+}