Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-validator

Typed fluent validation rules for Pudu

0.1.1Apache-2.01

InstallClose

NestedSelectionTest.pudu

Pudu62 lines3.1 KB

GitHub ↗
1/** @Test.Validation.NestedSelection.Suite — checks child selection scope */2module PuduLangValidator.NestedSelectionTest34import Std.Test as Test5import PuduLangValidator.Result as Validation6import PuduLangValidator.Rule as Rule7import PuduLangValidator.Rules.Child as Child8import PuduLangValidator.Rules.Text as TextRule9import PuduLangValidator.Validator as Validator1011type Address = { city: Str, zip: Str }12type Order = { sku: Str, note: Str }13type Customer = { address: Option[Address], orders: Array[Order] }1415fn addressRules() -> Validator.Validator[Address] {16  let city = Rule.build(TextRule.notEmpty(Rule.ruleFor("city", |address: Address| address.city)))17  let zip = Rule.build(Rule.inRuleSet(TextRule.notEmpty(Rule.ruleFor("zip", |address: Address| address.zip)), "shipping"))18  Validator.add(Validator.add(Validator.create(), city), zip)19}2021fn orderRules() -> Validator.Validator[Order] {22  let sku = Rule.build(TextRule.notEmpty(Rule.ruleFor("sku", |order: Order| order.sku)))23  let note = Rule.build(TextRule.notEmpty(Rule.ruleFor("note", |order: Order| order.note)))24  Validator.add(Validator.add(Validator.create(), sku), note)25}2627fn customerRules() -> Validator.Validator[Customer] {28  let parent = Rule.build(Rule.withMessage(Rule.must(29        Rule.ruleFor("address", |customer: Customer| customer.address),30        |_value: Option[Address]| false31      ), "Parent address failed."))32  let address = Child.setOptionalValidator("address", |customer: Customer| customer.address, addressRules())33  let orders = Child.forEachValidator("orders", |customer: Customer| customer.orders, orderRules())34  Validator.add(Validator.add(Validator.add(Validator.create(), parent), address), orders)35}3637fn main() -> Int {38  let validator = customerRules()39  let customer = Customer {40    address: Some(Address{city: "", zip: ""}),41    orders: [Order{sku: "", note: ""}, Order{sku: "", note: ""}]42  }43  let shipping = Validator.validateWith(&validator, customer, Validator.onlyRuleSets(["shipping"]))44  let addressOnly = Validator.validateWith(&validator, customer,45    Validator.includeProperties(Validator.allRuleSets(), ["address.zip"]))46  let oneSku = Validator.validateWith(&validator, customer,47    Validator.includeProperties(Validator.defaults(), ["orders[1].sku"]))48  let allSku = Validator.validateWith(&validator, customer,49    Validator.includeProperties(Validator.defaults(), ["orders[].sku"]))50  let checks = Test.suite("NestedSelection", &[51      Test.equals("child rule set reaches named child", &shipping.errors.map(|failure: Validation.Failure| failure.propertyName),52          &["address.zip"]),53      Test.equals("nested property selection reaches one child field", &addressOnly.errors.map(|failure: Validation.Failure| failure.propertyName),54          &["address.zip"]),55      Test.equals("indexed property selection reaches one item and field", &oneSku.errors.map(|failure: Validation.Failure| failure.propertyName),56          &["orders[1].sku"]),57      Test.equals("empty index selects the field on every item", &allSku.errors.map(|failure: Validation.Failure| failure.propertyName),58          &["orders[0].sku", "orders[1].sku"])59    ])60  Test.report(&Test.run(&checks))61}62