func TestParserLoadConfigFileError(t *testing.T) {
	files, err := ioutil.ReadDir("testdata/error-files")
	if err != nil {
		t.Fatal(err)
	}
	for _, info := range files {
		name := info.Name()
		t.Run(name, func(t *testing.T) {
			src, err := ioutil.ReadFile(filepath.Join("testdata/error-files", name))
			if err != nil {
				t.Fatal(err)
			}
			const marker = "ERROR: "
			sc := bufio.NewScanner(bytes.NewReader(src))
			wantErrors := make(map[int]string)
			lineNum := 1
			for sc.Scan() {
				lineText := sc.Text()
				if idx := strings.Index(lineText, marker); idx != -1 {
					summaryText := lineText[idx+len(marker):]
					wantErrors[lineNum] = summaryText
				}
				lineNum++
			}
			parser := testParser(map[string]string{
				name: string(src),
			})
			_, diags := parser.LoadConfigFile(name)
			gotErrors := make(map[int]string)
			for _, diag := range diags {
				if diag.Severity != hcl.DiagError || diag.Subject == nil {
					continue
				}
				gotErrors[diag.Subject.Start.Line] = diag.Summary
			}
			if diff := cmp.Diff(wantErrors, gotErrors); diff != "" {
				t.Errorf("wrong errors\n%s", diff)
			}
		})
	}
}
TestParseLoadConfigFileError is a test that verifies files from
testdata/warning-files produce particular errors.

This test does not verify that reading these files produces the correct
file element contents in spite of those errors. More detailed assertions
may be made on some subset of these configuration files in other tests.
package configs
import (
	"bufio"
	"bytes"
	"io/ioutil"
	"path/filepath"
	"strings"
	"testing"
	"github.com/google/go-cmp/cmp"
	"github.com/hashicorp/hcl/v2"
)
func TestParserLoadConfigFileSuccess(t *testing.T) {
	files, err := ioutil.ReadDir("testdata/valid-files")
	if err != nil {
		t.Fatal(err)
	}
	for _, info := range files {
		name := info.Name()
		t.Run(name, func(t *testing.T) {
			src, err := ioutil.ReadFile(filepath.Join("testdata/valid-files", name))
			if err != nil {
				t.Fatal(err)
			}
			parser := testParser(map[string]string{
				name: string(src),
			})
			_, diags := parser.LoadConfigFile(name)
			if len(diags) != 0 {
				t.Errorf("unexpected diagnostics")
				for _, diag := range diags {
					t.Logf("- %s", diag)
				}
			}
		})
	}
}
func TestParserLoadConfigFileFailure(t *testing.T) {
	files, err := ioutil.ReadDir("testdata/invalid-files")
	if err != nil {
		t.Fatal(err)
	}
	for _, info := range files {
		name := info.Name()
		t.Run(name, func(t *testing.T) {
			src, err := ioutil.ReadFile(filepath.Join("testdata/invalid-files", name))
			if err != nil {
				t.Fatal(err)
			}
			parser := testParser(map[string]string{
				name: string(src),
			})
			_, diags := parser.LoadConfigFile(name)
			if !diags.HasErrors() {
				t.Errorf("LoadConfigFile succeeded; want errors")
			}
			for _, diag := range diags {
				t.Logf("- %s", diag)
			}
		})
	}
}
func TestParserLoadConfigFileFailureMessages(t *testing.T) {
	tests := []struct {
		Filename     string
		WantSeverity hcl.DiagnosticSeverity
		WantDiag     string
	}{
		{
			"invalid-files/data-resource-lifecycle.tf",
			hcl.DiagError,
			"Unsupported lifecycle block",
		},
		{
			"invalid-files/variable-type-unknown.tf",
			hcl.DiagError,
			"Invalid type specification",
		},
		{
			"invalid-files/unexpected-attr.tf",
			hcl.DiagError,
			"Unsupported argument",
		},
		{
			"invalid-files/unexpected-block.tf",
			hcl.DiagError,
			"Unsupported block type",
		},
		{
			"invalid-files/resource-count-and-for_each.tf",
			hcl.DiagError,
			`Invalid combination of "count" and "for_each"`,
		},
		{
			"invalid-files/data-count-and-for_each.tf",
			hcl.DiagError,
			`Invalid combination of "count" and "for_each"`,
		},
		{
			"invalid-files/resource-lifecycle-badbool.tf",
			hcl.DiagError,
			"Unsuitable value type",
		},
	}
	for _, test := range tests {
		t.Run(test.Filename, func(t *testing.T) {
			src, err := ioutil.ReadFile(filepath.Join("testdata", test.Filename))
			if err != nil {
				t.Fatal(err)
			}
			parser := testParser(map[string]string{
				test.Filename: string(src),
			})
			_, diags := parser.LoadConfigFile(test.Filename)
			if len(diags) != 1 {
				t.Errorf("Wrong number of diagnostics %d; want 1", len(diags))
				for _, diag := range diags {
					t.Logf("- %s", diag)
				}
				return
			}
			if diags[0].Severity != test.WantSeverity {
				t.Errorf("Wrong diagnostic severity %#v; want %#v", diags[0].Severity, test.WantSeverity)
			}
			if diags[0].Summary != test.WantDiag {
				t.Errorf("Wrong diagnostic summary\ngot:  %s\nwant: %s", diags[0].Summary, test.WantDiag)
			}
		})
	}
}
func TestParserLoadConfigFileWarning(t *testing.T) {
	files, err := ioutil.ReadDir("testdata/warning-files")
	if err != nil {
		t.Fatal(err)
	}
	for _, info := range files {
		name := info.Name()
		t.Run(name, func(t *testing.T) {
			src, err := ioutil.ReadFile(filepath.Join("testdata/warning-files", name))
			if err != nil {
				t.Fatal(err)
			}
			const marker = "WARNING: "
			sc := bufio.NewScanner(bytes.NewReader(src))
			wantWarnings := make(map[int]string)
			lineNum := 1
			for sc.Scan() {
				lineText := sc.Text()
				if idx := strings.Index(lineText, marker); idx != -1 {
					summaryText := lineText[idx+len(marker):]
					wantWarnings[lineNum] = summaryText
				}
				lineNum++
			}
			parser := testParser(map[string]string{
				name: string(src),
			})
			_, diags := parser.LoadConfigFile(name)
			if diags.HasErrors() {
				t.Errorf("unexpected error diagnostics")
				for _, diag := range diags {
					t.Logf("- %s", diag)
				}
			}
			gotWarnings := make(map[int]string)
			for _, diag := range diags {
				if diag.Severity != hcl.DiagWarning || diag.Subject == nil {
					continue
				}
				gotWarnings[diag.Subject.Start.Line] = diag.Summary
			}
			if diff := cmp.Diff(wantWarnings, gotWarnings); diff != "" {
				t.Errorf("wrong warnings\n%s", diff)
			}
		})
	}
}