github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/tfdiags/consolidate_warnings_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package tfdiags
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/google/go-cmp/cmp"
    11  	"github.com/hashicorp/hcl/v2"
    12  )
    13  
    14  func TestConsolidateWarnings(t *testing.T) {
    15  	var diags Diagnostics
    16  
    17  	for i := 0; i < 4; i++ {
    18  		diags = diags.Append(&hcl.Diagnostic{
    19  			Severity: hcl.DiagWarning,
    20  			Summary:  "Warning 1",
    21  			Detail:   fmt.Sprintf("This one has a subject %d", i),
    22  			Subject: &hcl.Range{
    23  				Filename: "foo.tf",
    24  				Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    25  				End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    26  			},
    27  		})
    28  		diags = diags.Append(&hcl.Diagnostic{
    29  			Severity: hcl.DiagError,
    30  			Summary:  "Error 1",
    31  			Detail:   fmt.Sprintf("This one has a subject %d", i),
    32  			Subject: &hcl.Range{
    33  				Filename: "foo.tf",
    34  				Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    35  				End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    36  			},
    37  		})
    38  		diags = diags.Append(Sourceless(
    39  			Warning,
    40  			"Warning 2",
    41  			fmt.Sprintf("This one is sourceless %d", i),
    42  		))
    43  		diags = diags.Append(SimpleWarning("Warning 3"))
    44  	}
    45  
    46  	diags = diags.Append(&hcl.Diagnostic{
    47  		Severity: hcl.DiagWarning,
    48  		Summary:  "Warning 4",
    49  		Detail:   "Only one of this one",
    50  		Subject: &hcl.Range{
    51  			Filename: "foo.tf",
    52  			Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    53  			End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    54  		},
    55  	})
    56  
    57  	// Finally, we'll just add a set of diags that should not be consolidated.
    58  
    59  	diags = diags.Append(&hcl.Diagnostic{
    60  		Severity: hcl.DiagWarning,
    61  		Summary:  "do not consolidate",
    62  		Detail:   "warning 1, I should not have been consolidated",
    63  		Subject: &hcl.Range{
    64  			Filename: "bar.tf",
    65  			Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    66  			End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    67  		},
    68  		Extra: doNotConsolidate(true),
    69  	})
    70  
    71  	diags = diags.Append(&hcl.Diagnostic{
    72  		Severity: hcl.DiagWarning,
    73  		Summary:  "do not consolidate",
    74  		Detail:   "warning 2, I should not have been consolidated",
    75  		Subject: &hcl.Range{
    76  			Filename: "bar.tf",
    77  			Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    78  			End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    79  		},
    80  		Extra: doNotConsolidate(true),
    81  	})
    82  
    83  	diags = diags.Append(&hcl.Diagnostic{
    84  		Severity: hcl.DiagWarning,
    85  		Summary:  "do not consolidate",
    86  		Detail:   "warning 3, I should not have been consolidated",
    87  		Subject: &hcl.Range{
    88  			Filename: "bar.tf",
    89  			Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
    90  			End:      hcl.Pos{Line: 1, Column: 1, Byte: 0},
    91  		},
    92  		Extra: doNotConsolidate(true),
    93  	})
    94  
    95  	// We're using ForRPC here to force the diagnostics to be of a consistent
    96  	// type that we can easily assert against below.
    97  	got := diags.ConsolidateWarnings(2).ForRPC()
    98  	want := Diagnostics{
    99  		// First set
   100  		&rpcFriendlyDiag{
   101  			Severity_: Warning,
   102  			Summary_:  "Warning 1",
   103  			Detail_:   "This one has a subject 0",
   104  			Subject_: &SourceRange{
   105  				Filename: "foo.tf",
   106  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   107  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   108  			},
   109  		},
   110  		&rpcFriendlyDiag{
   111  			Severity_: Error,
   112  			Summary_:  "Error 1",
   113  			Detail_:   "This one has a subject 0",
   114  			Subject_: &SourceRange{
   115  				Filename: "foo.tf",
   116  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   117  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   118  			},
   119  		},
   120  		&rpcFriendlyDiag{
   121  			Severity_: Warning,
   122  			Summary_:  "Warning 2",
   123  			Detail_:   "This one is sourceless 0",
   124  		},
   125  		&rpcFriendlyDiag{
   126  			Severity_: Warning,
   127  			Summary_:  "Warning 3",
   128  		},
   129  
   130  		// Second set (consolidation begins; note additional paragraph in Warning 1 detail)
   131  		&rpcFriendlyDiag{
   132  			Severity_: Warning,
   133  			Summary_:  "Warning 1",
   134  			Detail_:   "This one has a subject 1\n\n(and 2 more similar warnings elsewhere)",
   135  			Subject_: &SourceRange{
   136  				Filename: "foo.tf",
   137  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   138  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   139  			},
   140  		},
   141  		&rpcFriendlyDiag{
   142  			Severity_: Error,
   143  			Summary_:  "Error 1",
   144  			Detail_:   "This one has a subject 1",
   145  			Subject_: &SourceRange{
   146  				Filename: "foo.tf",
   147  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   148  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   149  			},
   150  		},
   151  		&rpcFriendlyDiag{
   152  			Severity_: Warning,
   153  			Summary_:  "Warning 2",
   154  			Detail_:   "This one is sourceless 1",
   155  		},
   156  		&rpcFriendlyDiag{
   157  			Severity_: Warning,
   158  			Summary_:  "Warning 3",
   159  		},
   160  
   161  		// Third set (no more Warning 1, because it's consolidated)
   162  		&rpcFriendlyDiag{
   163  			Severity_: Error,
   164  			Summary_:  "Error 1",
   165  			Detail_:   "This one has a subject 2",
   166  			Subject_: &SourceRange{
   167  				Filename: "foo.tf",
   168  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   169  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   170  			},
   171  		},
   172  		&rpcFriendlyDiag{
   173  			Severity_: Warning,
   174  			Summary_:  "Warning 2",
   175  			Detail_:   "This one is sourceless 2",
   176  		},
   177  		&rpcFriendlyDiag{
   178  			Severity_: Warning,
   179  			Summary_:  "Warning 3",
   180  		},
   181  
   182  		// Fourth set (still no warning 1)
   183  		&rpcFriendlyDiag{
   184  			Severity_: Error,
   185  			Summary_:  "Error 1",
   186  			Detail_:   "This one has a subject 3",
   187  			Subject_: &SourceRange{
   188  				Filename: "foo.tf",
   189  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   190  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   191  			},
   192  		},
   193  		&rpcFriendlyDiag{
   194  			Severity_: Warning,
   195  			Summary_:  "Warning 2",
   196  			Detail_:   "This one is sourceless 3",
   197  		},
   198  		&rpcFriendlyDiag{
   199  			Severity_: Warning,
   200  			Summary_:  "Warning 3",
   201  		},
   202  
   203  		// Special straggler warning gets to show up unconsolidated, because
   204  		// there is only one of it.
   205  		&rpcFriendlyDiag{
   206  			Severity_: Warning,
   207  			Summary_:  "Warning 4",
   208  			Detail_:   "Only one of this one",
   209  			Subject_: &SourceRange{
   210  				Filename: "foo.tf",
   211  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   212  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   213  			},
   214  		},
   215  
   216  		// The final set of warnings should not have been consolidated because
   217  		// of our filter function.
   218  		&rpcFriendlyDiag{
   219  			Severity_: Warning,
   220  			Summary_:  "do not consolidate",
   221  			Detail_:   "warning 1, I should not have been consolidated",
   222  			Subject_: &SourceRange{
   223  				Filename: "bar.tf",
   224  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   225  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   226  			},
   227  		},
   228  		&rpcFriendlyDiag{
   229  			Severity_: Warning,
   230  			Summary_:  "do not consolidate",
   231  			Detail_:   "warning 2, I should not have been consolidated",
   232  			Subject_: &SourceRange{
   233  				Filename: "bar.tf",
   234  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   235  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   236  			},
   237  		},
   238  		&rpcFriendlyDiag{
   239  			Severity_: Warning,
   240  			Summary_:  "do not consolidate",
   241  			Detail_:   "warning 3, I should not have been consolidated",
   242  			Subject_: &SourceRange{
   243  				Filename: "bar.tf",
   244  				Start:    SourcePos{Line: 1, Column: 1, Byte: 0},
   245  				End:      SourcePos{Line: 1, Column: 1, Byte: 0},
   246  			},
   247  		},
   248  	}
   249  
   250  	if diff := cmp.Diff(want, got); diff != "" {
   251  		t.Errorf("wrong result\n%s", diff)
   252  	}
   253  }
   254  
   255  type doNotConsolidate bool
   256  
   257  var _ DiagnosticExtraDoNotConsolidate = doNotConsolidate(true)
   258  
   259  func (d doNotConsolidate) DoNotConsolidateDiagnostic() bool {
   260  	return bool(d)
   261  }