File: parse_test.go

package info (click to toggle)
golang-github-hashicorp-terraform-json 0.5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,572 kB
  • sloc: makefile: 31
file content (103 lines) | stat: -rw-r--r-- 2,109 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package tfjson

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
)

const testFixtureDir = "testdata"
const testGoldenPlanFileName = "plan.json"
const testGoldenSchemasFileName = "schemas.json"

func testParse(t *testing.T, filename string, typ reflect.Type) {
	entries, err := ioutil.ReadDir(testFixtureDir)
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	for _, e := range entries {
		if !e.IsDir() {
			continue
		}

		t.Run(e.Name(), func(t *testing.T) {
			expected, err := ioutil.ReadFile(filepath.Join(testFixtureDir, e.Name(), filename))
			if err != nil {
				t.Fatal(err)
			}

			parsed := reflect.New(typ).Interface()
			dec := json.NewDecoder(bytes.NewBuffer(expected))
			dec.DisallowUnknownFields()
			if err = dec.Decode(parsed); err != nil {
				t.Fatal(err)
			}

			actual, err := json.Marshal(parsed)
			if err != nil {
				t.Fatal(err)
			}

			// Add a newline at the end
			actual = append(actual, byte('\n'))

			if err := testDiff(actual, expected); err != nil {
				t.Fatal(err)
			}
		})
	}
}

func TestParsePlan(t *testing.T) {
	testParse(t, testGoldenPlanFileName, reflect.TypeOf(Plan{}))
}

func TestParseSchemas(t *testing.T) {
	testParse(t, testGoldenSchemasFileName, reflect.TypeOf(ProviderSchemas{}))
}

func testDiff(out, gld []byte) error {
	var b strings.Builder // holding long error message

	// compare lengths
	if len(out) != len(gld) {
		fmt.Fprintf(&b, "\nlength changed: len(output) = %d, len(golden) = %d", len(out), len(gld))
	}

	// compare contents
	line := 1
	offs := 1
	for i := 0; i < len(out) && i < len(gld); i++ {
		ch := out[i]
		if ch != gld[i] {
			fmt.Fprintf(&b, "\noutput:%d:%d: %s", line, i-offs+1, lineAt(out, offs))
			fmt.Fprintf(&b, "\ngolden:%d:%d: %s", line, i-offs+1, lineAt(gld, offs))
			fmt.Fprintf(&b, "\n\n")
			break
		}
		if ch == '\n' {
			line++
			offs = i + 1
		}
	}

	if b.Len() > 0 {
		return errors.New(b.String())
	}
	return nil
}

func lineAt(text []byte, offs int) []byte {
	i := offs
	for i < len(text) && text[i] != '\n' {
		i++
	}
	return text[offs:i]
}