diff --git a/.changelog/392.txt b/.changelog/392.txt new file mode 100644 index 000000000..88e2e72bd --- /dev/null +++ b/.changelog/392.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +diag: `ErrorsCount`, `WarningsCount`, `Errors` and `Warnings` functions have been added to `diag.Diagnostics` +``` diff --git a/diag/diagnostics.go b/diag/diagnostics.go index 1d42df718..b0e333326 100644 --- a/diag/diagnostics.go +++ b/diag/diagnostics.go @@ -70,3 +70,39 @@ func (diags Diagnostics) HasError() bool { return false } + +// ErrorsCount returns the number of Diagnostic in Diagnostics that are SeverityError. +func (diags Diagnostics) ErrorsCount() int { + return len(diags.Errors()) +} + +// WarningsCount returns the number of Diagnostic in Diagnostics that are SeverityWarning. +func (diags Diagnostics) WarningsCount() int { + return len(diags.Warnings()) +} + +// Errors returns all the Diagnostic in Diagnostics that are SeverityError. +func (diags Diagnostics) Errors() Diagnostics { + dd := Diagnostics{} + + for _, d := range diags { + if SeverityError == d.Severity() { + dd = append(dd, d) + } + } + + return dd +} + +// Warnings returns all the Diagnostic in Diagnostics that are SeverityWarning. +func (diags Diagnostics) Warnings() Diagnostics { + dd := Diagnostics{} + + for _, d := range diags { + if SeverityWarning == d.Severity() { + dd = append(dd, d) + } + } + + return dd +} diff --git a/diag/diagnostics_test.go b/diag/diagnostics_test.go index 9b9ebb989..cdc58fcf5 100644 --- a/diag/diagnostics_test.go +++ b/diag/diagnostics_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" ) @@ -518,3 +519,179 @@ func TestDiagnosticsHasError(t *testing.T) { }) } } + +func TestDiagnosticsErrorsCount(t *testing.T) { + t.Parallel() + + type testCase struct { + diags diag.Diagnostics + expected int + } + tests := map[string]testCase{ + "nil": { + diags: nil, + expected: 0, + }, + "empty": { + diags: diag.Diagnostics{}, + expected: 0, + }, + "errors": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + expected: 1, + }, + "warnings": { + diags: diag.Diagnostics{ + diag.NewWarningDiagnostic("Error Summary", "Error detail."), + }, + expected: 0, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + got := test.diags.ErrorsCount() + + if diff := cmp.Diff(test.expected, got); diff != "" { + t.Fatalf("expected: %q, got: %q", test.expected, got) + } + }) + } +} + +func TestDiagnosticsWarningsCount(t *testing.T) { + t.Parallel() + + type testCase struct { + diags diag.Diagnostics + expected int + } + tests := map[string]testCase{ + "nil": { + diags: nil, + expected: 0, + }, + "empty": { + diags: diag.Diagnostics{}, + expected: 0, + }, + "errors": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + expected: 1, + }, + "warnings": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + }, + expected: 0, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + got := test.diags.WarningsCount() + + if diff := cmp.Diff(test.expected, got); diff != "" { + t.Fatalf("expected: %q, got: %q", test.expected, got) + } + }) + } +} + +func TestDiagnosticsErrors(t *testing.T) { + t.Parallel() + + type testCase struct { + diags diag.Diagnostics + expected diag.Diagnostics + } + tests := map[string]testCase{ + "nil": { + diags: nil, + expected: diag.Diagnostics{}, + }, + "empty": { + diags: diag.Diagnostics{}, + expected: diag.Diagnostics{}, + }, + "errors": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + expected: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + }, + }, + "warnings": { + diags: diag.Diagnostics{ + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + expected: diag.Diagnostics{}, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + got := test.diags.Errors() + + if diff := cmp.Diff(test.expected, got); diff != "" { + t.Fatalf("expected: %q, got: %q", test.expected, got) + } + }) + } +} + +func TestDiagnosticsWarnings(t *testing.T) { + t.Parallel() + + type testCase struct { + diags diag.Diagnostics + expected diag.Diagnostics + } + tests := map[string]testCase{ + "nil": { + diags: nil, + expected: diag.Diagnostics{}, + }, + "empty": { + diags: diag.Diagnostics{}, + expected: diag.Diagnostics{}, + }, + "errors": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + }, + expected: diag.Diagnostics{}, + }, + "warnings": { + diags: diag.Diagnostics{ + diag.NewErrorDiagnostic("Error Summary", "Error detail."), + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + expected: diag.Diagnostics{ + diag.NewWarningDiagnostic("Warning Summary", "Warning detail."), + }, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + got := test.diags.Warnings() + + if diff := cmp.Diff(test.expected, got); diff != "" { + t.Fatalf("expected: %q, got: %q", test.expected, got) + } + }) + } +}