cue-lang / cue

The home of the CUE language! Validate and define text-based and dynamic configuration
https://cuelang.org
Apache License 2.0
5.02k stars 286 forks source link

matchN: inconsistent reporting of the full set of validation errors #3388

Open jpluscplusm opened 3 weeks ago

jpluscplusm commented 3 weeks ago

What version of CUE are you using (cue version)?

$ cue version
cue version v0.11.0-0.dev.0.20240822081630-a20e523c2059

go version go1.23.0
      -buildmode exe
       -compiler gc
  DefaultGODEBUG asynctimerchan=1,gotypesalias=0,httpservecontentkeepheaders=1,tls3des=1,tlskyber=0,x509keypairleaf=0,x509negativeserial=1
     CGO_ENABLED 1
          GOARCH amd64
            GOOS linux
         GOAMD64 v1
cue.lang.version v0.11.0

Does this issue reproduce with the latest stable release?

n/a (function is not available in latest, v0.10.0)

What did you do?

! exec cue vet
cmp stderr stderr.golden

-- f.cue --
package p

A: 42
A: matchN(0, [int])
A: matchN(0, [string, number])
A: matchN(0, [42, >100, >1000])

B: 42
B: matchN(1, [int, >10])
B: matchN(1, [string, >100])

-- stderr.golden --
A: invalid value 42 (does not satisfy matchN(0, [int])): 1 matched, expected 0:
    ./f.cue:4:4
    ./f.cue:3:4
    ./f.cue:4:11
    ./f.cue:5:4
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [string,number])): 1 matched, expected 0:
    ./f.cue:5:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:11
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [42,>100,>1000])): 1 matched, expected 0:
    ./f.cue:6:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:4
    ./f.cue:6:11
B: invalid value 42 (does not satisfy matchN(1, [int,>10])): 2 matched, expected 1:
    ./f.cue:9:4
    ./f.cue:8:4
    ./f.cue:9:11
B: invalid value 42 (does not satisfy matchN(1, [string,>100])): 0 matched, expected 1:
    ./f.cue:10:4
    ./f.cue:8:4
    ./f.cue:9:4
    ./f.cue:10:11

Repro from @myitcv in https://github.com/cue-lang/cue/issues/3388#issuecomment-2304204638

What did you expect to see?

A passing test.

What did you see instead?

> ! exec cue vet
[stderr]
A: invalid value 42 (does not satisfy matchN(0, [int])): 1 matched, expected 0:
    ./f.cue:4:4
    ./f.cue:3:4
    ./f.cue:4:11
    ./f.cue:5:4
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [string,number])): 1 matched, expected 0:
    ./f.cue:5:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:11
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [42,>100,>1000])): 1 matched, expected 0:
    ./f.cue:6:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:4
    ./f.cue:6:11
B: invalid value 42 (does not satisfy matchN(1, [string,>100])): 0 matched, expected 1:
    ./f.cue:10:4
    ./f.cue:8:4
    ./f.cue:9:4
    ./f.cue:10:11
[exit status 1]
> cmp stderr stderr.golden
diff stderr stderr.golden
--- stderr
+++ stderr.golden
@@ -16,6 +16,10 @@
     ./f.cue:4:4
     ./f.cue:5:4
     ./f.cue:6:11
+B: invalid value 42 (does not satisfy matchN(1, [int,>10])): 2 matched, expected 1:
+    ./f.cue:9:4
+    ./f.cue:8:4
+    ./f.cue:9:11
 B: invalid value 42 (does not satisfy matchN(1, [string,>100])): 0 matched, expected 1:
     ./f.cue:10:4
     ./f.cue:8:4

FAIL: /tmp/testscript912524492/matchN.inconsistentErrorReporting.txtar/script.txtar:2: stderr and stderr.golden differ
myitcv commented 3 weeks ago

Thanks for the report, @jpluscplusm.

If you will allow me, I think the repro is clearer like this:

! exec cue vet
cmp stderr stderr.golden

-- f.cue --
package p

A: 42
A: matchN(0, [int])
A: matchN(0, [string, number])
A: matchN(0, [42, >100, >1000])

B: 42
B: matchN(1, [int, >10])
B: matchN(1, [string, >100])

-- stderr.golden --
A: invalid value 42 (does not satisfy matchN(0, [int])): 1 matched, expected 0:
    ./f.cue:4:4
    ./f.cue:3:4
    ./f.cue:4:11
    ./f.cue:5:4
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [string,number])): 1 matched, expected 0:
    ./f.cue:5:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:11
    ./f.cue:6:4
A: invalid value 42 (does not satisfy matchN(0, [42,>100,>1000])): 1 matched, expected 0:
    ./f.cue:6:4
    ./f.cue:3:4
    ./f.cue:4:4
    ./f.cue:5:4
    ./f.cue:6:11
B: invalid value 42 (does not satisfy matchN(1, [int,>10])): 2 matched, expected 1:
    ./f.cue:9:4
    ./f.cue:8:4
    ./f.cue:9:11
B: invalid value 42 (does not satisfy matchN(1, [string,>100])): 0 matched, expected 1:
    ./f.cue:10:4
    ./f.cue:8:4
    ./f.cue:9:4
    ./f.cue:10:11

Expectation is that it should pass but we get:

> cmp stderr stderr.golden
diff stderr stderr.golden
--- stderr
+++ stderr.golden
@@ -16,6 +16,10 @@
     ./f.cue:4:4
     ./f.cue:5:4
     ./f.cue:6:11
+B: invalid value 42 (does not satisfy matchN(1, [int,>10])): 2 matched, expected 1:
+    ./f.cue:9:4
+    ./f.cue:8:4
+    ./f.cue:9:11
 B: invalid value 42 (does not satisfy matchN(1, [string,>100])): 0 matched, expected 1:
     ./f.cue:10:4
     ./f.cue:8:4

FAIL: /tmp/testscript2903460784/repro.txtar/script.txtar:2: stderr and stderr.golden differ
mpvl commented 3 weeks ago

Observation: v3 does the right thing here.