# Tests that recursive schema definitions with many optional fields (e.g. a
# JSON-Schema-like #Schema with properties/required) do not cause exponential
# conjunct blowup when embedded or unified. The `reduced` case validates basic
# self-embedding; `full` validates a realistic JSON-Schema-style structure.
# https://cuelang.org/issue/3633
-- in.cue --
reduced: {
	#Schema: {
		a?: null | bool | string | int | #Schema
		b?: null | bool | string | int | #Schema
		c?: null | bool | string | int | #Schema
		d?: null | bool | string | int | #Schema
		e?: null | bool | string | int | #Schema
		f?: null | bool | string | int | #Schema
	}

	out: #Schema & { #Schema }
}
full: {
	#Schema: {
		required?: [...string]
		properties?: [string]: null | bool | string | [...int] | #Schema

		foo00?: null | bool | string | [...int] | {string: int32}
		foo01?: null | bool | string | [...int] | {string: int32}
		foo02?: null | bool | string | [...int] | {string: int32}
		foo03?: null | bool | string | [...int] | {string: int32}
		foo04?: null | bool | string | [...int] | {string: int32}
		foo05?: null | bool | string | [...int] | {string: int32}
		foo06?: null | bool | string | [...int] | {string: int32}
		foo07?: null | bool | string | [...int] | {string: int32}
		foo08?: null | bool | string | [...int] | {string: int32}
		foo09?: null | bool | string | [...int] | {string: int32}
		foo10?: null | bool | string | [...int] | {string: int32}
		foo11?: null | bool | string | [...int] | {string: int32}
		foo12?: null | bool | string | [...int] | {string: int32}
		foo13?: null | bool | string | [...int] | {string: int32}
		foo14?: null | bool | string | [...int] | {string: int32}
		foo15?: null | bool | string | [...int] | {string: int32}
		foo16?: null | bool | string | [...int] | {string: int32}
		foo17?: null | bool | string | [...int] | {string: int32}
		foo18?: null | bool | string | [...int] | {string: int32}
		foo19?: null | bool | string | [...int] | {string: int32}
	}

	out: [...#Schema] & [{
		#Schema
		properties: foo: required: ["bar", "baz"]
	}]
}

// TODO(inline):
//  1) format better
//  2) identify repeated elements
//  3) leave at= flag at begginning when generating.
@test(eq, at=full.out, [{
	properties: {
		foo: {
			required: ["bar", "baz"]
			properties?: {}
			foo00?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo01?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo02?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo03?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo04?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo05?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo06?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo07?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo08?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo09?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo10?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo11?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo12?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo13?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo14?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo15?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo16?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo17?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo18?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
			foo19?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
		}
	}
	required?: []
	foo00?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo01?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo02?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo03?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo04?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo05?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo06?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo07?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo08?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo09?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo10?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo11?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo12?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo13?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo14?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo15?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo16?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo17?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo18?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
	foo19?: null | bool | string | [] | {string: >=-2147483648 & <=2147483647 & int}
}])
@test(eq, {
	a?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
	b?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
	c?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
	d?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
	e?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
	f?: null | bool | string | int | {a?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, b?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, c?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, d?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, e?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}, f?: null | bool | string | int | {a?: null | bool | string | int, b?: null | bool | string | int, c?: null | bool | string | int, d?: null | bool | string | int, e?: null | bool | string | int, f?: null | bool | string | int}}
}, at=reduced.out)

-- out/eval/stats --
Leaks:  145
Freed:  1886
Reused: 1798
Allocs: 233
Retain: 0

Unifications: 401
Conjuncts:    2081
Disjuncts:    1625

NumCloseIDs: 50
