summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-20 21:47:41 +0200
committerPaul Buetow <paul@buetow.org>2026-03-20 21:47:41 +0200
commit0363262a55b8a07d0fa96e6158d61a782a843ca0 (patch)
tree6642d94be478a0a42c815ab9ce7381c131ca95f0 /internal
parent4668cc8462876c6878f45b334d012a0d7a346762 (diff)
cmd/perc: add unit tests with 86% coverage
- 21 test functions covering version, calc, rpn subcommands - Tests for assignment, percentage calculations, error handling, repl mode - Coverage: runCommand 91.7%, runRPN 100%, printUsage 100%
Diffstat (limited to 'internal')
-rw-r--r--internal/repl/commands_test.go41
-rw-r--r--internal/repl/repl_test.go112
2 files changed, 153 insertions, 0 deletions
diff --git a/internal/repl/commands_test.go b/internal/repl/commands_test.go
index 7a37579..90fa3e8 100644
--- a/internal/repl/commands_test.go
+++ b/internal/repl/commands_test.go
@@ -5,6 +5,47 @@ import (
"testing"
)
+func TestCommands(t *testing.T) {
+ cmds := Commands()
+ if len(cmds) == 0 {
+ t.Error("Commands() should return at least one command")
+ }
+}
+
+func TestExecuteCommandRPN(t *testing.T) {
+ _, err := ExecuteCommand("rpn")
+ if err != nil {
+ t.Fatalf("ExecuteCommand('rpn') returned error: %v", err)
+ }
+}
+
+func TestExecuteCommandCalc(t *testing.T) {
+ _, err := ExecuteCommand("calc")
+ if err != nil {
+ t.Fatalf("ExecuteCommand('calc') returned error: %v", err)
+ }
+}
+
+func TestExecuteCommandHelpWithUnknownSubcommand(t *testing.T) {
+ output, err := ExecuteCommand("help unknown")
+ if err != nil {
+ t.Fatalf("ExecuteCommand('help unknown') returned error: %v", err)
+ }
+ if !strings.Contains(output, "No help available") {
+ t.Errorf("ExecuteCommand('help unknown') should mention 'No help available', got: %s", output[:50])
+ }
+}
+
+func TestExecuteCommandHelpForHelp(t *testing.T) {
+ output, err := ExecuteCommand("help help")
+ if err != nil {
+ t.Fatalf("ExecuteCommand('help help') returned error: %v", err)
+ }
+ if !strings.Contains(output, "help") {
+ t.Errorf("ExecuteCommand('help help') output should contain 'help', got: %s", output[:50])
+ }
+}
+
func TestExecuteCommandHelp(t *testing.T) {
output, err := ExecuteCommand("help")
if err != nil {
diff --git a/internal/repl/repl_test.go b/internal/repl/repl_test.go
new file mode 100644
index 0000000..53a707a
--- /dev/null
+++ b/internal/repl/repl_test.go
@@ -0,0 +1,112 @@
+package repl
+
+import (
+ "testing"
+
+ "github.com/c-bata/go-prompt"
+)
+
+func TestExecutor(t *testing.T) {
+ // Test that executor doesn't panic on empty input
+ executor("")
+}
+
+func TestExecutorWithHelp(t *testing.T) {
+ // Test executor with help command
+ // This should execute the help command and not print output
+ executor("help")
+}
+
+func TestExecutorWithClear(t *testing.T) {
+ executor("clear")
+}
+
+func TestExecutorWithQuit(t *testing.T) {
+ // This should exit REPL but we can't test the actual exit
+ // We just verify the command is processed without error
+ executor("quit")
+}
+
+func TestExecutorWithExit(t *testing.T) {
+ executor("exit")
+}
+
+func TestExecutorWithPercentage(t *testing.T) {
+ // Test executor with a percentage calculation
+ // Note: output is printed to stdout, we just verify it doesn't panic
+ executor("20% of 150")
+}
+
+func TestExecutorWithRPN(t *testing.T) {
+ // Test executor with RPN command
+ executor("rpn 3 4 +")
+}
+
+func TestExecutorWithInvalid(t *testing.T) {
+ // Test executor with invalid input
+ executor("invalid input")
+}
+
+// Note: captureOutput is removed - we test for side effects instead of capturing output
+
+func TestExecutorWithVars(t *testing.T) {
+ executor("rpn x 5 = vars")
+}
+
+func TestExecutorWithClearVariables(t *testing.T) {
+ executor("rpn clear")
+}
+
+func TestIsBuiltinCommand(t *testing.T) {
+ // Test known built-in commands
+ tests := []struct {
+ input string
+ expected bool
+ }{
+ {"help", true},
+ {"clear", true},
+ {"quit", true},
+ {"exit", true},
+ {"rpn", true},
+ {"calc", true},
+ {"20% of 150", false},
+ {"invalid", false},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.input, func(t *testing.T) {
+ _, ok := isBuiltinCommand(tt.input)
+ if ok != tt.expected {
+ t.Errorf("isBuiltinCommand(%q) = %v, want %v", tt.input, ok, tt.expected)
+ }
+ })
+ }
+}
+
+func TestIsBuiltinCommandWithSubcommand(t *testing.T) {
+ // Test with help subcommands
+ _, ok := isBuiltinCommand("help clear")
+ if !ok {
+ t.Error("isBuiltinCommand('help clear') should return true")
+ }
+}
+
+func TestCompleter(t *testing.T) {
+ // Test completer with empty input
+ suggestions := completer(prompt.Document{})
+ // completer returns suggestions for builtin commands
+ // We just verify it doesn't panic
+ _ = suggestions
+}
+
+func TestCompleterWithPartialMatch(t *testing.T) {
+ // Test completer with partial command
+ suggestions := completer(prompt.Document{Text: "h"})
+ // completer returns suggestions for builtin commands
+ _ = suggestions
+}
+
+func TestCompleterWithClearPrefix(t *testing.T) {
+ suggestions := completer(prompt.Document{Text: "cl"})
+ _ = suggestions
+}