public void ShouldValidateComposition_MultiNested_ImplicitEngine() { var builder = new Fluent.FluentBuilder(); builder.For <Foo>() .Setup(f => f.Value) .MustEqual(1) .EndSetup() .If(f => f.Foo1 != null) .If(f => f.Foo1 != null) .If(f => f.Foo1 != null) .Setup(f => f.Foo1) .CallValidate(); builder.For <Foo>() .If(f => f.Foo2 != null) .If(f => f.Foo2 != null) .If(f => f.Foo2 != null) .Setup(f => f.Foo2) .CallValidate(); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(1), Foo2 = new Foo(1) }; Assert.IsTrue(engine.Validate(foo)); foo.Foo2.Value = 3; Assert.IsFalse(engine.Validate(foo)); }
public void TestMessageInheritedClass2() { //NOTE: Same as TestMessageInheritedClass, with order of registrations changed. var builder = new Fluent.FluentBuilder(); builder.For <ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A"); builder.For <ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For <ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2, 0, 0); report.Validate(obj); Assert.AreEqual("ClassC validation for A", report.GetErrorMessage(obj, o => o.A)); }
public void ShouldValidateComposition_MultiNested_ImplicitEngine() { var builder = new Fluent.FluentBuilder(); builder.For<Foo>() .Setup(f => f.Value) .MustEqual(1) .EndSetup() .If(f => f.Foo1 != null) .If(f => f.Foo1 != null) .If(f => f.Foo1 != null) .Setup(f => f.Foo1) .CallValidate(); builder.For<Foo>() .If(f => f.Foo2 != null) .If(f => f.Foo2 != null) .If(f => f.Foo2 != null) .Setup(f => f.Foo2) .CallValidate(); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(1), Foo2 = new Foo(1) }; Assert.IsTrue(engine.Validate(foo)); foo.Foo2.Value = 3; Assert.IsFalse(engine.Validate(foo)); }
public void ShouldCopySpecificRules() { var baseBuilder = new Fluent.FluentBuilder(); baseBuilder.For <Foo1>() .Setup(f => f.Value) .MustEqual(1); baseBuilder.For <Foo2>() .Setup(f => f.Value) .MustEqual(2); baseBuilder.For <Foo3>() .Setup(f => f.Value) .MustEqual(3); var builder = new Fluent.FluentBuilder(); var engine1 = builder.Build(baseBuilder, typeof(Foo1), typeof(Foo3)); //Engine1 now has rules of baseEngine (only Foo1 and Foo3). Assert.IsFalse(engine1.Validate(new Foo1(0))); Assert.IsTrue(engine1.Validate(new Foo1(1))); Assert.IsTrue(engine1.Validate(new Foo3(3))); Assert.IsFalse(engine1.Validate(new Foo3(0))); Assert.IsTrue(engine1.Validate(new Foo2(2))); Assert.IsTrue(engine1.Validate(new Foo2(0))); Assert.IsTrue(engine1.Validate(new Foo2(1))); }
public void ShouldValidateUsingOtherRulesEngine() { var builder = new Fluent.FluentBuilder(); builder.For <Foo>() .Setup(f => f.Prop1) .MustEqual(8); var fooEngine = builder.Build(); var builder2 = new Fluent.FluentBuilder(); builder2.For <Container>() .Setup(c => c.Foos) .CallValidateForEachElement(fooEngine); var containerEngine = builder2.Build(); Assert.IsTrue(fooEngine.Validate(new Foo(8))); Assert.IsFalse(fooEngine.Validate(new Foo(7))); Assert.IsTrue(containerEngine.Validate(new Container(new Foo(8), new Foo(8), new Foo(8)))); //Should not be valid if any of the Foo's is invalid in the collection. Assert.IsFalse(containerEngine.Validate(new Container(new Foo(7), new Foo(8), new Foo(8)))); Assert.IsFalse(containerEngine.Validate(new Container(new Foo(8), new Foo(7), new Foo(8)))); Assert.IsFalse(containerEngine.Validate(new Container(new Foo(8), new Foo(8), new Foo(7)))); }
public void ShouldWorkWithConditions2() { var builder = new Fluent.FluentBuilder(); builder.For <ConditionalData>() .If(m => m.A > 10) .Setup(m => m.B) .MustBeGreaterThan(5) .Else() .Setup(m => m.B) .MustBeLessThan(5) .EndIf(); var data1 = new ConditionalData(11, 0, 0); var data2 = new ConditionalData(11, 6, 0); var data3 = new ConditionalData(0, 0, 0); var data4 = new ConditionalData(0, 6, 0); var engine = builder.Build(); Assert.IsFalse(engine.Validate(data1)); Assert.IsTrue(engine.Validate(data2)); Assert.IsTrue(engine.Validate(data3)); Assert.IsFalse(engine.Validate(data4)); }
public void TestMessageInheritedClass4() { //NOTE: This test is the same as No.3, with definition of rules order changed. var builder = new Fluent.FluentBuilder(); builder.For <ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); builder.For <ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For <ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A.1") .MustBeLessThan(-1) .WithMessage("ClassC validation for A.2"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2, 0, 0); report.Validate(obj); //m=>m.A will hit A.1 because the rules for base types are executed first. m=>m.A will fail because of rule defined on ClassA!. Assert.AreEqual("ClassC validation for A.1", report.GetErrorMessage(obj, o => o.A)); report = new ValidationReport(engine); obj = new ClassC(1, 0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); //m=>m.A will hit A.2 because the rules for base types are fine. m=>m.A will fail because of rule defined on ClassC!. Assert.AreEqual("ClassC validation for A.2", report.GetErrorMessage(obj, o => o.A)); }
public void ShouldCopyAllRules() { var baseBuilder = new Fluent.FluentBuilder(); baseBuilder.For <Foo1>() .Setup(f => f.Value) .MustBeGreaterThan(0); baseBuilder.For <Foo2>() .Setup(f => f.Value) .MustEqual(6); var baseEngine = baseBuilder.Build(); Assert.IsFalse(baseEngine.Validate(new Foo1(-1))); Assert.IsFalse(baseEngine.Validate(new Foo2(1))); var builder = new Fluent.FluentBuilder(); builder.For <Foo1>() .Setup(f => f.Value) .MustBeLessThan(10); var engine1 = builder.Build(baseBuilder); //Engine1 now has rules of baseEngine in addition to its own. Assert.IsFalse(engine1.Validate(new Foo1(-1))); Assert.IsFalse(engine1.Validate(new Foo1(10))); Assert.IsTrue(engine1.Validate(new Foo1(9))); Assert.IsFalse(engine1.Validate(new Foo2(2))); Assert.IsTrue(engine1.Validate(new Foo2(6))); }
public void ShouldValidateUsingOtherRulesEngine() { var builder = new Fluent.FluentBuilder(); builder.For<Foo>() .Setup(f => f.Prop1) .MustEqual(8); var fooEngine = builder.Build(); var builder2 = new Fluent.FluentBuilder(); builder2.For<Container>() .Setup(c => c.Foos) .CallValidateForEachElement(fooEngine); var containerEngine = builder2.Build(); Assert.IsTrue(fooEngine.Validate(new Foo(8))); Assert.IsFalse(fooEngine.Validate(new Foo(7))); Assert.IsTrue(containerEngine.Validate(new Container(new Foo(8), new Foo(8), new Foo(8)))); //Should not be valid if any of the Foo's is invalid in the collection. Assert.IsFalse(containerEngine.Validate(new Container(new Foo(7), new Foo(8), new Foo(8)))); Assert.IsFalse(containerEngine.Validate(new Container(new Foo(8), new Foo(7), new Foo(8)))); Assert.IsFalse(containerEngine.Validate(new Container(new Foo(8), new Foo(8), new Foo(7)))); }
public void TestMessageInheritedClass3() { var builder = new Fluent.FluentBuilder(); builder.For <ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); builder.For <ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For <ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A.1") .MustBeLessThan(-1) .WithMessage("ClassC validation for A.2"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2, 0, 0); report.Validate(obj); //m=>m.A will hit A.1 because the rules for base types are executed first. m=>m.A will fail because of rule defined on ClassA!. Assert.AreEqual("ClassC validation for A.1", report.GetErrorMessage(obj, o => o.A)); obj = new ClassC(1, 0, 0); report.Validate(obj); //m=>m.A will hit A.2 because the rules for base types are fine. m=>m.A will fail because of rule defined on ClassC!. Assert.AreEqual("ClassC validation for A.2", report.GetErrorMessage(obj, o => o.A)); }
public void ShouldFindErrorMessage2() { var builder = new Fluent.FluentBuilder(); builder.For <CompositeClass>() .Setup(c => c.Value) .MustBeGreaterThan(0) .Setup(c => c.C) .MustNotBeNull() .Setup(c => c.C.C) .WithMessage("Composed value is not valid") .MustBeBetween(1, 10, Rules.BetweenRuleBoundsOption.BothInclusive) ; var engine = builder.Build(); var o = new CompositeClass() { C = new ClassC() }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("Composed value is not valid", r.GetErrorMessage(o.C, f => f.C)); //NOTE: There are no errors on ClassC! Should return null. Assert.IsNull(r.GetErrorMessage(o, f => f.C.C)); }
public void ShouldFindErrorMessageWithNestedIF_Else() { var builder = new Fluent.FluentBuilder(); builder.For <ClassC>() .If(c => c.C > 1) .If(c => c.C > 2) .If(c => c.C > 5) .Setup(c => c.C) .WithMessage("C is not valid. >5") .MustEqual(18) .Else() .Setup(c => c.C) .WithMessage("C is not valid. <5") .MustEqual(1); var engine = builder.Build(); var o = new ClassC() { C = 4 }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("C is not valid. <5", r.GetErrorMessage(o, f => f.C)); }
public void TestMessagesCount() { var builder = new Fluent.FluentBuilder(); builder.For <MyMessageTestClass>() .WithMessage("Object is not valid") .Setup(m => m.A) .WithMessage("Property A is not valid.") .MustBeBetween(1, 10) .Setup(m => m.B) .WithMessage("Property B is not valid.") .MustBeBetween(1, 10); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new MyMessageTestClass(0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual(2, report.GetErrorMessages(obj).Length); obj = new MyMessageTestClass(0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual(2, report.GetErrorMessages(obj).Length); //There should be a total of 4 error messages... Assert.AreEqual(4, report.GetErrorMessages().Length); }
public void ShouldValidateComposition_Explicit() { //TODO: Redo this test!!! CallValidate() = implicit call. Build an entirely new engine for the explicit test. var builder = new Fluent.FluentBuilder(); builder.For <Foo>() .Setup(f => f.Value) .MustEqual(1) .EndSetup() .If(f => f.Foo1 != null) .Setup(f => f.Foo1) .CallValidate() .EndIf() .If(f => f.Foo2 != null) .Setup(f => f.Foo2) .CallValidate(); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(1), Foo2 = new Foo(1) }; Assert.IsTrue(engine.Validate(foo)); foo.Foo2.Value = 3; Assert.IsFalse(engine.Validate(foo)); }
public void ShouldValidate() { var builder = new Fluent.FluentBuilder(); builder.For <ClassA>().Setup(a => a.A).MustBeGreaterThan(0); var engine = builder.Build(); var report = new ValidationReport(engine); Assert.IsFalse(report.Validate(new ClassA())); }
public void TestNotEqualRuleCrossField1() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <int> >() .Setup(m => m.Value1) .MustNotEqual(m => m.Value2); var engine = builder.Build(); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(1, 2))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(4, 4))); }
public void TestGenericRule() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <int> >() .Setup(m => m.Value1) .MustPassGenericRule(m => m > 10); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(9))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(14))); }
public void TestReferenceNotNull() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <object> >() .Setup(m => m.Value1) .MustNotBeNull(); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyDomainObject <object>(null))); Assert.IsTrue(engine.Validate(new MyDomainObject <object>(new object()))); }
public void TestNullableNotNull() { var builder = new Fluent.FluentBuilder(); builder.For <MyNullableContainer <int> >() .Setup(m => m.Value) .MustNotBeNull(); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyNullableContainer <int>(null))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(1))); }
public void TestInitialize() { var builder = new Fluent.FluentBuilder(); builder.For <Foo>() .Setup(f => f.Prop1) .MustBeLessThan(10); builder.For <Container>() .Setup(c => c.Foos) .MustNotBeNull() .CallValidateForEachElement(); _re = builder.Build(); }
public void TestMessageForSpecificRule() { var builder = new Fluent.FluentBuilder(); builder.For<MyMessageTestClass>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("Must be Less Than or equal to {0}"); var engine = builder.Build(); var report = new TestingValidationReport(engine); var obj = new MyMessageTestClass(2, 2); report.Validate(obj); report.AssertError(obj, o => o.A, RuleKinds.LessThanOrEqualToRule, 1); }
public void TestInitialize() { var builder = new Fluent.FluentBuilder(); builder.For<Foo>() .Setup(f => f.Prop1) .MustBeLessThan(10); builder.For<Container>() .Setup(c => c.Foos) .MustNotBeNull() .CallValidateForEachElement(); _re = builder.Build(); }
public void TestLessThanRule1() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <int> >() .Setup(m => m.Value1) .MustBeLessThan(2); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(3))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(2))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(1))); }
public void ShouldBlameExplicitlySelectedCulprit_BlameIsAfterTheRule() { var builder = new Fluent.FluentBuilder(); builder.For<Person>() .Setup(p => p.FirstName) .MustBeOneOf("John", "Paul", "James") .Blame(p => p.HomeAddress, a => a.Line1); var engine = builder.Build(); var report = new TestingValidationReport(engine); var address = MakeAddress("18 Perkins St", null, "1234", "Brisbane"); report.Validate(MakePerson("Jane", "Holland", address)); report.AssertError(address, m => m.Line1, RuleKinds.OneOfRule, null); }
public void ShouldShortCircuit() { var builder = new Fluent.FluentBuilder(); builder.For<Member>() .MustPassGenericRule(m => { throw new AssertFailedException("Should have short-circuited."); }); var en2 = builder.Build(_builder1); var member1 = new Member(null); var memberNameExp = ExpressionHelper.New<Member, string>(mm => mm.Name); var report = new ValidationReport(); //Only short-circuit here would work...Others would throw exception... _en1.Validate(member1, report, ValidationReportDepth.ShortCircuit); }
public void ShouldShortCircuit() { var builder = new Fluent.FluentBuilder(); builder.For <Member>() .MustPassGenericRule(m => { throw new Exception("Should have short-circuited."); }); var en2 = builder.Build(_builder1); var member1 = new Member(null); var memberNameExp = ExpressionHelper.New <Member, string>(mm => mm.Name); var report = new ValidationReport(); //Only short-circuit here would work...Others would throw exception... _en1.Validate(member1, report, ValidationReportDepth.ShortCircuit); }
public void TestBetweenRuleLowerExclusiveUpperInclusive() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <int> >() .Setup(m => m.Value1) .MustBeBetween(5, 10, Rules.BetweenRuleBoundsOption.LowerExclusiveUpperInclusive); var engine = builder.Build(); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(6))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(5))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(10))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(4))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(11))); }
public void TestMessageForSpecificRule() { var builder = new Fluent.FluentBuilder(); builder.For <MyMessageTestClass>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("Must be Less Than or equal to {0}"); var engine = builder.Build(); var report = new TestingValidationReport(engine); var obj = new MyMessageTestClass(2, 2); report.Validate(obj); report.AssertError(obj, o => o.A, RuleKinds.LessThanOrEqualToRule, 1); }
public void TestMustBeOfType() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <object> >() .Setup(m => m.Value1) .MustBeOfType(typeof(ApplicationException)); var engine = builder.Build(); Assert.IsTrue(engine.Validate(new MyDomainObject <object>(new ApplicationException()))); Assert.IsTrue(engine.Validate(new MyDomainObject <object>(new System.Reflection.TargetException()))); Assert.IsFalse(engine.Validate(new MyDomainObject <object>(new Exception()))); Assert.IsFalse(engine.Validate(new MyDomainObject <object>("123"))); Assert.IsFalse(engine.Validate(new MyDomainObject <object>(null))); }
public void ShouldBlameExplicitlySelectedCulprit_BlameIsAfterTheRule() { var builder = new Fluent.FluentBuilder(); builder.For <Person>() .Setup(p => p.FirstName) .MustBeOneOf("John", "Paul", "James") .Blame(p => p.HomeAddress, a => a.Line1); var engine = builder.Build(); var report = new TestingValidationReport(engine); var address = MakeAddress("18 Perkins St", null, "1234", "Brisbane"); report.Validate(MakePerson("Jane", "Holland", address)); report.AssertError(address, m => m.Line1, RuleKinds.OneOfRule, null); }
public void TestMustNotBeOneOfRule() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <int> >() .Setup(m => m.Value1) .MustNotBeOneOf(2, 5, 8, 9); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(2))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(5))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(8))); Assert.IsFalse(engine.Validate(new MyDomainObject <int>(9))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(1))); Assert.IsTrue(engine.Validate(new MyDomainObject <int>(4))); }
public void TestMustNotBeOneOfRule_CaseInsensitive() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <string> >() .Setup(m => m.Value1) .MustNotBeOneOf(StringComparer.OrdinalIgnoreCase, "BOB", "Paul", "JanE", "Sally"); var engine = builder.Build(); Assert.IsFalse(engine.Validate(new MyDomainObject <string>("bob"))); Assert.IsFalse(engine.Validate(new MyDomainObject <string>("PAUL"))); Assert.IsFalse(engine.Validate(new MyDomainObject <string>("Sally"))); Assert.IsFalse(engine.Validate(new MyDomainObject <string>("Jane"))); Assert.IsTrue(engine.Validate(new MyDomainObject <string>("Ringo"))); Assert.IsTrue(engine.Validate(new MyDomainObject <string>("Bono"))); }
public void TestMustPassRegex() { var builder = new Fluent.FluentBuilder(); builder.For <MyDomainObject <string> >() .Setup(m => m.Value1) .MustMatchRegex("^A+$", System.Text.RegularExpressions.RegexOptions.IgnoreCase); var engine = builder.Build(); Assert.IsTrue(engine.Validate(new MyDomainObject <string>("AAAAAAAA"))); Assert.IsTrue(engine.Validate(new MyDomainObject <string>("aaaaaa"))); //NOTE: If the string is null, then Regex should still validate. Assert.IsTrue(engine.Validate(new MyDomainObject <string>(null))); Assert.IsFalse(engine.Validate(new MyDomainObject <string>(""))); Assert.IsFalse(engine.Validate(new MyDomainObject <string>("BBBB"))); }
public ValidationDepthTests() { _builder1 = new Fluent.FluentBuilder(); _builder1.For <Member>() .Setup(m => m.Name) .MustNotBeNull() .EndSetup(); _builder1.For <Club>() .Setup(c => c.President) .MustNotBeNull() .CallValidate() .Setup(c => c.Members) .MustNotBeNull() .CallValidateForEachElement() ; _en1 = _builder1.Build(); }
public void TestInitialize() { var builder = new Fluent.FluentBuilder(); builder.For <ClassA>() .Setup(a => a.ParamA) .MustBeLessThan(1000); builder.For <ClassB>() .Setup(b => b.ParamB) .MustBeLessThan(1000); builder.For <ClassC>() .Setup(c => c.ParamC) .MustBeLessThan(1000) .Setup(c => c.ParamA) .MustBeLessThan(250); _re = builder.Build(); }
public void TestInitialize() { var builder = new Fluent.FluentBuilder(); builder.For<ClassA>() .Setup(a => a.ParamA) .MustBeLessThan(1000); builder.For<ClassB>() .Setup(b => b.ParamB) .MustBeLessThan(1000); builder.For<ClassC>() .Setup(c => c.ParamC) .MustBeLessThan(1000) .Setup(c => c.ParamA) .MustBeLessThan(250); _re = builder.Build(); }
public void ShouldCulpabiliseComposition() { var builder = new Fluent.FluentBuilder(); builder.For <Foo>() .Setup(f => f.Foo1.Value) .MustEqual(1); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(0) }; var report = new ValidationReport(engine); Assert.IsFalse(report.Validate(foo)); ValidationError[] errors; Assert.IsTrue(report.HasError(foo.Foo1, f => f.Value, out errors)); }
public ValidationDepthTests() { _builder1 = new Fluent.FluentBuilder(); _builder1.For<Member>() .Setup(m => m.Name) .MustNotBeNull() .EndSetup(); _builder1.For<Club>() .Setup(c => c.President) .MustNotBeNull() .CallValidate() .Setup(c => c.Members) .MustNotBeNull() .CallValidateForEachElement() ; _en1 = _builder1.Build(); }
public void SimpleInterfaceTest() { var builder = new Fluent.FluentBuilder(); builder.For<IMyClass>() .Setup(m => m.A) .MustBeGreaterThan(0); var engine = builder.Build(); var report = new TestingValidationReport(engine); var o1 = new MyClass(0); Assert.IsFalse(report.Validate(o1)); Assert.AreEqual(1, report.Errors.Length); report.AssertError<IMyClass, int>(o1, p1 => p1.A, RuleKinds.GreaterThanRule, 0); var o2 = new MyClassExplicit(0); Assert.IsFalse(report.Validate(o2)); Assert.AreEqual(1, report.Errors.Length); report.AssertError<IMyClass, int>(o2, p1 => p1.A, RuleKinds.GreaterThanRule, 0); }
public void ShouldBlameExplicitlySelectedCulprit_DifferentCulpritForDifferentRules() { var builder = new Fluent.FluentBuilder(); builder.For<Person>() .Setup(p => p.FirstName) .MustNotEqual("Paul") .Blame(p => p.HomeAddress, a => a.Line1) .MustNotEqual("Peter") .Blame(p => p.HomeAddress, a => a.PostCode); var engine = builder.Build(); var report = new TestingValidationReport(engine); var address = MakeAddress("18 Perkins St", null, "1234", "Brisbane"); report.Validate(MakePerson("Paul", "Holland", address)); report.AssertError(address, m => m.Line1, RuleKinds.NotEqualRule, null); report.Clear(); report.Validate(MakePerson("Peter", "Holland", address)); report.AssertError(address, m => m.PostCode, RuleKinds.NotEqualRule, null); }
public void ShouldFindErrorMessage2() { var builder = new Fluent.FluentBuilder(); builder.For<CompositeClass>() .Setup(c => c.Value) .MustBeGreaterThan(0) .Setup(c => c.C) .MustNotBeNull() .Setup(c => c.C.C) .WithMessage("Composed value is not valid") .MustBeBetween(1, 10, Rules.BetweenRuleBoundsOption.BothInclusive) ; var engine = builder.Build(); var o = new CompositeClass() { C = new ClassC() }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("Composed value is not valid", r.GetErrorMessage(o.C, f => f.C)); //NOTE: There are no errors on ClassC! Should return null. Assert.IsNull(r.GetErrorMessage(o, f => f.C.C)); }
public void TestMessageInheritedClass() { var builder = new Fluent.FluentBuilder(); builder.For<ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); builder.For<ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For<ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2,0,0); report.Validate(obj); Assert.AreEqual("ClassC validation for A", report.GetErrorMessage(obj, o => o.A)); }
public void ShouldValidateComposition_Explicit() { //TODO: Redo this test!!! CallValidate() = implicit call. Build an entirely new engine for the explicit test. var builder = new Fluent.FluentBuilder(); builder.For<Foo>() .Setup(f => f.Value) .MustEqual(1) .EndSetup() .If(f => f.Foo1 != null) .Setup(f => f.Foo1) .CallValidate() .EndIf() .If(f => f.Foo2 != null) .Setup(f => f.Foo2) .CallValidate(); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(1), Foo2 = new Foo(1) }; Assert.IsTrue(engine.Validate(foo)); foo.Foo2.Value = 3; Assert.IsFalse(engine.Validate(foo)); }
public void ShouldWorkWithConditions2() { var builder = new Fluent.FluentBuilder(); builder.For<ConditionalData>() .If(m => m.A > 10) .Setup(m => m.B) .MustBeGreaterThan(5) .Else() .Setup(m => m.B) .MustBeLessThan(5) .EndIf(); var data1 = new ConditionalData(11, 0, 0); var data2 = new ConditionalData(11, 6, 0); var data3 = new ConditionalData(0, 0, 0); var data4 = new ConditionalData(0, 6, 0); var engine = builder.Build(); Assert.IsFalse(engine.Validate(data1)); Assert.IsTrue(engine.Validate(data2)); Assert.IsTrue(engine.Validate(data3)); Assert.IsFalse(engine.Validate(data4)); }
public void TestMessageForProperty() { var builder = new Fluent.FluentBuilder(); builder.For<MyMessageTestClass>() .WithMessage("Object is not valid") .Setup(m => m.A) .WithMessage("Property A is not valid.") .MustBeLessThanOrEqualTo(10) .MustNotEqual(5) .MustNotEqual(0) .WithMessage("Must not equal zero") .Setup(m => m.B) .MustEqual(0); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new MyMessageTestClass(11, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual("Property A is not valid.", report.GetErrorMessage(obj, o => o.A)); report = new ValidationReport(engine); obj = new MyMessageTestClass(5, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual("Property A is not valid.", report.GetErrorMessage(obj, o => o.A)); report = new ValidationReport(engine); obj = new MyMessageTestClass(0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual("Must not equal zero", report.GetErrorMessage(obj, o => o.A)); report = new ValidationReport(engine); obj = new MyMessageTestClass(9, 1); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual("Object is not valid", report.GetErrorMessage(obj, o => o.B)); }
public void TestMessagesCount() { var builder = new Fluent.FluentBuilder(); builder.For<MyMessageTestClass>() .WithMessage("Object is not valid") .Setup(m => m.A) .WithMessage("Property A is not valid.") .MustBeBetween(1, 10) .Setup(m => m.B) .WithMessage("Property B is not valid.") .MustBeBetween(1, 10); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new MyMessageTestClass(0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual(2, report.GetErrorMessages(obj).Length); obj = new MyMessageTestClass(0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); Assert.AreEqual(2, report.GetErrorMessages(obj).Length); //There should be a total of 4 error messages... Assert.AreEqual(4, report.GetErrorMessages().Length); }
public void ShouldFindErrorMessageWithNestedIF_Else() { var builder = new Fluent.FluentBuilder(); builder.For<ClassC>() .If(c => c.C > 1) .If(c => c.C > 2) .If(c => c.C > 5) .Setup(c => c.C) .WithMessage("C is not valid. >5") .MustEqual(18) .Else() .Setup(c => c.C) .WithMessage("C is not valid. <5") .MustEqual(1); var engine = builder.Build(); var o = new ClassC() { C = 4 }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("C is not valid. <5", r.GetErrorMessage(o, f => f.C)); }
public void ShouldValidate() { var builder = new Fluent.FluentBuilder(); builder.For<ClassA>().Setup(a => a.A).MustBeGreaterThan(0); var engine = builder.Build(); var report = new ValidationReport(engine); Assert.IsFalse(report.Validate(new ClassA())); }
//TODO: Blame Culprit when using composition! //[TestMethod] public void ShouldBlameExplicitlySelectedCulprit_Composition() { var builder = new Fluent.FluentBuilder(); builder.For<Person>() .Setup(p => p.HomeAddress) .CallValidate() .Blame(p => p.FirstName); builder.For<Address>() .Setup(a => a.Line1) .MustEqual("Line1"); var engine = builder.Build(); var report = new TestingValidationReport(engine); var address = MakeAddress("Not Line 1", null, "1234", "Brisbane"); var person = MakePerson("Blinky", "Bill", address); report.Validate(person); report.AssertError(person, m => m.FirstName, RuleKinds.EqualRule, "Line1"); }
public void TestMessageInheritedClass3() { var builder = new Fluent.FluentBuilder(); builder.For<ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); builder.For<ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For<ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A.1") .MustBeLessThan(-1) .WithMessage("ClassC validation for A.2"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2, 0, 0); report.Validate(obj); //m=>m.A will hit A.1 because the rules for base types are executed first. m=>m.A will fail because of rule defined on ClassA!. Assert.AreEqual("ClassC validation for A.1", report.GetErrorMessage(obj, o => o.A)); obj = new ClassC(1, 0, 0); report.Validate(obj); //m=>m.A will hit A.2 because the rules for base types are fine. m=>m.A will fail because of rule defined on ClassC!. Assert.AreEqual("ClassC validation for A.2", report.GetErrorMessage(obj, o => o.A)); }
public void ShouldFindErrorMessage4() { var builder = new Fluent.FluentBuilder(); builder.For<ClassC>() .Setup(c => c.C) .WithMessage("C is not valid") .MustBeBetween(1, 10, Rules.BetweenRuleBoundsOption.BothInclusive); builder.For<CompositeClass>() .Setup(c => c.Value) .MustBeGreaterThan(0) .Setup(c => c.C) .MustNotBeNull() .WithMessage("C Must not be null") .CallValidate() .WithMessage("Composed value is not valid"); var engine = builder.Build(); var o = new CompositeClass() { C = new ClassC() }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("Composed value is not valid", r.GetErrorMessage(o, f => f.C)); Assert.AreEqual("C is not valid", r.GetErrorMessage(o.C, f => f.C)); var o1 = new CompositeClass() { C = null }; var r1 = new ValidationReport(engine); r1.Validate(o1); Assert.AreEqual("C Must not be null", r1.GetErrorMessage(o1, f => f.C)); }
public void ShouldCulpabiliseComposition() { var builder = new Fluent.FluentBuilder(); builder.For<Foo>() .Setup(f => f.Foo1.Value) .MustEqual(1); var engine = builder.Build(); var foo = new Foo(1) { Foo1 = new Foo(0) }; var report = new ValidationReport(engine); Assert.IsFalse(report.Validate(foo)); ValidationError[] errors; Assert.IsTrue(report.HasError(foo.Foo1, f => f.Value, out errors)); }
public void ShouldFindErrorMessage3() { var builder = new Fluent.FluentBuilder(); builder.For<ClassC>().WithMessage("ClassC is not valid") .Setup(c => c.C) .MustBeBetween(1, 10); builder.For<CompositeClass>() .Setup(c => c.C) .CallValidate(); var engine = builder.Build(); var o = new CompositeClass() { C = new ClassC() }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("ClassC is not valid", r.GetErrorMessage(o, f => f.C)); }
public void ShouldFindErrorMessageWithNestedIF() { var builder = new Fluent.FluentBuilder(); builder.For<ClassC>() .If(c => c.C > 10) .If(c => c.C > 11) .If(c => c.C > 12) .Setup(c => c.C) .WithMessage("C is not valid. >12") .MustBeBetween(10, 15); var engine = builder.Build(); var o = new ClassC() { C = 20 }; var r = new ValidationReport(engine); r.Validate(o); Assert.AreEqual("C is not valid. >12", r.GetErrorMessage(o, f => f.C)); }
public void TestMessageInheritedClass4() { //NOTE: This test is the same as No.3, with definition of rules order changed. var builder = new Fluent.FluentBuilder(); builder.For<ClassA>() .Setup(m => m.A) .MustBeLessThanOrEqualTo(1) .WithMessage("ClassA validation for A"); builder.For<ClassB>() .Setup(m => m.A) .WithMessage("ClassB validation for A"); builder.For<ClassC>() .Setup(m => m.A) .WithMessage("ClassC validation for A.1") .MustBeLessThan(-1) .WithMessage("ClassC validation for A.2"); var engine = builder.Build(); var report = new ValidationReport(engine); var obj = new ClassC(2, 0, 0); report.Validate(obj); //m=>m.A will hit A.1 because the rules for base types are executed first. m=>m.A will fail because of rule defined on ClassA!. Assert.AreEqual("ClassC validation for A.1", report.GetErrorMessage(obj, o => o.A)); report = new ValidationReport(engine); obj = new ClassC(1, 0, 0); engine.Validate(obj, report, ValidationReportDepth.FieldShortCircuit); //m=>m.A will hit A.2 because the rules for base types are fine. m=>m.A will fail because of rule defined on ClassC!. Assert.AreEqual("ClassC validation for A.2", report.GetErrorMessage(obj, o => o.A)); }