├── global.json ├── src └── Checker │ ├── IRuleBuilder.cs │ ├── IChecker.cs │ ├── ICheckRule.cs │ ├── CheckContext.cs │ ├── IPropertyChecker.cs │ ├── CheckFailure.cs │ ├── RuleBuilder.cs │ ├── CheckResult.cs │ ├── IRuleBuilderExtensions.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── NotEmptyChecker.cs │ ├── PropertyCheckContext.cs │ ├── CheckerBase.cs │ ├── LessThanChecker.cs │ ├── Checker.csproj │ ├── ExpressionExtensions.cs │ ├── PropertyRule.cs │ └── Fluent.xUnit.csproj ├── test └── Checker.Test │ ├── User.cs │ ├── UserChecker.cs │ ├── FluentCheckerTest.cs │ └── Checker.Test.csproj ├── LICENSE ├── README.md ├── Checker.sln └── .gitignore /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src", "test" ], 3 | "sdk": { 4 | "version": "1.0.0-preview2-003131" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Checker/IRuleBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi 2 | { 3 | public interface IRuleBuilder 4 | { 5 | IRuleBuilder SetChecker(IPropertyChecker checker); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Checker/IChecker.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi 2 | { 3 | public interface IChecker 4 | { 5 | CheckResult Check(T instance); 6 | 7 | CheckResult Check(CheckContext context); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Checker/ICheckRule.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Checking.FluentApi 4 | { 5 | public interface ICheckRule 6 | { 7 | IEnumerable Check(CheckContext context); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/Checker.Test/User.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi.Test 2 | { 3 | public class User 4 | { 5 | public string Username { get; set; } 6 | public string Password { get; set; } 7 | 8 | public int Age { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Checker/CheckContext.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi 2 | { 3 | public class CheckContext 4 | { 5 | public CheckContext(T instance) 6 | { 7 | InstanceToCheck = instance; 8 | } 9 | 10 | public T InstanceToCheck { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Checker/IPropertyChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Checking.FluentApi 4 | { 5 | public interface IPropertyChecker 6 | { 7 | bool Succeed { get; } 8 | 9 | IEnumerable Checker(PropertyCheckContext context); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Checker/CheckFailure.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi 2 | { 3 | public class CheckFailure 4 | { 5 | public string PropertyName { get; set; } 6 | 7 | public string ErrorMessage { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return ErrorMessage; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Checker.Test/UserChecker.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi.Test 2 | { 3 | public class UserChecker : CheckerBase 4 | { 5 | public UserChecker() 6 | { 7 | RuleFor(u => u.Username).NotEmpty(); 8 | RuleFor(u => u.Password).NotEmpty(); 9 | RuleFor(u => u.Age).LessThan(100); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Checker/RuleBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace Checking.FluentApi 2 | { 3 | internal class RuleBuilder : IRuleBuilder 4 | { 5 | public RuleBuilder(PropertyRule rule) 6 | { 7 | Rule = rule; 8 | } 9 | 10 | public PropertyRule Rule { get; } 11 | 12 | public IRuleBuilder SetChecker(IPropertyChecker checker) 13 | { 14 | Rule.AddChecker(checker); 15 | 16 | return this; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/Checker.Test/FluentCheckerTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Checking.FluentApi.Test 4 | { 5 | public class FluentCheckerTest 6 | { 7 | public void Checking_FluentApi_Test() 8 | { 9 | var user = new User 10 | { 11 | Username = "rigofunc", 12 | Password = "p@ssword", 13 | Age = 31, 14 | }; 15 | 16 | var checker = new UserChecker(); 17 | 18 | var result = checker.Check(user); 19 | 20 | //Assert.IsTrue(result.Succeed); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Checker/CheckResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Checking.FluentApi 5 | { 6 | public class CheckResult 7 | { 8 | private readonly IList errors; 9 | 10 | public bool Succeed => errors.Count == 0; 11 | 12 | public IList Errors => errors; 13 | 14 | public CheckResult() 15 | { 16 | errors = new List(); 17 | } 18 | 19 | public CheckResult(IEnumerable failures) 20 | { 21 | errors = failures.ToList(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/Checker.Test/Checker.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Checking.FluentApi.Test 4 | 5 | 6 | netstandard1.6 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Checker/IRuleBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Checking.FluentApi 4 | { 5 | public static class IRuleBuilderExtensions 6 | { 7 | public static IRuleBuilder NotEmpty(this IRuleBuilder ruleBuilder) 8 | { 9 | return ruleBuilder.SetChecker(new NotEmptyChecker(default(TProperty))); 10 | } 11 | 12 | public static IRuleBuilder LessThan(this IRuleBuilder ruleBuilder, TProperty valueToCompare) 13 | where TProperty : IComparable, IComparable 14 | { 15 | return ruleBuilder.SetChecker(new LessThanChecker(valueToCompare)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Checker/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("Microsoft")] 10 | [assembly: AssemblyProduct("Checker")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("6c774e9b-cf8b-48a6-9481-9668dc460b1f")] 20 | -------------------------------------------------------------------------------- /src/Checker/NotEmptyChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Checking.FluentApi 5 | { 6 | internal class NotEmptyChecker : IPropertyChecker 7 | { 8 | private readonly TProperty @default; 9 | 10 | public NotEmptyChecker(TProperty @default) 11 | { 12 | this.@default = @default; 13 | } 14 | 15 | public bool Succeed { get; private set; } = true; 16 | public IEnumerable Checker(PropertyCheckContext context) 17 | { 18 | if (context.PropertyValue == null || context.PropertyValue.Equals(@default)) 19 | { 20 | Succeed = false; 21 | 22 | return new[] { new CheckFailure { 23 | PropertyName = context.PropertyName, 24 | ErrorMessage = $"The value of { context.PropertyName } connot be empty"} 25 | }.AsEnumerable(); 26 | } 27 | 28 | return Enumerable.Empty(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 love.net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Checker/PropertyCheckContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Checking.FluentApi 4 | { 5 | public class PropertyCheckContext 6 | { 7 | private readonly Lazy propertyValueContainer; 8 | 9 | public PropertyCheckContext(CheckContext parentContext, PropertyRule rule, string propertyName) 10 | { 11 | ParentContext = parentContext; 12 | Rule = rule; 13 | PropertyName = propertyName; 14 | propertyValueContainer = new Lazy(() => rule.PropertyFunc(parentContext.InstanceToCheck)); 15 | } 16 | 17 | public CheckContext ParentContext { get; } 18 | 19 | public PropertyRule Rule { get; } 20 | 21 | public T Instance 22 | { 23 | get 24 | { 25 | return ParentContext.InstanceToCheck; 26 | } 27 | } 28 | 29 | public string PropertyName { get; } 30 | 31 | public TProperty PropertyValue 32 | { 33 | get { return propertyValueContainer.Value; } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Checker/CheckerBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | 6 | namespace Checking.FluentApi 7 | { 8 | public abstract class CheckerBase : IChecker 9 | { 10 | private readonly IList> rules = new List>(); 11 | 12 | public virtual CheckResult Check(CheckContext context) 13 | { 14 | var failures = rules.SelectMany(r => r.Check(context)); 15 | 16 | return new CheckResult(failures); 17 | } 18 | 19 | public virtual CheckResult Check(T instance) 20 | { 21 | return Check(new CheckContext(instance)); 22 | } 23 | 24 | public void AddRule(ICheckRule rule) 25 | { 26 | rules.Add(rule); 27 | } 28 | 29 | public IRuleBuilder RuleFor(Expression> expression) 30 | { 31 | var rule = PropertyRule.Create(expression); 32 | 33 | AddRule(rule); 34 | 35 | return new RuleBuilder(rule); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Checker/LessThanChecker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Checking.FluentApi 6 | { 7 | internal class LessThanChecker : IPropertyChecker where TProperty : IComparable, IComparable 8 | { 9 | private readonly TProperty valueToCompare; 10 | 11 | public LessThanChecker(TProperty valueToCompare) 12 | { 13 | this.valueToCompare = valueToCompare; 14 | } 15 | 16 | public bool Succeed { get; private set; } = true; 17 | 18 | public IEnumerable Checker(PropertyCheckContext context) 19 | { 20 | if (context.PropertyValue.CompareTo(valueToCompare) >= 0) 21 | { 22 | Succeed = false; 23 | 24 | return new[] { new CheckFailure { 25 | PropertyName = context.PropertyName, 26 | ErrorMessage = $"The value of {context.PropertyName} must less then {valueToCompare}"} 27 | }.AsEnumerable(); 28 | } 29 | 30 | return Enumerable.Empty(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Checker/Checker.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard1.6 4 | Checker 5 | $(PackageTargetFallback);dnxcore50 6 | false 7 | false 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 1.6.0 18 | 19 | 20 | 21 | Checking.FluentApi 22 | 23 | 24 | $(DefineConstants);RELEASE 25 | 26 | -------------------------------------------------------------------------------- /src/Checker/ExpressionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | 5 | namespace Checking.FluentApi 6 | { 7 | internal static class ExpressionExtensions 8 | { 9 | public static MemberInfo GetMember(this LambdaExpression expression) 10 | { 11 | var memberExp = RemoveUnary(expression.Body); 12 | 13 | if (memberExp == null) 14 | { 15 | return null; 16 | } 17 | 18 | return memberExp.Member; 19 | } 20 | 21 | public static MemberInfo GetMember(this Expression> expression) 22 | { 23 | var memberExp = RemoveUnary(expression.Body); 24 | 25 | if (memberExp == null) 26 | { 27 | return null; 28 | } 29 | 30 | return memberExp.Member; 31 | } 32 | 33 | private static MemberExpression RemoveUnary(Expression toUnwrap) 34 | { 35 | if (toUnwrap is UnaryExpression) 36 | { 37 | return ((UnaryExpression)toUnwrap).Operand as MemberExpression; 38 | } 39 | 40 | return toUnwrap as MemberExpression; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Checker 2 | The minimum code to demo how to use expression tree/lambda, extension methods to implement fluent api. 3 | 4 | # What's Fluent API 5 | [This article](http://rrpblog.azurewebsites.net/?p=33) explains it much better than I ever could. 6 | 7 | > there are two sides to interfaces, the implementation and the usage. There's more work to be done on the creation side, I agree with that, 8 | however the main benefits can be found on the usage side of things. 9 | Indeed, for me the main advantage of fluent interfaces is a more natural, easier to remember and use and why not, more aesthetically pleasing API. 10 | And just maybe, the effort of having to squeeze an API in a fluent form may lead to better thought out API? 11 | 12 | As Martin Fowler says [in the original article about fluent interfaces](https://martinfowler.com/bliki/FluentInterface.html): 13 | 14 | > Probably the most important thing to notice about this style is that the intent is to do something along the lines of an internal DomainSpecificLanguage. 15 | Indeed this is why we chose the term 'fluent' to describe it, in many ways the two terms are synonyms. The API is primarily designed to be readable and to flow. 16 | The price of this fluency is more effort, both in thinking and in the API construction itself. The simple API of constructor, setter, and addition methods is 17 | much easier to write. Coming up with a nice fluent API requires a good bit of thought. 18 | 19 | As in most cases API's are created once and used over and over again, the extra effort may be worth it. 20 | 21 | # How to use 22 | 23 | ```csharp 24 | public class User 25 | { 26 | public string Username { get; set; } 27 | public string Password { get; set; } 28 | 29 | public int Age { get; set; } 30 | } 31 | 32 | public class UserChecker : CheckerBase 33 | { 34 | public UserChecker() 35 | { 36 | RuleFor(u => u.Username).NotEmpty(); 37 | RuleFor(u => u.Password).NotEmpty(); 38 | RuleFor(u => u.Age).LessThan(100); 39 | } 40 | } 41 | 42 | [Fact] 43 | public void Checking_FluentApi_Test() 44 | { 45 | var user = new User 46 | { 47 | Username = "rigofunc", 48 | Password = "p@ssword", 49 | Age = 31, 50 | }; 51 | 52 | var checker = new UserChecker(); 53 | 54 | var result = checker.Check(user); 55 | 56 | Assert.IsTrue(result.Succeed); 57 | } 58 | ``` -------------------------------------------------------------------------------- /src/Checker/PropertyRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | 6 | namespace Checking.FluentApi 7 | { 8 | public class PropertyRule : ICheckRule 9 | { 10 | private readonly IList> checkers = new List>(); 11 | 12 | public PropertyRule(MemberInfo member, Func propertyFunc, Type typeToValidate) 13 | { 14 | Member = member; 15 | PropertyFunc = propertyFunc; 16 | TypeToValidate = typeToValidate; 17 | } 18 | 19 | public static PropertyRule Create(Expression> expression) 20 | { 21 | var member = expression.GetMember(); 22 | 23 | var compiled = expression.Compile(); 24 | 25 | return new PropertyRule(member, compiled, typeof(TProperty)); 26 | } 27 | 28 | public MemberInfo Member { get; } 29 | 30 | public Func PropertyFunc { get; } 31 | 32 | public LambdaExpression Expression { get; } 33 | 34 | public IPropertyChecker CurrentChecker { get; private set; } 35 | 36 | /// 37 | /// Type of the property being validated 38 | /// 39 | public Type TypeToValidate { get; private set; } 40 | 41 | public IEnumerable> Checkers => checkers; 42 | 43 | public IEnumerable Check(CheckContext context) 44 | { 45 | foreach (var checker in checkers) 46 | { 47 | var hasFailure = false; 48 | var failures = checker.Checker(new PropertyCheckContext(context, this, Member.Name)); 49 | 50 | foreach (var item in failures) 51 | { 52 | hasFailure = true; 53 | yield return item; 54 | } 55 | 56 | if (hasFailure) 57 | { 58 | break; 59 | } 60 | } 61 | } 62 | 63 | public void AddChecker(IPropertyChecker checker) 64 | { 65 | CurrentChecker = checker; 66 | 67 | checkers.Add(checker); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Checker.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26020.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{65163C4E-7C8D-4442-9610-59CF3EB44E58}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4333E7F-A313-4878-B372-80B91037F6BE}" 9 | ProjectSection(SolutionItems) = preProject 10 | global.json = global.json 11 | README.md = README.md 12 | EndProjectSection 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Checker", "src\Checker\Checker.csproj", "{6C774E9B-CF8B-48A6-9481-9668DC460B1F}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{D9F67DF9-2A18-447C-A713-F7CC8D8948FD}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Checker.Test", "test\Checker.Test\Checker.Test.csproj", "{E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|x64 = Debug|x64 24 | Debug|x86 = Debug|x86 25 | Release|Any CPU = Release|Any CPU 26 | Release|x64 = Release|x64 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|x64.ActiveCfg = Debug|x64 33 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|x64.Build.0 = Debug|x64 34 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|x86.ActiveCfg = Debug|x86 35 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Debug|x86.Build.0 = Debug|x86 36 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|x64.ActiveCfg = Release|x64 39 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|x64.Build.0 = Release|x64 40 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|x86.ActiveCfg = Release|x86 41 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F}.Release|x86.Build.0 = Release|x86 42 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|x64.ActiveCfg = Debug|x64 45 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|x64.Build.0 = Debug|x64 46 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|x86.ActiveCfg = Debug|x86 47 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Debug|x86.Build.0 = Debug|x86 48 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|x64.ActiveCfg = Release|x64 51 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|x64.Build.0 = Release|x64 52 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|x86.ActiveCfg = Release|x86 53 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75}.Release|x86.Build.0 = Release|x86 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(NestedProjects) = preSolution 59 | {6C774E9B-CF8B-48A6-9481-9668DC460B1F} = {65163C4E-7C8D-4442-9610-59CF3EB44E58} 60 | {E02C9BE5-7E2A-4D09-9E8C-571EB7414A75} = {D9F67DF9-2A18-447C-A713-F7CC8D8948FD} 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /src/Checker/Fluent.xUnit.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {3D46AC26-9507-4969-A4FA-04FDABF2F079} 7 | Library 8 | Properties 9 | Fluent.xUnit 10 | Fluent.xUnit 11 | v4.6 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | False 76 | 77 | 78 | False 79 | 80 | 81 | False 82 | 83 | 84 | False 85 | 86 | 87 | 88 | 89 | 90 | 91 | 98 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | --------------------------------------------------------------------------------