1// Copyright 2019 Istio 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 constraint 16 17import ( 18 "testing" 19 20 . "github.com/onsi/gomega" 21) 22 23func TestParse(t *testing.T) { 24 var cases = []struct { 25 Input string 26 Expected *Constraints 27 }{ 28 { 29 Input: ``, 30 Expected: &Constraints{}, 31 }, 32 { 33 Input: ` 34constraints: 35`, 36 Expected: &Constraints{}, 37 }, 38 39 { 40 Input: ` 41constraints: 42 - collection: foo 43`, 44 Expected: &Constraints{ 45 Constraints: []*Collection{ 46 { 47 Name: "foo", 48 }, 49 }, 50 }, 51 }, 52 53 { 54 Input: ` 55constraints: 56 - collection: foo 57 check: 58`, 59 Expected: &Constraints{ 60 Constraints: []*Collection{ 61 { 62 Name: "foo", 63 }, 64 }, 65 }, 66 }, 67 68 { 69 Input: ` 70constraints: 71 - collection: foo 72 check: 73 - exactlyOne: 74`, 75 Expected: &Constraints{ 76 Constraints: []*Collection{ 77 { 78 Name: "foo", 79 Check: []Range{ 80 &ExactlyOne{}, 81 }, 82 }, 83 }, 84 }, 85 }, 86 87 { 88 Input: ` 89constraints: 90 - collection: foo 91 check: 92 - any: 93`, 94 Expected: &Constraints{ 95 Constraints: []*Collection{ 96 { 97 Name: "foo", 98 Check: []Range{ 99 &Any{}, 100 }, 101 }, 102 }, 103 }, 104 }, 105 106 { 107 Input: ` 108constraints: 109 - collection: foo 110 check: 111 - exactlyOne: 112 - select: foo 113 exists: true 114`, 115 Expected: &Constraints{ 116 Constraints: []*Collection{ 117 { 118 Name: "foo", 119 Check: []Range{ 120 &ExactlyOne{ 121 Constraints: []Check{ 122 &Select{ 123 Expression: "foo", 124 Op: SelectExists, 125 }, 126 }, 127 }, 128 }, 129 }, 130 }, 131 }, 132 }, 133 134 { 135 Input: ` 136constraints: 137 - collection: foo 138 check: 139 - exactlyOne: 140 - select: foo 141 exists: false 142`, 143 Expected: &Constraints{ 144 Constraints: []*Collection{ 145 { 146 Name: "foo", 147 Check: []Range{ 148 &ExactlyOne{ 149 Constraints: []Check{ 150 &Select{ 151 Expression: "foo", 152 Op: SelectNotExists, 153 }, 154 }, 155 }, 156 }, 157 }, 158 }, 159 }, 160 }, 161 162 { 163 Input: ` 164constraints: 165 - collection: foo 166 check: 167 - exactlyOne: 168 - select: foo 169 equals: 170 boo: bar 171`, 172 Expected: &Constraints{ 173 Constraints: []*Collection{ 174 { 175 Name: "foo", 176 Check: []Range{ 177 &ExactlyOne{ 178 Constraints: []Check{ 179 &Select{ 180 Expression: "foo", 181 Op: SelectEquals, 182 Arg: map[string]interface{}{ 183 "boo": "bar", 184 }, 185 }, 186 }, 187 }, 188 }, 189 }, 190 }, 191 }, 192 }, 193 194 { 195 Input: ` 196constraints: 197 - collection: foo 198 check: 199 - exactlyOne: 200 - select: foo 201 equals: 202 - boo: bar 203`, 204 Expected: &Constraints{ 205 Constraints: []*Collection{ 206 { 207 Name: "foo", 208 Check: []Range{ 209 &ExactlyOne{ 210 Constraints: []Check{ 211 &Select{ 212 Expression: "foo", 213 Op: SelectEquals, 214 Arg: []interface{}{ 215 map[string]interface{}{ 216 "boo": "bar", 217 }, 218 }, 219 }, 220 }, 221 }, 222 }, 223 }, 224 }, 225 }, 226 }, 227 228 { 229 Input: ` 230constraints: 231 - collection: foo 232 check: 233 - any: 234 - select: foo 235 then: 236 - select: bar 237 exists: true 238`, 239 Expected: &Constraints{ 240 Constraints: []*Collection{ 241 { 242 Name: "foo", 243 Check: []Range{ 244 &Any{ 245 Constraints: []Check{ 246 &Select{ 247 Expression: "foo", 248 Op: SelectGroup, 249 Children: []*Select{ 250 { 251 Expression: "bar", 252 Op: SelectExists, 253 }, 254 }, 255 }, 256 }, 257 }, 258 }, 259 }, 260 }, 261 }, 262 }, 263 } 264 265 for _, c := range cases { 266 t.Run("", func(t *testing.T) { 267 g := NewGomegaWithT(t) 268 cons, err := Parse([]byte(c.Input)) 269 g.Expect(err).To(BeNil()) 270 271 // Clear parentage to simplify testing 272 for _, c := range cons.Constraints { 273 for _, d := range c.Check { 274 var constr []Check 275 switch v := d.(type) { 276 case *ExactlyOne: 277 constr = v.Constraints 278 case *Any: 279 constr = v.Constraints 280 } 281 282 for _, e := range constr { 283 s, ok := e.(*Select) 284 if ok { 285 s.Parent = nil 286 } 287 288 for _, c := range s.Children { 289 c.Parent = nil 290 } 291 } 292 } 293 } 294 g.Expect(cons).To(Equal(c.Expected)) 295 }) 296 } 297} 298