github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/cue/testdata/cycle/compbottom.txtar (about) 1 // Issues: #667, #695, #622 2 3 // Comparing against bottom is not officially supported by the spec. 4 // In practice it is used for a variety of purposes. 5 // 6 // TODO: It should really be replaced with two builtins: 7 // 8 // - exists(reference): check if a certain field exists. 9 // - isvalid(value): check if a certain value is valid (recursively). 10 // 11 // For now it implements something in between these two: it fails if a value 12 // resolves to an error, but not necessarily if it does so recursively. 13 // Although adding a recursive check is easy, it will break existing 14 // configurations, as a recursive evaluation will trigger cycles where these 15 // are perhaps not expected. 16 17 // To verify these tests, each result should have a field 18 // 19 // X: "user@example.com" 20 // 21 // for the large and medium examples and 22 // 23 // X: "message: hello" 24 // 25 // for the simple example. 26 // 27 // These are not automatically tested using CUE to avoid interfering with the 28 // evaluation. 29 30 -- in.cue -- 31 import "regexp" 32 33 simple: { 34 #message: #"^(message: (?P<message>.*))?$"# 35 36 p1: { 37 X: "message: hello" 38 #aux: { 39 if Y.message == _|_ { 40 message: "" 41 } 42 if Y.message != _|_ { 43 message: "message: " + Y.message 44 } 45 } 46 47 Y: regexp.FindNamedSubmatch(#message, X) 48 X: #aux.message 49 } 50 51 p2: { 52 #aux: { 53 if Y.message == _|_ { 54 message: "" 55 } 56 if Y.message != _|_ { 57 message: "message: " + Y.message 58 } 59 } 60 61 X: "message: hello" 62 Y: regexp.FindNamedSubmatch(#message, X) 63 X: #aux.message 64 } 65 66 p3: { 67 #aux: { 68 if Y.message == _|_ { 69 message: "" 70 } 71 if Y.message != _|_ { 72 message: "message: " + Y.message 73 } 74 } 75 76 Y: regexp.FindNamedSubmatch(#message, X) 77 X: "message: hello" 78 X: #aux.message 79 } 80 81 p4: { 82 X: #aux.message 83 #aux: { 84 if Y.message == _|_ { 85 message: "" 86 } 87 if Y.message != _|_ { 88 message: "message: " + Y.message 89 } 90 } 91 92 Y: regexp.FindNamedSubmatch(#message, X) 93 X: "message: hello" 94 } 95 96 p5: { 97 #aux: { 98 if Y.message == _|_ { 99 message: "" 100 } 101 if Y.message != _|_ { 102 message: "message: " + Y.message 103 } 104 } 105 106 X: #aux.message 107 Y: regexp.FindNamedSubmatch(#message, X) 108 X: "message: hello" 109 } 110 111 p6: { 112 #aux: { 113 if Y.message == _|_ { 114 message: "" 115 } 116 if Y.message != _|_ { 117 message: "message: " + Y.message 118 } 119 } 120 121 Y: regexp.FindNamedSubmatch(#message, X) 122 X: #aux.message 123 X: "message: hello" 124 } 125 } 126 127 medium: { 128 #userHostPort: #"^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)$"# 129 130 p1: { 131 Y: { 132 userinfo: "user" 133 host: "example.com" 134 } 135 136 X: #X.userinfo + #X.host 137 138 #X: { 139 if Y.userinfo == _|_ { 140 userinfo: "" 141 } 142 if Y.userinfo != _|_ { 143 userinfo: Y.userinfo + "@" 144 } 145 146 host: Y.host 147 } 148 149 Y: { 150 if #Y.userinfo != _|_ { 151 userinfo: #Y.userinfo 152 } 153 154 host: #Y.host 155 } 156 157 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 158 } 159 160 p2: { 161 X: #X.userinfo + #X.host 162 163 Y: { 164 userinfo: "user" 165 host: "example.com" 166 } 167 168 #X: { 169 if Y.userinfo == _|_ { 170 userinfo: "" 171 } 172 if Y.userinfo != _|_ { 173 userinfo: Y.userinfo + "@" 174 } 175 176 host: Y.host 177 } 178 179 Y: { 180 if #Y.userinfo != _|_ { 181 userinfo: #Y.userinfo 182 } 183 184 host: #Y.host 185 } 186 187 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 188 } 189 190 p3: { 191 X: #X.userinfo + #X.host 192 193 #X: { 194 if Y.userinfo == _|_ { 195 userinfo: "" 196 } 197 if Y.userinfo != _|_ { 198 userinfo: Y.userinfo + "@" 199 } 200 201 host: Y.host 202 } 203 204 Y: { 205 userinfo: "user" 206 host: "example.com" 207 } 208 209 Y: { 210 if #Y.userinfo != _|_ { 211 userinfo: #Y.userinfo 212 } 213 214 host: #Y.host 215 } 216 217 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 218 } 219 220 p4: { 221 X: #X.userinfo + #X.host 222 223 #X: { 224 if Y.userinfo == _|_ { 225 userinfo: "" 226 } 227 if Y.userinfo != _|_ { 228 userinfo: Y.userinfo + "@" 229 } 230 231 host: Y.host 232 } 233 234 Y: { 235 if #Y.userinfo != _|_ { 236 userinfo: #Y.userinfo 237 } 238 239 host: #Y.host 240 } 241 242 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 243 244 Y: { 245 userinfo: "user" 246 host: "example.com" 247 } 248 } 249 } 250 -- out/eval -- 251 (struct){ 252 simple: (struct){ 253 #message: (string){ "^(message: (?P<message>.*))?$" } 254 p1: (struct){ 255 X: (string){ "message: hello" } 256 #aux: (#struct){ 257 message: (string){ "message: hello" } 258 } 259 Y: (struct){ 260 message: (string){ "hello" } 261 } 262 } 263 p2: (struct){ 264 #aux: (#struct){ 265 message: (string){ "message: hello" } 266 } 267 X: (string){ "message: hello" } 268 Y: (struct){ 269 message: (string){ "hello" } 270 } 271 } 272 p3: (struct){ 273 #aux: (#struct){ 274 message: (string){ "message: hello" } 275 } 276 Y: (struct){ 277 message: (string){ "hello" } 278 } 279 X: (string){ "message: hello" } 280 } 281 p4: (struct){ 282 X: (string){ "message: hello" } 283 #aux: (#struct){ 284 message: (string){ "message: hello" } 285 } 286 Y: (struct){ 287 message: (string){ "hello" } 288 } 289 } 290 p5: (struct){ 291 #aux: (#struct){ 292 message: (string){ "message: hello" } 293 } 294 X: (string){ "message: hello" } 295 Y: (struct){ 296 message: (string){ "hello" } 297 } 298 } 299 p6: (struct){ 300 #aux: (#struct){ 301 message: (string){ "message: hello" } 302 } 303 Y: (struct){ 304 message: (string){ "hello" } 305 } 306 X: (string){ "message: hello" } 307 } 308 } 309 medium: (struct){ 310 #userHostPort: (string){ "^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)$" } 311 p1: (struct){ 312 Y: (struct){ 313 userinfo: (string){ "user" } 314 host: (string){ "example.com" } 315 } 316 X: (string){ "user@example.com" } 317 #X: (#struct){ 318 host: (string){ "example.com" } 319 userinfo: (string){ "user@" } 320 } 321 #Y: (#struct){ 322 host: (string){ "example.com" } 323 userinfo: (string){ "user" } 324 } 325 } 326 p2: (struct){ 327 X: (string){ "user@example.com" } 328 Y: (struct){ 329 userinfo: (string){ "user" } 330 host: (string){ "example.com" } 331 } 332 #X: (#struct){ 333 host: (string){ "example.com" } 334 userinfo: (string){ "user@" } 335 } 336 #Y: (#struct){ 337 host: (string){ "example.com" } 338 userinfo: (string){ "user" } 339 } 340 } 341 p3: (struct){ 342 X: (string){ "user@example.com" } 343 #X: (#struct){ 344 host: (string){ "example.com" } 345 userinfo: (string){ "user@" } 346 } 347 Y: (struct){ 348 userinfo: (string){ "user" } 349 host: (string){ "example.com" } 350 } 351 #Y: (#struct){ 352 host: (string){ "example.com" } 353 userinfo: (string){ "user" } 354 } 355 } 356 p4: (struct){ 357 X: (string){ "user@example.com" } 358 #X: (#struct){ 359 host: (string){ "example.com" } 360 userinfo: (string){ "user@" } 361 } 362 Y: (struct){ 363 host: (string){ "example.com" } 364 userinfo: (string){ "user" } 365 } 366 #Y: (#struct){ 367 host: (string){ "example.com" } 368 userinfo: (string){ "user" } 369 } 370 } 371 } 372 } 373 -- out/compile -- 374 --- in.cue 375 { 376 simple: { 377 #message: "^(message: (?P<message>.*))?$" 378 p1: { 379 X: "message: hello" 380 #aux: { 381 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 382 message: "" 383 } 384 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 385 message: ("message: " + 〈2;Y〉.message) 386 } 387 } 388 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 389 X: 〈0;#aux〉.message 390 } 391 p2: { 392 #aux: { 393 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 394 message: "" 395 } 396 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 397 message: ("message: " + 〈2;Y〉.message) 398 } 399 } 400 X: "message: hello" 401 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 402 X: 〈0;#aux〉.message 403 } 404 p3: { 405 #aux: { 406 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 407 message: "" 408 } 409 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 410 message: ("message: " + 〈2;Y〉.message) 411 } 412 } 413 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 414 X: "message: hello" 415 X: 〈0;#aux〉.message 416 } 417 p4: { 418 X: 〈0;#aux〉.message 419 #aux: { 420 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 421 message: "" 422 } 423 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 424 message: ("message: " + 〈2;Y〉.message) 425 } 426 } 427 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 428 X: "message: hello" 429 } 430 p5: { 431 #aux: { 432 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 433 message: "" 434 } 435 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 436 message: ("message: " + 〈2;Y〉.message) 437 } 438 } 439 X: 〈0;#aux〉.message 440 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 441 X: "message: hello" 442 } 443 p6: { 444 #aux: { 445 if (〈1;Y〉.message == _|_(explicit error (_|_ literal) in source)) { 446 message: "" 447 } 448 if (〈1;Y〉.message != _|_(explicit error (_|_ literal) in source)) { 449 message: ("message: " + 〈2;Y〉.message) 450 } 451 } 452 Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#message〉, 〈0;X〉) 453 X: 〈0;#aux〉.message 454 X: "message: hello" 455 } 456 } 457 medium: { 458 #userHostPort: "^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)$" 459 p1: { 460 Y: { 461 userinfo: "user" 462 host: "example.com" 463 } 464 X: (〈0;#X〉.userinfo + 〈0;#X〉.host) 465 #X: { 466 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 467 userinfo: "" 468 } 469 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 470 userinfo: (〈2;Y〉.userinfo + "@") 471 } 472 host: 〈1;Y〉.host 473 } 474 Y: { 475 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 476 userinfo: 〈2;#Y〉.userinfo 477 } 478 host: 〈1;#Y〉.host 479 } 480 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 481 } 482 p2: { 483 X: (〈0;#X〉.userinfo + 〈0;#X〉.host) 484 Y: { 485 userinfo: "user" 486 host: "example.com" 487 } 488 #X: { 489 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 490 userinfo: "" 491 } 492 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 493 userinfo: (〈2;Y〉.userinfo + "@") 494 } 495 host: 〈1;Y〉.host 496 } 497 Y: { 498 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 499 userinfo: 〈2;#Y〉.userinfo 500 } 501 host: 〈1;#Y〉.host 502 } 503 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 504 } 505 p3: { 506 X: (〈0;#X〉.userinfo + 〈0;#X〉.host) 507 #X: { 508 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 509 userinfo: "" 510 } 511 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 512 userinfo: (〈2;Y〉.userinfo + "@") 513 } 514 host: 〈1;Y〉.host 515 } 516 Y: { 517 userinfo: "user" 518 host: "example.com" 519 } 520 Y: { 521 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 522 userinfo: 〈2;#Y〉.userinfo 523 } 524 host: 〈1;#Y〉.host 525 } 526 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 527 } 528 p4: { 529 X: (〈0;#X〉.userinfo + 〈0;#X〉.host) 530 #X: { 531 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 532 userinfo: "" 533 } 534 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 535 userinfo: (〈2;Y〉.userinfo + "@") 536 } 537 host: 〈1;Y〉.host 538 } 539 Y: { 540 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 541 userinfo: 〈2;#Y〉.userinfo 542 } 543 host: 〈1;#Y〉.host 544 } 545 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 546 Y: { 547 userinfo: "user" 548 host: "example.com" 549 } 550 } 551 } 552 }