diff --git a/internal/display/formatter.go b/internal/display/formatter.go index 7208083..83198ec 100644 --- a/internal/display/formatter.go +++ b/internal/display/formatter.go @@ -2,15 +2,32 @@ package display import ( "fmt" + "strings" "time" ) // FormatCurrency formats a float as currency with comma separators func FormatCurrency(amount float64) string { + sign := "" if amount < 0 { - return fmt.Sprintf("-$%.2f", -amount) + sign = "-" + amount = -amount } - return fmt.Sprintf("$%.2f", amount) + + formatted := fmt.Sprintf("%.2f", amount) + parts := strings.Split(formatted, ".") + intPart := parts[0] + decimalPart := parts[1] + + var withCommas strings.Builder + for i, digit := range intPart { + if i > 0 && (len(intPart)-i)%3 == 0 { + withCommas.WriteByte(',') + } + withCommas.WriteRune(digit) + } + + return fmt.Sprintf("%s$%s.%s", sign, withCommas.String(), decimalPart) } // FormatPercent formats a float as a percentage diff --git a/internal/display/formatter_test.go b/internal/display/formatter_test.go new file mode 100644 index 0000000..d41ad9e --- /dev/null +++ b/internal/display/formatter_test.go @@ -0,0 +1,25 @@ +package display + +import ( + "fmt" + "testing" +) + +func TestFormatCurrencyAddsCommas(t *testing.T) { + tests := []struct { + amount float64 + want string + }{ + {1234.56, "$1,234.56"}, + {9876543.2, "$9,876,543.20"}, + {-1200.5, "-$1,200.50"}, + } + + for _, tt := range tests { + t.Run(fmt.Sprintf("%v", tt.amount), func(t *testing.T) { + if got := FormatCurrency(tt.amount); got != tt.want { + t.Fatalf("FormatCurrency(%v) = %q, want %q", tt.amount, got, tt.want) + } + }) + } +}