
PropertyComparisonTest.pudu
Pudu75 lines4.5 KB
1/** @Test.Validation.PropertyComparison.Suite — checks typed source comparisons */2module PuduLangValidator.PropertyComparisonTest34import Std.Sync as Sync5import Std.Test as Test6import PuduLangValidator.Result as Validation7import PuduLangValidator.Rule as Rule8import PuduLangValidator.Rules.Comparison as Comparison9import PuduLangValidator.Rules.Ordering as Ordering10import PuduLangValidator.Validator as Validator1112type Fields = { value: Int, bound: Int, text: Str, confirmation: Str }1314fn evaluate(builder: Rule.RuleBuilder[Fields, Int], source: Fields) -> Validation.ValidationResult {15 Validator.validate(&Validator.add(Validator.create(), Rule.build(builder)), source)16}1718fn valueRule() -> Rule.RuleBuilder[Fields, Int] {19 Rule.ruleFor("value", |item: Fields| item.value)20}2122fn main() -> Int {23 let below = Fields{value: 4, bound: 5, text: "same", confirmation: "same"}24 let equal = Fields{value: 5, bound: 5, text: "same", confirmation: "other"}25 let above = Fields{value: 6, bound: 5, text: "same", confirmation: "other"}26 let changed = Fields{value: 6, bound: 7, text: "same", confirmation: "other"}27 let eqRule = Comparison.equalToProperty(valueRule(), "bound", |item: Fields| item.bound)28 let neRule = Comparison.notEqualToProperty(valueRule(), "bound", |item: Fields| item.bound)29 let gtRule = Ordering.greaterThanProperty(valueRule(), "bound", |item: Fields| item.bound)30 let geRule = Ordering.greaterThanOrEqualToProperty(valueRule(), "bound", |item: Fields| item.bound)31 let ltRule = Ordering.lessThanProperty(valueRule(), "bound", |item: Fields| item.bound)32 let leRule = Ordering.lessThanOrEqualToProperty(valueRule(), "bound", |item: Fields| item.bound)33 let textRule = Comparison.equalToProperty(34 Rule.ruleFor("text", |item: Fields| item.text), "confirmation", |item: Fields| item.confirmation)35 let eqFailure = evaluate(eqRule, below)36 let changedFailure = evaluate(gtRule, changed)37 let textFailure = Validator.validate(&Validator.add(Validator.create(), Rule.build(textRule)), equal)38 let calls = Sync.counter(0)39 let counted = Ordering.greaterThanProperty(valueRule(), "bound", fn(item: Fields) -> Int {40 let _step = Sync.increment(&calls, 1)41 if Sync.count(&calls) == Ok(1) { item.bound } else { panic("comparison selected twice") }42 })43 let countedFailure = evaluate(counted, below)44 let overridden = evaluate(Rule.withArgument(eqRule, "ComparisonValue", "hidden"), below)45 let checks = Test.suite("PropertyComparison", &[46 Test.that("equal accepts matching source field", evaluate(eqRule, equal).isValid),47 Test.that("equal rejects different source field", !eqFailure.isValid),48 Test.equals("equal carries comparison value", &eqFailure.errors[0].errorMessage,49 &"Value must equal 5 from bound."),50 Test.that("not equal rejects matching source field", !evaluate(neRule, equal).isValid),51 Test.that("not equal accepts different source field", evaluate(neRule, below).isValid),52 Test.that("greater than rejects lower value", !evaluate(gtRule, below).isValid),53 Test.that("greater than rejects equal value", !evaluate(gtRule, equal).isValid),54 Test.that("greater than accepts higher value", evaluate(gtRule, above).isValid),55 Test.that("greater or equal accepts boundary", evaluate(geRule, equal).isValid),56 Test.that("greater or equal rejects below", !evaluate(geRule, below).isValid),57 Test.that("less than accepts lower value", evaluate(ltRule, below).isValid),58 Test.that("less than rejects boundary", !evaluate(ltRule, equal).isValid),59 Test.that("less or equal accepts boundary", evaluate(leRule, equal).isValid),60 Test.that("less or equal rejects above", !evaluate(leRule, above).isValid),61 Test.equals("bound follows current source", &changedFailure.errors[0].errorMessage,62 &"Value must be greater than 7 from bound."),63 Test.that("generic equality accepts text", Validator.validate(64 &Validator.add(Validator.create(), Rule.build(textRule)), below).isValid),65 Test.equals("text comparison renders selected field", &textFailure.errors[0].errorMessage,66 &"Value must equal other from confirmation."),67 Test.equals("comparison selector runs once on failure", &Sync.count(&calls), &Ok(1)),68 Test.equals("captured comparison value renders", &countedFailure.errors[0].errorMessage,69 &"Value must be greater than 5 from bound."),70 Test.equals("caller argument overrides captured value", &overridden.errors[0].errorMessage,71 &"Value must equal hidden from bound.")72 ])73 Test.report(&Test.run(&checks))74}75