-- in.cue --
import (
	"encoding/json"
	"list"
	"struct"
)

// non-monotonic builtins must fail with an "incomplete" error if there
// is a possibility the constraint can get resolved by becoming more specific.
incompleteError1: {
	MyType: {
		kv: struct.MinFields(1)
	}

	foo: MyType & {
		kv: joel: "testing"
	}
}

incompleteError2: {
	MyType: {
		kv: [string]: string
		kv: struct.MinFields(1)
	}

	foo: MyType & {
		kv: joel: "testing"
	}
}

incompleteError3: {
	t: string
	t: json.Validate(string)
}

uniqueConstrains1: {
	t: string
	t: json.Validate(string)
	t: json.Validate(string)
}

uniqueConstrains2: {
	t: struct.MaxFields(1)
	t: struct.MaxFields(1)
}

violation: {
	#MyType: {
		kv: [string]: string
		kv: struct.MinFields(1)
	}

	foo: #MyType & {
		kv: joel: "testing"
		kv: tony: "testing"
	}
}

conjuncts: {
	kv: struct.MinFields(1)
	kv: struct.MaxFields(3)
}

// TODO: stripe off conflicting pairs
// conflicting: {
//     kv: struct.MinFields(3)
//     kv: struct.MaxFields(1)
// }

// Builtins with bool return that can be used as validator.

bareBuiltin: {
	a: json.Valid
	a: json.Valid
}

bareBuiltinCheck: {
	a: json.Valid
	a: "3"
}

builtinValidator: {
	a: json.Valid()
	a: json.Valid()
}

builtinValidatorCheck: {
	a: json.Valid()
	a: "3"
}

callOfCallToValidator: {
	a: json.Valid
	b: a()
	e: b()
	e: "5"
}

validatorAsFunction: {
	a: json.Valid
	b: a("3")
	c: json.Valid("3")
}

// issue2098: Tests that list.MinItems() does not panic when combined with list
// embedding and index access. https://cuelang.org/issue/2098
issue2098: ok1: {
	_a: [1, ...]
	_a: list.MinItems(1)
	_a[0]
}

issue2098: incomplete1: {
	_a: [...]
	_a: list.MinItems(1)
	_a[0]
}
-- issue3418.cue --
// issue3418: Tests that matchN correctly reports validation failures when
// combined with conflicting constraints, regardless of operand order.
// https://cuelang.org/issue/3418
issue3418: t1: "foo" & matchN(1, [1 & 2]) & matchN(1, [_])

issue3418: t2: "foo" & matchN(1, [_]) & matchN(1, [1 & 2])

issue3418: t3: {
	x: "foo"
	x: matchN(1, [_])
	x: matchN(1, [1 & 2])
}
issue3418: t4: {
	x: "foo"
	x: matchN(1, [1 & 2])
	x: matchN(1, [_])
}
-- issue3474.cue --
import "struct"

// issue3474: Tests that struct.MinFields/MaxFields validators correctly handle
// fields added by conditional comprehensions. https://cuelang.org/issue/3474
issue3474: structValidator: ok: {
	// Passes only after the comprehension is evaluated.
	A: struct.MinFields(1)
	A: {
		if true {B: true}
	}
}
issue3474: structValidator: failAfter: {
	// Passes only before the comprehension is evaluated.
	A: struct.MaxFields(1)
	A: {
		C: true
		if true {B: true}
	}
}
issue3474: structValidator: incomplete: {
	// Passes neither before nor after the comprehension is evaluated.
	A: struct.MinFields(1)
	A: {
		if true {}
	}
}
issue3474: structValidator: failClosed: {
	// Passes neither before nor after the comprehension is evaluated.
	#A: struct.MinFields(1)
	#A: {
		if true {}
	}
}

