Skip to content

Instantly share code, notes, and snippets.

@NDiiong
Forked from saberone/Validation.cs
Created June 24, 2020 16:44
Show Gist options
  • Save NDiiong/d6f60fd6c04a122a08dffe776f3e6012 to your computer and use it in GitHub Desktop.
Save NDiiong/d6f60fd6c04a122a08dffe776f3e6012 to your computer and use it in GitHub Desktop.
A Quick hack for a simple validation using yield. The idea is to create a very clean api/interface. Some Unit tests are included, but they are far from thorough.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Configuration;
using System.Web.Security;
namespace Validation
{
public interface IValidator <T>
{
IValidator<T> AddRule(IValidationRule<T> validationRule);
IEnumerable<IValidationRule<T>> Rules { get; }
}
public class BaseValidation<T> : IValidator<T>
{
private List<IValidationRule<T>> _rules;
public BaseValidation()
{
_rules = new List<IValidationRule<T>>();
}
public IValidator<T> AddRule(IValidationRule<T> validationRule)
{
_rules.Add(validationRule);
return this;
}
public IEnumerable<IValidationRule<T>> Rules {
get { return _rules; }
}
public IEnumerable<ValidationResult> Validate(T validationSubject)
{
var validationResult = new List<ValidationResult>();
foreach (var validationRule in Rules)
{
validationResult.AddRange(validationRule.Validate(validationSubject));
}
return validationResult;
}
}
public interface IValidationRule<T>
{
IEnumerable<ValidationResult> Validate(T subjectForValidation);
string Description { get; }
}
public class ValidationRule
{
}
public class ValidationResult
{
public bool Valid { get; set; }
public string Reason { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Validation;
namespace ValidationTest
{
[TestClass]
public class BaseValidationTest
{
[TestMethod]
public void TestAddingOfRule()
{
var baseValidation = new BaseValidation<ValidationSubject>();
baseValidation.AddRule(new ValueShouldBeEqualOrBiggerThan10Rule())
.AddRule(new ValueShouldBeEqualOrBiggerThan10Rule());
Assert.AreEqual(2, baseValidation.Rules.Count());
}
[TestMethod]
public void TestMultipleRulesValidation()
{
var validationSubject = new ValidationSubject {Name = "Piet Pietersen", Value = 20};
var baseValidation = new BaseValidation<ValidationSubject>();
baseValidation.AddRule(new ValueShouldBeEqualOrBiggerThan10Rule())
.AddRule(new NameShouldContainJanRule())
.AddRule(new NameShouldContainJanAndValueIs5Rule());
IEnumerable<ValidationResult> validationResults = baseValidation.Validate(validationSubject);
Assert.AreEqual(1, 1);
}
}
[TestClass]
public class ValidationRuleTest
{
[TestMethod]
public void TestRuleWithSingleValidation()
{
var validationSubject = new ValidationSubject {Name = "Piet Pietersen", Value = 20};
var rule = new NameShouldContainJanRule();
IEnumerable<ValidationResult> validationResults = rule.Validate(validationSubject);
IList<ValidationResult> enumerable = validationResults as IList<ValidationResult> ??
validationResults.ToList();
Assert.AreEqual(1, enumerable.Count());
Assert.AreEqual(false, enumerable.First().Valid);
Assert.AreEqual("Doesn't contain Jan", enumerable.First().Reason);
}
[TestMethod]
public void TestRuleWithMultipleValidation()
{
var validationSubject = new ValidationSubject {Name = "Piet Pietersen", Value = 20};
var rule = new NameShouldContainJanAndValueIs5Rule();
IEnumerable<ValidationResult> validationResults = rule.Validate(validationSubject);
IList<ValidationResult> enumerable = validationResults as IList<ValidationResult> ??
validationResults.ToList();
Assert.AreEqual(2, enumerable.Count());
}
}
public class ValueShouldBeEqualOrBiggerThan10Rule : IValidationRule<ValidationSubject>
{
public IEnumerable<ValidationResult> Validate(ValidationSubject subjectForValidation)
{
if (subjectForValidation.Value >= 10)
{
yield return new ValidationResult {Valid = true};
}
else
{
yield return new ValidationResult {Valid = false, Reason = "Value is smaller than 10"};
}
}
public string Description
{
get { return "Value should be equal or bigger than 10"; }
}
}
public class NameShouldContainJanRule : IValidationRule<ValidationSubject>
{
public IEnumerable<ValidationResult> Validate(ValidationSubject subjectForValidation)
{
if (subjectForValidation.Name.Contains("Jan"))
{
yield return new ValidationResult {Valid = true};
}
else
{
yield return new ValidationResult {Valid = false, Reason = "Doesn't contain Jan"};
}
}
public string Description
{
get { return "Name should contain Jan"; }
}
}
public class NameShouldContainJanAndValueIs5Rule : IValidationRule<ValidationSubject>
{
public IEnumerable<ValidationResult> Validate(ValidationSubject subjectForValidation)
{
if (subjectForValidation.Name.Contains("Jan"))
{
yield return new ValidationResult {Valid = true};
}
else
{
yield return new ValidationResult {Valid = false, Reason = "Doesn't contain Jan"};
}
if (subjectForValidation.Value == 5)
{
yield return new ValidationResult {Valid = true};
}
else
{
yield return new ValidationResult {Valid = false, Reason = "Value should be 5"};
}
}
public string Description
{
get { return "Name should contain Jan and value should be 5"; }
}
}
public class ValidationSubject
{
public string Name { get; set; }
public int Value { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment