| package hcl |
| |
| import ( |
| "bytes" |
| "fmt" |
| "testing" |
| |
| "github.com/zclconf/go-cty/cty" |
| ) |
| |
| func TestDiagnosticTextWriter(t *testing.T) { |
| tests := []struct { |
| Input *Diagnostic |
| Want string |
| }{ |
| { |
| &Diagnostic{ |
| Severity: DiagError, |
| Summary: "Splines not reticulated", |
| Detail: "All splines must be pre-reticulated.", |
| Subject: &Range{ |
| Start: Pos{ |
| Byte: 0, |
| Column: 1, |
| Line: 1, |
| }, |
| End: Pos{ |
| Byte: 3, |
| Column: 4, |
| Line: 1, |
| }, |
| }, |
| }, |
| `Error: Splines not reticulated |
| |
| on line 1, in hardcoded-context: |
| 1: foo = 1 |
| |
| All splines must be pre-reticulated. |
| |
| `, |
| }, |
| { |
| &Diagnostic{ |
| Severity: DiagError, |
| Summary: "Unsupported attribute", |
| Detail: `"baz" is not a supported top-level attribute. Did you mean "bam"?`, |
| Subject: &Range{ |
| Start: Pos{ |
| Byte: 16, |
| Column: 1, |
| Line: 3, |
| }, |
| End: Pos{ |
| Byte: 19, |
| Column: 4, |
| Line: 3, |
| }, |
| }, |
| }, |
| `Error: Unsupported attribute |
| |
| on line 3, in hardcoded-context: |
| 3: baz = 3 |
| |
| "baz" is not a supported top-level |
| attribute. Did you mean "bam"? |
| |
| `, |
| }, |
| { |
| &Diagnostic{ |
| Severity: DiagError, |
| Summary: "Unsupported attribute", |
| Detail: `"pizza" is not a supported attribute. Did you mean "pizzetta"?`, |
| Subject: &Range{ |
| Start: Pos{ |
| Byte: 42, |
| Column: 3, |
| Line: 5, |
| }, |
| End: Pos{ |
| Byte: 47, |
| Column: 8, |
| Line: 5, |
| }, |
| }, |
| // This is actually not a great example of a context, but is here to test |
| // whether we're able to show a multi-line context when needed. |
| Context: &Range{ |
| Start: Pos{ |
| Byte: 24, |
| Column: 1, |
| Line: 4, |
| }, |
| End: Pos{ |
| Byte: 60, |
| Column: 2, |
| Line: 6, |
| }, |
| }, |
| }, |
| `Error: Unsupported attribute |
| |
| on line 5, in hardcoded-context: |
| 4: block "party" { |
| 5: pizza = "cheese" |
| 6: } |
| |
| "pizza" is not a supported attribute. |
| Did you mean "pizzetta"? |
| |
| `, |
| }, |
| { |
| &Diagnostic{ |
| Severity: DiagError, |
| Summary: "Test of including relevant variable values", |
| Detail: `This diagnostic includes an expression and an evalcontext.`, |
| Subject: &Range{ |
| Start: Pos{ |
| Byte: 42, |
| Column: 3, |
| Line: 5, |
| }, |
| End: Pos{ |
| Byte: 47, |
| Column: 8, |
| Line: 5, |
| }, |
| }, |
| Expression: &diagnosticTestExpr{ |
| vars: []Traversal{ |
| { |
| TraverseRoot{ |
| Name: "foo", |
| }, |
| }, |
| { |
| TraverseRoot{ |
| Name: "bar", |
| }, |
| TraverseAttr{ |
| Name: "baz", |
| }, |
| }, |
| { |
| TraverseRoot{ |
| Name: "missing", |
| }, |
| }, |
| { |
| TraverseRoot{ |
| Name: "boz", |
| }, |
| }, |
| }, |
| }, |
| EvalContext: &EvalContext{ |
| parent: &EvalContext{ |
| Variables: map[string]cty.Value{ |
| "foo": cty.StringVal("foo value"), |
| }, |
| }, |
| Variables: map[string]cty.Value{ |
| "bar": cty.ObjectVal(map[string]cty.Value{ |
| "baz": cty.ListValEmpty(cty.String), |
| }), |
| "boz": cty.NumberIntVal(5), |
| "unused": cty.True, |
| }, |
| }, |
| }, |
| `Error: Test of including relevant variable values |
| |
| on line 5, in hardcoded-context: |
| 5: pizza = "cheese" |
| |
| with bar.baz as empty list of string, |
| boz as 5, |
| foo as "foo value". |
| |
| This diagnostic includes an expression |
| and an evalcontext. |
| |
| `, |
| }, |
| } |
| |
| files := map[string]*File{ |
| "": &File{ |
| Bytes: []byte(testDiagnosticTextWriterSource), |
| Nav: &diagnosticTestNav{}, |
| }, |
| } |
| |
| for i, test := range tests { |
| t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) { |
| bwr := &bytes.Buffer{} |
| dwr := NewDiagnosticTextWriter(bwr, files, 40, false) |
| err := dwr.WriteDiagnostic(test.Input) |
| if err != nil { |
| t.Fatalf("unexpected error: %s", err) |
| } |
| got := bwr.String() |
| if got != test.Want { |
| t.Errorf("wrong result\n\ngot:\n%swant:\n%s", got, test.Want) |
| } |
| }) |
| } |
| } |
| |
| const testDiagnosticTextWriterSource = `foo = 1 |
| bar = 2 |
| baz = 3 |
| block "party" { |
| pizza = "cheese" |
| } |
| ` |
| |
| type diagnosticTestNav struct { |
| } |
| |
| func (tn *diagnosticTestNav) ContextString(offset int) string { |
| return "hardcoded-context" |
| } |
| |
| type diagnosticTestExpr struct { |
| vars []Traversal |
| staticExpr |
| } |
| |
| func (e *diagnosticTestExpr) Variables() []Traversal { |
| return e.vars |
| } |