issue3474: topValidator: ok: {
	A: matchN(1, [>10])
	A: {
		if true {100}
	}
}
issue3474: topValidator: fail: {
	A: matchN(1, [>10])
	A: {
		if true {1}
	}

}
issue3474: topValidator: incomplete: {
	A: matchN(1, [>10])
	A: {
		if true {int}
	}
}
issue3474: topValidator: failType: {
	A: matchN(1, [>10])
	A: {
		if true {C: 1}
	}
}
-- validator_is_top.cue --
// issue3639: Tests that embedding a matchN validator struct alongside direct
// application does not cause "field not allowed" errors. https://cuelang.org/issue/3639
issue3639: {
	a: {#X} & #X
	a: b: 1
	#X: matchN(1, [{b: int}])
}
// issue3661: Tests that matchN with a required field validator works when
// applied via a pattern constraint. https://cuelang.org/issue/3661
issue3661: {
	#X: matchN(1, [{b!: int}])
	a: b: 1
	a:     #X
	["a"]: #X
}
// issue3678: Tests that matchN with multiple required-field alternatives does not
// produce spurious "field not allowed" errors. https://cuelang.org/issue/3678
issue3678: {
	#X: matchN(1, [{
		a!: string
	}, {
		c!: string
	}])

	x: c: "c"

	y: #X
	y: x
	x: #X
}
// issue3981: Tests that matchN combined with close() correctly handles open
// struct arguments without topological sort regressions. https://cuelang.org/issue/3981
issue3981: matchWithClose: {
	out: {
		close({
			f1: matchN(1, [#openStruct])
		})
		#openStruct: {...}
	}
	out: f1: foo: ["bar"]
}
-- out/compile --
--- in.cue
{
  incompleteError1: {
    MyType: {
      kv: 〈import;struct〉.MinFields(1)
    }
    foo: (〈0;MyType〉 & {
      kv: {
        joel: "testing"
      }
    })
  }
  incompleteError2: {
    MyType: {
      kv: {
        [string]: string
      }
      kv: 〈import;struct〉.MinFields(1)
    }
    foo: (〈0;MyType〉 & {
      kv: {
        joel: "testing"
      }
    })
  }
  incompleteError3: {
    t: string
    t: 〈import;"encoding/json"〉.Validate(string)
  }
  uniqueConstrains1: {
    t: string
    t: 〈import;"encoding/json"〉.Validate(string)
    t: 〈import;"encoding/json"〉.Validate(string)
  }
  uniqueConstrains2: {
    t: 〈import;struct〉.MaxFields(1)
    t: 〈import;struct〉.MaxFields(1)
  }
  violation: {
    #MyType: {
      kv: {
        [string]: string
      }
      kv: 〈import;struct〉.MinFields(1)
    }
    foo: (〈0;#MyType〉 & {
      kv: {
        joel: "testing"
      }
      kv: {
        tony: "testing"
      }
    })
  }
  conjuncts: {
    kv: 〈import;struct〉.MinFields(1)
    kv: 〈import;struct〉.MaxFields(3)
  }
  bareBuiltin: {
    a: 〈import;"encoding/json"〉.Valid
    a: 〈import;"encoding/json"〉.Valid
  }
  bareBuiltinCheck: {
    a: 〈import;"encoding/json"〉.Valid
    a: "3"
  }
  builtinValidator: {
    a: 〈import;"encoding/json"〉.Valid()
    a: 〈import;"encoding/json"〉.Valid()
  }
  builtinValidatorCheck: {
    a: 〈import;"encoding/json"〉.Valid()
    a: "3"
  }
  callOfCallToValidator: {
    a: 〈import;"encoding/json"〉.Valid
    b: 〈0;a〉()
    e: 〈0;b〉()
    e: "5"
  }
  validatorAsFunction: {
    a: 〈import;"encoding/json"〉.Valid
    b: 〈0;a〉("3")
    c: 〈import;"encoding/json"〉.Valid("3")
  }
  issue2098: {
    ok1: {
      _a: [
        1,
        ...,
      ]
      _a: 〈import;list〉.MinItems(1)
      〈0;_a〉[0]
    }
  }
  issue2098: {
    incomplete1: {
      _a: [
        ...,
      ]
      _a: 〈import;list〉.MinItems(1)
      〈0;_a〉[0]
    }
  }
}
--- issue3418.cue
{
  issue3418: {
    t1: (("foo" & matchN(1, [
      (1 & 2),
    ])) & matchN(1, [
      _,
    ]))
  }
  issue3418: {
    t2: (("foo" & matchN(1, [
      _,
    ])) & matchN(1, [
      (1 & 2),
    ]))
  }
  issue3418: {
    t3: {
      x: "foo"
      x: matchN(1, [
        _,
      ])
      x: matchN(1, [
        (1 & 2),
      ])
    }
  }
  issue3418: {
    t4: {
      x: "foo"
      x: matchN(1, [
        (1 & 2),
      ])
      x: matchN(1, [
        _,
      ])
    }
  }
}
--- issue3474.cue
{
  issue3474: {
    structValidator: {
      ok: {
        A: 〈import;struct〉.MinFields(1)
        A: {
          if true {
            B: true
          }
        }
      }
    }
  }
  issue3474: {
    structValidator: {
      failAfter: {
        A: 〈import;struct〉.MaxFields(1)
        A: {
          C: true
          if true {
            B: true
          }
        }
      }
    }
  }
  issue3474: {
    structValidator: {
      incomplete: {
        A: 〈import;struct〉.MinFields(1)
        A: {
          if true {}
        }
      }
    }
  }
  issue3474: {
    structValidator: {
      failClosed: {
        #A: 〈import;struct〉.MinFields(1)
        #A: {
          if true {}
        }
      }
    }
  }
  issue3474: {
    topValidator: {
      ok: {
        A: matchN(1, [
          >10,
        ])
        A: {
          if true {
            100
          }
        }
      }
    }
  }
  issue3474: {
    topValidator: {
      fail: {
        A: matchN(1, [
          >10,
        ])
        A: {
          if true {
            1
          }
        }
      }
    }
  }
  issue3474: {
    topValidator: {
      incomplete: {
        A: matchN(1, [
          >10,
        ])
        A: {
          if true {
            int
          }
        }
      }
    }
  }
  issue3474: {
    topValidator: {
      failType: {
        A: matchN(1, [
          >10,
        ])
        A: {
          if true {
            C: 1
          }
        }
      }
    }
  }
}
--- validator_is_top.cue
{
  issue3639: {
    a: ({
      〈1;#X〉
    } & 〈0;#X〉)
    a: {
      b: 1
    }
    #X: matchN(1, [
      {
        b: int
      },
    ])
  }
  issue3661: {
    #X: matchN(1, [
      {
        b!: int
      },
    ])
    a: {
      b: 1
    }
    a: 〈0;#X〉
    ["a"]: 〈0;#X〉
  }
  issue3678: {
    #X: matchN(1, [
      {
        a!: string
      },
      {
        c!: string
      },
    ])
    x: {
      c: "c"
    }
    y: 〈0;#X〉
    y: 〈0;x〉
    x: 〈0;#X〉
  }
  issue3981: {
    matchWithClose: {
      out: {
        close({
          f1: matchN(1, [
            〈2;#openStruct〉,
          ])
        })
        #openStruct: {
          ...
        }
      }
      out: {
        f1: {
          foo: [
            "bar",
          ]
        }
      }
    }
  }
}
