Table-Driven Tests with Subtests and t.Run

Write table-driven Go tests that use subtests, parallel execution, and a shared example for email normalization cases.

GoData Integrity

Code

snippet
package main

import (
	"fmt"
	"strings"
	"testing"
)

func normalizeEmail(raw string) (string, error) {
	email := strings.TrimSpace(strings.ToLower(raw))
	at := strings.IndexByte(email, '@')
	if at <= 0 || at == len(email)-1 || strings.Count(email, "@") != 1 {
		return "", fmt.Errorf("invalid email %q", raw)
	}
	return email, nil
}

func TestNormalizeEmail(t *testing.T) {
	t.Parallel()
	cases := []struct {
		name    string
		input   string
		want    string
		wantErr bool
	}{
		{"lowercases and trims", "  [email protected] ", "[email protected]", false},
		{"rejects missing at", "ada.example.com", "", true},
		{"rejects empty local part", "@example.com", "", true},
		{"rejects double at", "ada@@example.com", "", true},
	}

	for _, testCase := range cases {
		testCase := testCase
		t.Run(testCase.name, func(t *testing.T) {
			t.Parallel()
			got, err := normalizeEmail(testCase.input)
			if testCase.wantErr {
				if err == nil {
					t.Fatalf("expected error, got %q", got)
				}
				return
			}
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if got != testCase.want {
				t.Fatalf("got %q, want %q", got, testCase.want)
			}
		})
	}
}

func ExampleNormalizeEmail() {
	email, _ := normalizeEmail("  [email protected] ")
	fmt.Println(email)
	// Output: [email protected]
}