summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-23 22:30:01 +0200
committerPaul Buetow <paul@buetow.org>2026-03-23 22:30:01 +0200
commitbd4750a4094ba8c6cddb6559e4599df2c068ced9 (patch)
treea2f6cc7038fe495d781dfc82c1cde799d9a1ef77
parent0998f4f76fb670c741eb0951630f4f5d18dcc1e5 (diff)
Refactor calculator_test.go to eliminate duplicate test code
-rw-r--r--internal/calculator/calculator_test.go262
1 files changed, 150 insertions, 112 deletions
diff --git a/internal/calculator/calculator_test.go b/internal/calculator/calculator_test.go
index 74afdae..f78afe5 100644
--- a/internal/calculator/calculator_test.go
+++ b/internal/calculator/calculator_test.go
@@ -5,44 +5,100 @@ import (
"testing"
)
-func TestParseXPercentOfY(t *testing.T) {
- tests := []struct {
- name string
- input string
- expected string
- }{
- {
- name: "20% of 150",
- input: "20% of 150",
- expected: "20.00% of 150.00 = 30.00",
- },
- {
- name: "what is 20% of 150",
- input: "what is 20% of 150",
- expected: "20.00% of 150.00 = 30.00",
- },
- {
- name: "50% of 200",
- input: "50% of 200",
- expected: "50.00% of 200.00 = 100.00",
- },
- {
- name: "decimal percent",
- input: "12.5% of 80",
- expected: "12.50% of 80.00 = 10.00",
- },
- {
- name: "decimal base",
- input: "20% of 75.5",
- expected: "20.00% of 75.50 = 15.10",
- },
- {
- name: "without 'of'",
- input: "25% 400",
- expected: "25.00% of 400.00 = 100.00",
- },
- }
+// commonTestCases contains common test case patterns used across multiple tests
+var commonTestCases = []struct {
+ name string
+ input string
+ expected string
+}{
+ {
+ name: "20% of 150",
+ input: "20% of 150",
+ expected: "20.00% of 150.00 = 30.00",
+ },
+ {
+ name: "what is 20% of 150",
+ input: "what is 20% of 150",
+ expected: "20.00% of 150.00 = 30.00",
+ },
+ {
+ name: "50% of 200",
+ input: "50% of 200",
+ expected: "50.00% of 200.00 = 100.00",
+ },
+ {
+ name: "decimal percent",
+ input: "12.5% of 80",
+ expected: "12.50% of 80.00 = 10.00",
+ },
+ {
+ name: "decimal base",
+ input: "20% of 75.5",
+ expected: "20.00% of 75.50 = 15.10",
+ },
+ {
+ name: "without 'of'",
+ input: "25% 400",
+ expected: "25.00% of 400.00 = 100.00",
+ },
+ {
+ name: "30 is what % of 150",
+ input: "30 is what % of 150",
+ expected: "30.00 is 20.00% of 150.00",
+ },
+ {
+ name: "50 is what % of 200",
+ input: "50 is what % of 200",
+ expected: "50.00 is 25.00% of 200.00",
+ },
+ {
+ name: "decimal values",
+ input: "12.5 is what % of 50",
+ expected: "12.50 is 25.00% of 50.00",
+ },
+ {
+ name: "without spaces around %",
+ input: "75 is what% of 300",
+ expected: "75.00 is 25.00% of 300.00",
+ },
+ {
+ name: "without 'of'",
+ input: "100 is what % 400",
+ expected: "100.00 is 25.00% of 400.00",
+ },
+ {
+ name: "30 is 20% of what",
+ input: "30 is 20% of what",
+ expected: "30.00 is 20.00% of 150.00",
+ },
+ {
+ name: "50 is 25% of what",
+ input: "50 is 25% of what",
+ expected: "50.00 is 25.00% of 200.00",
+ },
+ {
+ name: "decimal values",
+ input: "15 is 30% of what",
+ expected: "15.00 is 30.00% of 50.00",
+ },
+ {
+ name: "without spaces around %",
+ input: "75 is 25% of what",
+ expected: "75.00 is 25.00% of 300.00",
+ },
+ {
+ name: "without 'of'",
+ input: "40 is 20% what",
+ expected: "40.00 is 20.00% of 200.00",
+ },
+}
+// runParseTest runs a parse test with common validation logic
+func runParseTest(t *testing.T, tests []struct {
+ name string
+ input string
+ expected string
+}) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Parse(tt.input)
@@ -59,102 +115,84 @@ func TestParseXPercentOfY(t *testing.T) {
}
}
-func TestParseXIsWhatPercentOfY(t *testing.T) {
- tests := []struct {
- name string
- input string
- expected string
- }{
- {
- name: "30 is what % of 150",
- input: "30 is what % of 150",
- expected: "30.00 is 20.00% of 150.00",
- },
- {
- name: "50 is what % of 200",
- input: "50 is what % of 200",
- expected: "50.00 is 25.00% of 200.00",
- },
- {
- name: "decimal values",
- input: "12.5 is what % of 50",
- expected: "12.50 is 25.00% of 50.00",
- },
- {
- name: "without spaces around %",
- input: "75 is what% of 300",
- expected: "75.00 is 25.00% of 300.00",
- },
- {
- name: "without 'of'",
- input: "100 is what % 400",
- expected: "100.00 is 25.00% of 400.00",
- },
+// runParseErrorTest runs a parse error test
+func runParseErrorTest(t *testing.T, tests []struct {
+ name string
+ input string
+}) {
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, err := Parse(tt.input)
+ if err == nil {
+ t.Errorf("Parse(%q) expected error, got nil", tt.input)
+ }
+ })
}
+}
+// runParseNoStepsTest runs a parse test without requiring steps
+func runParseNoStepsTest(t *testing.T, tests []struct {
+ name string
+ input string
+ expected string
+}) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Parse(tt.input)
if err != nil {
t.Fatalf("Parse(%q) returned error: %v", tt.input, err)
}
- if !strings.HasPrefix(result, tt.expected) {
- t.Errorf("Parse(%q) = %q, expected to start with %q", tt.input, result, tt.expected)
- }
- if !strings.Contains(result, "Steps:") {
- t.Errorf("Parse(%q) = %q, expected to contain calculation steps", tt.input, result)
+ if result != tt.expected {
+ t.Errorf("Parse(%q) = %q, expected %q", tt.input, result, tt.expected)
}
})
}
}
-func TestParseXIsYPercentOfWhat(t *testing.T) {
+func TestParseXPercentOfY(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
- {
- name: "30 is 20% of what",
- input: "30 is 20% of what",
- expected: "30.00 is 20.00% of 150.00",
- },
- {
- name: "50 is 25% of what",
- input: "50 is 25% of what",
- expected: "50.00 is 25.00% of 200.00",
- },
- {
- name: "decimal values",
- input: "15 is 30% of what",
- expected: "15.00 is 30.00% of 50.00",
- },
- {
- name: "without spaces around %",
- input: "75 is 25% of what",
- expected: "75.00 is 25.00% of 300.00",
- },
- {
- name: "without 'of'",
- input: "40 is 20% what",
- expected: "40.00 is 20.00% of 200.00",
- },
+ commonTestCases[0], // "20% of 150"
+ commonTestCases[1], // "what is 20% of 150"
+ commonTestCases[2], // "50% of 200"
+ commonTestCases[3], // "decimal percent"
+ commonTestCases[4], // "decimal base"
+ commonTestCases[5], // "without 'of'"
}
+ runParseTest(t, tests)
+}
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result, err := Parse(tt.input)
- if err != nil {
- t.Fatalf("Parse(%q) returned error: %v", tt.input, err)
- }
- if !strings.HasPrefix(result, tt.expected) {
- t.Errorf("Parse(%q) = %q, expected to start with %q", tt.input, result, tt.expected)
- }
- if !strings.Contains(result, "Steps:") {
- t.Errorf("Parse(%q) = %q, expected to contain calculation steps", tt.input, result)
- }
- })
+func TestParseXIsWhatPercentOfY(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ expected string
+ }{
+ commonTestCases[6], // "30 is what % of 150"
+ commonTestCases[7], // "50 is what % of 200"
+ commonTestCases[8], // "decimal values"
+ commonTestCases[9], // "without spaces around %"
+ commonTestCases[10], // "without 'of'"
+ }
+ runParseTest(t, tests)
+}
+
+func TestParseXIsYPercentOfWhat(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ expected string
+ }{
+ commonTestCases[11], // "30 is 20% of what"
+ commonTestCases[12], // "50 is 25% of what"
+ commonTestCases[13], // "decimal values"
+ commonTestCases[14], // "without spaces around %"
+ commonTestCases[15], // "without 'of'"
}
+ runParseTest(t, tests)
}
func TestParseErrors(t *testing.T) {