diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-23 22:30:01 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-23 22:30:01 +0200 |
| commit | bd4750a4094ba8c6cddb6559e4599df2c068ced9 (patch) | |
| tree | a2f6cc7038fe495d781dfc82c1cde799d9a1ef77 | |
| parent | 0998f4f76fb670c741eb0951630f4f5d18dcc1e5 (diff) | |
Refactor calculator_test.go to eliminate duplicate test code
| -rw-r--r-- | internal/calculator/calculator_test.go | 262 |
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) { |
