1
2
3
4
5 package unify
6
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "os"
12 "path/filepath"
13 "slices"
14 "strings"
15 "testing"
16
17 "gopkg.in/yaml.v3"
18 )
19
20 func TestUnify(t *testing.T) {
21 paths, err := filepath.Glob("testdata/*")
22 if err != nil {
23 t.Fatal(err)
24 }
25 if len(paths) == 0 {
26 t.Fatal("no testdata found")
27 }
28 for _, path := range paths {
29
30 base := filepath.Base(path)
31 if base[0] == '_' {
32 continue
33 }
34 if !strings.HasSuffix(base, ".yaml") {
35 t.Errorf("non-.yaml file in testdata: %s", base)
36 continue
37 }
38 base = strings.TrimSuffix(base, ".yaml")
39
40 t.Run(base, func(t *testing.T) {
41 testUnify(t, path)
42 })
43 }
44 }
45
46 func testUnify(t *testing.T, path string) {
47 f, err := os.Open(path)
48 if err != nil {
49 t.Fatal(err)
50 }
51 defer f.Close()
52
53 type testCase struct {
54 Skip bool
55 Name string
56 Unify []Closure
57 Want yaml.Node
58 All yaml.Node
59 }
60 dec := yaml.NewDecoder(f)
61
62 for i := 0; ; i++ {
63 var tc testCase
64 err := dec.Decode(&tc)
65 if err == io.EOF {
66 break
67 }
68 if err != nil {
69 t.Fatal(err)
70 }
71
72 name := tc.Name
73 if name == "" {
74 name = fmt.Sprint(i)
75 }
76
77 t.Run(name, func(t *testing.T) {
78 if tc.Skip {
79 t.Skip("skip: true set in test case")
80 }
81
82 defer func() {
83 p := recover()
84 if p != nil || t.Failed() {
85
86
87
88 var buf bytes.Buffer
89 Debug.UnifyLog = &buf
90 func() {
91 defer func() {
92
93
94
95 recover()
96 }()
97 Unify(tc.Unify...)
98 }()
99 Debug.UnifyLog = nil
100 t.Logf("Trace:\n%s", buf.String())
101 }
102 if p != nil {
103 panic(p)
104 }
105 }()
106
107
108
109
110 c, err := Unify(tc.Unify...)
111 if err != nil {
112
113 t.Fatal(err)
114 }
115
116
117
118 clean := func(val any) *yaml.Node {
119 var node yaml.Node
120 node.Encode(val)
121 for n := range allYamlNodes(&node) {
122
123
124 n.Style &^= yaml.FlowStyle
125 n.HeadComment = ""
126 n.LineComment = ""
127 n.FootComment = ""
128 }
129 return &node
130 }
131 check := func(gotVal any, wantNode *yaml.Node) {
132 got, err := yaml.Marshal(clean(gotVal))
133 if err != nil {
134 t.Fatalf("Encoding Value back to yaml failed: %s", err)
135 }
136 want, err := yaml.Marshal(clean(wantNode))
137 if err != nil {
138 t.Fatalf("Encoding Want back to yaml failed: %s", err)
139 }
140
141 if !bytes.Equal(got, want) {
142 t.Errorf("%s:%d:\nwant:\n%sgot\n%s", f.Name(), wantNode.Line, want, got)
143 }
144 }
145 if tc.Want.Kind != 0 {
146 check(c.val, &tc.Want)
147 }
148 if tc.All.Kind != 0 {
149 fVal := slices.Collect(c.All())
150 check(fVal, &tc.All)
151 }
152 })
153 }
154 }
155
View as plain text