blob: d3f08fd97d52024c94e0e24dc62edb10d7837210 [file] [log] [blame]
Marcel van Lohuizenb9b62d32019-03-14 23:50:15 +01001// Copyright 2019 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cue
16
17import (
18 "fmt"
19 "reflect"
20 "strings"
21 "testing"
22
23 "cuelang.org/go/cue/ast"
24)
25
26func TestAttributeBody(t *testing.T) {
27 testdata := []struct {
28 in, out string
29 err string
30 }{{
31 in: "",
32 out: "[{ 0}]",
33 }, {
34 in: "bb",
35 out: "[{bb 0}]",
36 }, {
37 in: "a,",
38 out: "[{a 0} { 0}]",
39 }, {
40 in: "a,b",
41 out: "[{a 0} {b 0}]",
42 }, {
43 in: `foo,"bar",#"baz"#`,
44 out: "[{foo 0} {bar 0} {baz 0}]",
45 }, {
46 in: `bar=str`,
47 out: "[{bar=str 3}]",
48 }, {
49 in: `bar="str"`,
50 out: "[{bar=str 3}]",
51 }, {
52 in: `bar=,baz=`,
53 out: "[{bar= 3} {baz= 3}]",
54 }, {
55 in: `foo=1,bar="str",baz=free form`,
56 out: "[{foo=1 3} {bar=str 3} {baz=free form 3}]",
57 }, {
58 in: `"""
59 """`,
60 out: "[{ 0}]",
61 }, {
62 in: `#'''
63 \#x20
64 '''#`,
65 out: "[{ 0}]",
66 }, {
67 in: "'' ,b",
68 err: "invalid attribute",
69 }, {
70 in: "' ,b",
71 err: "not terminated",
72 }, {
73 in: `"\ "`,
74 err: "invalid attribute",
75 }, {
76 in: `# `,
77 err: "invalid attribute",
78 }}
79 for _, tc := range testdata {
80 t.Run(tc.in, func(t *testing.T) {
81 pa := &parsedAttr{}
82 err := parseAttrBody(&context{}, baseValue{}, tc.in, pa)
83
84 if tc.err != "" {
85 if !strings.Contains(debugStr(&context{}, err), tc.err) {
86 t.Errorf("error was %v; want %v", err, tc.err)
87 }
88 return
89 }
90 if err != nil {
91 t.Fatal(err)
92 }
93
94 if got := fmt.Sprint(pa.fields); got != tc.out {
95 t.Errorf("got %v; want %v", got, tc.out)
96 }
97 })
98 }
99}
100
101func TestCreateAttrs(t *testing.T) {
102 testdata := []struct {
103 // space-separated lists of attributes
104 in, out string
105 err string
106 }{{
107 in: "@foo()",
108 out: "foo:",
109 }, {
110 in: "@b(bb) @aaa(aa,)",
111 out: "aaa:aa, b:bb",
112 }, {
113 in: "@b(a,",
114 err: "invalid attribute",
115 }, {
116 in: "@b(foo) @b(foo)",
117 err: "attributes",
118 }, {
119 in: "@b('' ,b)",
120 err: "invalid attribute",
121 }}
122 for _, tc := range testdata {
123 t.Run(tc.in, func(t *testing.T) {
124 a := []*ast.Attribute{}
125 for _, s := range strings.Split(tc.in, " ") {
126 a = append(a, &ast.Attribute{Text: s})
127 }
128 attrs, err := createAttrs(&context{}, baseValue{}, a)
129
130 if tc.err != "" {
131 if !strings.Contains(debugStr(&context{}, err), tc.err) {
132 t.Errorf("error was %v; want %v", err, tc.err)
133 }
134 return
135 }
136 if err != nil {
137 t.Fatal(err)
138 }
139 sa := []string{}
140 for _, a := range attrs.attr {
141 sa = append(sa, a.key()+":"+a.body())
142 }
143 if got := strings.Join(sa, " "); got != tc.out {
144 t.Errorf("got %v; want %v", got, tc.out)
145 }
146 })
147 }
148}
149
150func TestUnifyAttrs(t *testing.T) {
151 parse := func(s string) *attributes {
152 a := []*ast.Attribute{}
153 for _, s := range strings.Split(s, " ") {
154 a = append(a, &ast.Attribute{Text: s})
155 }
156 attrs, _ := createAttrs(&context{}, baseValue{}, a)
157 return attrs
158 }
159 foo := parse("@foo()")
160
161 testdata := []struct {
162 // space-separated lists of attributes
163 a, b, out *attributes
164 err string
165 }{{
166 a: nil,
167 b: nil,
168 out: nil,
169 }, {
170 a: nil,
171 b: foo,
172 out: foo,
173 }, {
174 a: foo,
175 b: nil,
176 out: foo,
177 }, {
178 a: foo,
179 b: foo,
180 out: foo,
181 }, {
182 a: foo,
183 b: parse("@bar()"),
184 out: parse("@bar() @foo()"),
185 }, {
186 a: foo,
187 b: parse("@bar() @foo()"),
188 out: parse("@bar() @foo()"),
189 }, {
190 a: parse("@bar() @foo()"),
191 b: parse("@foo() @bar()"),
192 out: parse("@bar() @foo()"),
193 }, {
194 a: parse("@bar() @foo()"),
195 b: parse("@foo() @baz()"),
196 out: parse("@bar() @baz() @foo()"),
197 }, {
198 a: parse("@foo(ab)"),
199 b: parse("@foo(cd)"),
200 err: `conflicting attributes for key "foo"`,
201 }}
202 for _, tc := range testdata {
203 t.Run("", func(t *testing.T) {
204 attrs, err := unifyAttrs(&context{}, baseValue{}, tc.a, tc.b)
205 if tc.err != "" {
206 if !strings.Contains(debugStr(&context{}, err), tc.err) {
207 t.Errorf("error was %v; want %v", err, tc.err)
208 }
209 return
210 }
211 if err != nil {
212 t.Fatal(err)
213 }
214 if !reflect.DeepEqual(attrs, tc.out) {
215 t.Errorf("\ngot: %v;\nwant: %v", attrs, tc.out)
216 }
217 })
218 }
219}