diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-20 21:47:41 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-20 21:47:41 +0200 |
| commit | 0363262a55b8a07d0fa96e6158d61a782a843ca0 (patch) | |
| tree | 6642d94be478a0a42c815ab9ce7381c131ca95f0 /internal | |
| parent | 4668cc8462876c6878f45b334d012a0d7a346762 (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.go | 41 | ||||
| -rw-r--r-- | internal/repl/repl_test.go | 112 |
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 +} |
