-- in.cue --
import (
	"list"
	"strings"
)

a1: {
	a: and([b, c])
	b: =~"oo"
	c: =~"fo"
} @test(eq, {
	a: =~"oo" & =~"fo"
	b: =~"oo"
	c: =~"fo"
})
a2: a1 & {a: "foo"} @test(eq, {a: "foo", b: =~"oo", c: =~"fo"})
a3: a1 & {a: "bar"} @test(err, code=eval,
	suberr=(code=eval, contains="invalid value", args=["bar", =~"oo"], pos=[-8:5, -9:5, 0:14]),
	suberr=(code=eval, contains="invalid value", args=["bar", =~"fo"], pos=[-7:5, -9:5, 0:14]))

o1: {
	a: or([b, c])
	b: string
	c: "bar"
} @test(eq, {a: string | "bar", b: string, c: "bar"})
o2: o1 & {a: "foo"}           @test(eq, {a: "foo", b: string, c: "bar"})
o3: o1 & {a: "foo", b: "baz"} @test(err, code=eval,
	suberr=(code=eval, contains="conflicting values", args=["bar", "foo"], pos=[-5:12, -3:5, 0:5, 0:14]),
	suberr=(code=eval, contains="conflicting values", args=["baz", "foo"], pos=[-5:9, 0:5, 0:14, 0:24]))

// Issue #585
stringListErrors: {
	a: {
		x: [string, ...string]
		result: strings.Join(x, " ") @test(err, code=incomplete,
			contains="non-concrete value string for element", pos=[0:11, -1:7])
	}

	b: {
		x: [int, ...string]
		result: strings.Join(x, " ") @test(err, code=eval,
			contains="cannot use value int (int) as string", pos=[0:11, -1:7])
	}

	c: {
		x: []
		result: strings.Join(x, int) @test(err, code=eval,
			contains="cannot use int (type int) as string in argument 2 to strings.Join",
			pos=[0:27])
	}
}

decimalListErrors: {
	a: {
		x: [string]
		result: list.Avg(x) @test(err, code=eval,
			contains="invalid list element", pos=[0:11, -1:7])
			// TODO: allow checking wrapped errors: args=[string, number],
	}

	b: {
		x: [int, ...string]
		result: list.Avg(x) @test(err, code=incomplete,
			contains="non-concrete value int for element 0 of number list argument 0", pos=[0:11, -1:7])
	}
}
-- issue3648.cue --
// Fully finalize values before passing them to builtins.

// "not properly initialized" error regression in evalv3 involving builtins:
// list.Concat received an unfinalized value when called from a pattern constraint.
// https://cuelang.org/issue/3648
import "list"

issue3648: reduced: {
	[string]: {
		a: list.Concat([b])
		b: [{}]
	}
	foo: {}

	@test(eq, {foo: {a: [{}], b: [{}]}})
}
issue3648: full: {
	#Redirect: path?: string

	[string]: {
		// Note that this bug disappears if the order of the fields below is swapped.
		allRedirects: list.Concat([redirects])
		redirects:    [...#Redirect]
	}
	foo: {}

	@test(eq, {
		#Redirect: {path?: string}
		[string]: {
			allRedirects: list.Concat([[]])
			redirects:    []
		}
		foo: {allRedirects: [], redirects: []}
	})
}
-- out/errors.txt --
[eval] a3.a: invalid value "bar" (out of bound =~"oo"):
    ./in.cue:8:5
    ./in.cue:7:5
    ./in.cue:16:14
a3.a: invalid value "bar" (out of bound =~"fo"):
    ./in.cue:9:5
    ./in.cue:7:5
    ./in.cue:16:14
[eval] o3.a: 2 errors in empty disjunction:
o3.a: conflicting values "bar" and "foo":
    ./in.cue:21:12
    ./in.cue:23:5
    ./in.cue:26:5
    ./in.cue:26:14
o3.a: conflicting values "baz" and "foo":
    ./in.cue:21:9
    ./in.cue:26:5
    ./in.cue:26:14
    ./in.cue:26:24
[incomplete] stringListErrors.a.result: error in call to strings.Join: non-concrete value string for element 0 of string list argument 0:
    ./in.cue:34:11
    ./in.cue:33:7
[eval] stringListErrors.b.result: error in call to strings.Join: invalid list element 0 in argument 0 to call: cannot use value int (int) as string:
    ./in.cue:40:11
    ./in.cue:39:7
[eval] stringListErrors.c.result: cannot use int (type int) as string in argument 2 to strings.Join:
    ./in.cue:46:27
[eval] decimalListErrors.a.result: error in call to list.Avg: invalid list element 0 in argument 0 to call: cannot use value string (string) as number:
    ./in.cue:55:11
    ./in.cue:54:7
[incomplete] decimalListErrors.b.result: error in call to list.Avg: non-concrete value int for element 0 of number list argument 0:
    ./in.cue:62:11
    ./in.cue:61:7
-- out/eval/stats --
Leaks:  1
Freed:  95
Reused: 76
Allocs: 20
Retain: 0

Unifications: 72
Conjuncts:    144
Disjuncts:    12

NumCloseIDs: 45
