├── .editorconfig ├── .gitattributes ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── CONTRIBUTING.md ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── Valit.sln ├── appveyor.yml ├── build.cake ├── build.ps1 ├── build.sh ├── cake.config ├── codecov.yml ├── src └── Valit │ ├── CompleteValitStrategy.cs │ ├── Errors │ ├── ErrorMessages.cs │ └── ValitRuleError.cs │ ├── Exceptions │ ├── SemanticExceptions.cs │ ├── ValitExceptionExtensions.cs │ └── ValitExceptionMessages.cs │ ├── FailFastValitStrategy.cs │ ├── IValitMessageProvider.cs │ ├── IValitResult.cs │ ├── IValitRule.cs │ ├── IValitRules.cs │ ├── IValitRulesMessageProvider.cs │ ├── IValitRulesStrategyPicker.cs │ ├── IValitStrategy.cs │ ├── IValitator.cs │ ├── MessageProvider │ └── EmptyMessageProvider.cs │ ├── Result │ └── ValitResult.cs │ ├── Rules │ ├── CollectionValitRule.cs │ ├── IValitRuleAccessor.cs │ ├── NestedObjectCollectionValitRule.cs │ ├── NestedObjectValitRule.cs │ ├── ValitRule.cs │ ├── ValitRuleAccessorExtensions.cs │ └── ValitRuleExtensions.cs │ ├── Validators │ └── Valitator.cs │ ├── Valit.csproj │ ├── ValitException.cs │ ├── ValitRuleBooleanExtensions.cs │ ├── ValitRuleByteExtensions.cs │ ├── ValitRuleDateTimeExtensions.cs │ ├── ValitRuleDateTimeOffsetExtensions.cs │ ├── ValitRuleDecimalExtensions.cs │ ├── ValitRuleDoubleExtensions.cs │ ├── ValitRuleEnumerableExtensions.cs │ ├── ValitRuleFloatExtensions.cs │ ├── ValitRuleGuidExtensions.cs │ ├── ValitRuleInt16Extensions.cs │ ├── ValitRuleInt32Extensions.cs │ ├── ValitRuleInt64Extensions.cs │ ├── ValitRulePropertyExtensions.cs │ ├── ValitRuleSByteExtensions.cs │ ├── ValitRuleStringExtensions.cs │ ├── ValitRuleTimeSpanExtensions.cs │ ├── ValitRuleUInt16Extensions.cs │ ├── ValitRuleUInt32Extensions.cs │ ├── ValitRuleUInt64Extensions.cs │ ├── ValitRules.cs │ ├── ValitRulesExtensions.cs │ ├── ValitStrategies.cs │ └── ValitStrategiesExtensions.cs ├── tests └── Valit.Tests │ ├── Boolean │ ├── Boolean_IsEqual_To_Tests.cs │ ├── Boolean_IsFalse_Tests.cs │ ├── Boolean_IsTrue_Tests.cs │ └── Boolean_Required_Tests.cs │ ├── Byte │ ├── Byte_IsEqual_To_Tests.cs │ ├── Byte_IsGreaterThanOrEqualTo_Tests.cs │ ├── Byte_IsGreaterThan_Tests.cs │ ├── Byte_IsLessThanOrEqualTo_Tests.cs │ ├── Byte_IsLessThan_Tests.cs │ ├── Byte_IsNonZero_Tests.cs │ └── Byte_Required_Tests.cs │ ├── Collection │ └── Primitive_Property_Collection_Validation_Tests.cs │ ├── DateTimeOffset_ │ ├── DateTimeOffset_IsAfterNow_Tests.cs │ ├── DateTimeOffset_IsAfterOrSameAs_Tests.cs │ ├── DateTimeOffset_IsAfterUtcNow_Tests.cs │ ├── DateTimeOffset_IsAfter_Tests.cs │ ├── DateTimeOffset_IsBeforeNow_Tests.cs │ ├── DateTimeOffset_IsBeforeOrSameAs_Tests.cs │ ├── DateTimeOffset_IsBeforeUtcNow_Tests.cs │ ├── DateTimeOffset_IsBefore_Tests.cs │ ├── DateTimeOffset_IsSameAs_Tests.cs │ └── DateTimeOffset_Required_Tests.cs │ ├── DateTime_ │ ├── DateTime_IsAfterNow_Tests.cs │ ├── DateTime_IsAfterOrSameAs_Tests.cs │ ├── DateTime_IsAfterUtcNow_Tests.cs │ ├── DateTime_IsAfter_Tests.cs │ ├── DateTime_IsBeforeNow_Tests.cs │ ├── DateTime_IsBeforeOrSameAs_Tests.cs │ ├── DateTime_IsBeforeUtcNow_Tests.cs │ ├── DateTime_IsBefore_Tests.cs │ ├── DateTime_IsSameAs_Tests.cs │ └── DateTime_Required_Tests.cs │ ├── Decimal │ ├── Decimal_IsEqual_To_Tests.cs │ ├── Decimal_IsGreaterThanOrEqualTo_Tests.cs │ ├── Decimal_IsGreaterThan_Tests.cs │ ├── Decimal_IsLessThanOrEqualTo_Tests.cs │ ├── Decimal_IsLessThan_Tests.cs │ ├── Decimal_IsNegative_Tests.cs │ ├── Decimal_IsNonZero_Tests.cs │ ├── Decimal_IsPositive_Tests.cs │ └── Decimal_Required_Tests.cs │ ├── Double │ ├── Double_IsEqualTo_Tests.cs │ ├── Double_IsGreaterThanOrEqualTo_Tests.cs │ ├── Double_IsGreaterThan_Tests.cs │ ├── Double_IsLessThanOrEqualTo_Tests.cs │ ├── Double_IsLessThan_Tests.cs │ ├── Double_IsNaN_Tests.cs │ ├── Double_IsNegative_Tests.cs │ ├── Double_IsNonZero_Tests.cs │ ├── Double_IsNumber_Tests.cs │ ├── Double_IsPositive_Tests.cs │ └── Double_Required_Tests.cs │ ├── Enumerable │ ├── Enumerable_MaxItems_Tests.cs │ └── Enumerable_MinItems_Tests.cs │ ├── Float │ ├── Float_IsEqualTo_Tests.cs │ ├── Float_IsGreaterThanOrEqualTo_Tests.cs │ ├── Float_IsGreaterThan_Tests.cs │ ├── Float_IsLessThanOrEqualTo_Tests.cs │ ├── Float_IsLessThan_Tests.cs │ ├── Float_IsNaN_Tests.cs │ ├── Float_IsNegative_Tests.cs │ ├── Float_IsNonZero_Tests.cs │ ├── Float_IsNumber_Tests.cs │ ├── Float_IsPositive_Tests.cs │ └── Float_Required_Tests.cs │ ├── Guid_ │ ├── Guid_IsEqualTo_Tests.cs │ ├── Guid_IsNotEmpty_Tests.cs │ └── Guid_Required_Tests.cs │ ├── HelperExtensions │ ├── DateTimeExtensions.cs │ ├── DateTimeOffsetExtensions.cs │ └── DecimalExtensions.cs │ ├── Int16 │ ├── Int16_IsEqual_To_Tests.cs │ ├── Int16_IsGreaterThanOrEqualTo_Tests.cs │ ├── Int16_IsGreaterThan_Tests.cs │ ├── Int16_IsLessThanOrEqualTo_Tests.cs │ ├── Int16_IsLessThan_Tests.cs │ ├── Int16_IsNegative_Tests.cs │ ├── Int16_IsNonZero_Tests.cs │ ├── Int16_IsPositive_Tests.cs │ └── Int16_Required_Tests.cs │ ├── Int32 │ ├── Int32_IsEqual_To_Tests.cs │ ├── Int32_IsGreaterThanOrEqualTo_Tests.cs │ ├── Int32_IsGreaterThan_Tests.cs │ ├── Int32_IsLessThanOrEqualTo_Tests.cs │ ├── Int32_IsLessThan_Tests.cs │ ├── Int32_IsNegative_Tests.cs │ ├── Int32_IsNonZero_Tests.cs │ ├── Int32_IsPositive_Tests.cs │ └── Int32_Required_Tests.cs │ ├── Int64 │ ├── Int64_IsEqual_To_Tests.cs │ ├── Int64_IsGreaterThanOrEqualTo_Tests.cs │ ├── Int64_IsGreaterThan_Tests.cs │ ├── Int64_IsLessThanOrEqualTo_Tests.cs │ ├── Int64_IsLessThan_Tests.cs │ ├── Int64_IsNegative_Tests.cs │ ├── Int64_IsNonZero_Tests.cs │ ├── Int64_IsPositive_Tests.cs │ └── Int64_Required_Tests.cs │ ├── MessageProvider │ ├── CustomMessageProvider_Tests.cs │ └── EmptyMessageProvider_Tests.cs │ ├── NestedObject │ ├── Nested_Object_Collection_Validation_Tests.cs │ └── Nested_Object_Validation_Tests.cs │ ├── Property │ ├── Property_Required_Tests.cs │ ├── Property_Tag_Tests.cs │ ├── Property_When_Tests.cs │ ├── Property_WithDefaultMessage_Tests.cs │ ├── Property_WithErrorCode_Tests.cs │ └── Property_WithMessage_Tests.cs │ ├── SByte │ ├── SByte_IsEqual_To_Tests.cs │ ├── SByte_IsGreaterThanOrEqualTo_Tests.cs │ ├── SByte_IsGreaterThan_Tests.cs │ ├── SByte_IsLessThanOrEqualTo_Tests.cs │ ├── SByte_IsLessThan_Tests.cs │ ├── SByte_IsNegative_Tests.cs │ ├── SByte_IsNonZero_Tests.cs │ ├── SByte_IsPositive_Tests.cs │ └── SByte_Required_Tests.cs │ ├── Strategies │ ├── Complete.cs │ └── FailFast.cs │ ├── String │ ├── String_Email_Tests.cs │ ├── String_IsEqualTo_Tests.cs │ ├── String_Matches_Tests.cs │ ├── String_MaxLength_Tests.cs │ ├── String_MinLength_Tests.cs │ └── String_Required_Tests.cs │ ├── TimeSpan_ │ ├── TimeSpan_IsEqualTo_Tests.cs │ ├── TimeSpan_IsGreaterThanOrEqualTo_Tests.cs │ ├── TimeSpan_IsGreaterThan_Tests.cs │ ├── TimeSpan_IsLessThanOrEqualTo_Tests.cs │ ├── TimeSpan_IsLessThan_Tests.cs │ ├── TimeSpan_IsNonZero_Tests.cs │ └── TimeSpan_Required_Tests.cs │ ├── UInt16 │ ├── UInt16_IsEqual_To_Tests.cs │ ├── UInt16_IsGreaterThanOrEqualTo_Tests.cs │ ├── UInt16_IsGreaterThan_Tests.cs │ ├── UInt16_IsLessThanOrEqualTo_Tests.cs │ ├── UInt16_IsLessThan_Tests.cs │ ├── UInt16_IsNonZero_Tests.cs │ └── UInt16_Required_Tests.cs │ ├── UInt32 │ ├── UInt32_IsEqual_To_Tests.cs │ ├── UInt32_IsGreaterThanOrEqualTo_Tests.cs │ ├── UInt32_IsGreaterThan_Tests.cs │ ├── UInt32_IsLessThanOrEqualTo_Tests.cs │ ├── UInt32_IsLessThan_Tests.cs │ ├── UInt32_IsNonZero_Tests.cs │ └── UInt32_Required_Tests.cs │ ├── UInt64 │ ├── UInt64_IsEqual_To_Tests.cs │ ├── UInt64_IsGreaterThanOrEqualTo_Tests.cs │ ├── UInt64_IsGreaterThan_Tests.cs │ ├── UInt64_IsLessThanOrEqualTo_Tests.cs │ ├── UInt64_IsLessThan_Tests.cs │ ├── UInt64_IsNonZero_Tests.cs │ └── UInt64_Required_Tests.cs │ ├── Valit.Tests.csproj │ └── Valitator │ ├── Valitator_MessageProvider_Tests.cs │ └── Valitator_ValitRules_Tests.cs └── tools └── packages.config /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = crlf 6 | indent_style = space 7 | 8 | [*.cs] 9 | indent_size = 4 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | dotnet_sort_system_directives_first = true 13 | csharp_new_line_before_open_brace = all 14 | csharp_new_line_before_else = true 15 | csharp_new_line_before_catch= true 16 | csharp_new_line_before_finally= true 17 | csharp_new_line_before_members_in_object_initializers= true 18 | csharp_new_line_before_members_in_anonymous_types= true 19 | csharp_new_line_between_query_expression_clauses= true 20 | csharp_indent_case_contents= true 21 | csharp_indent_switch_labels= true 22 | csharp_indent_labels = no_change 23 | csharp_space_after_cast = false 24 | csharp_space_after_keywords_in_control_flow_statements= true 25 | csharp_space_between_method_declaration_parameter_list_parentheses = false 26 | csharp_space_between_method_call_parameter_list_parentheses = false 27 | csharp_space_between_parentheses = false 28 | csharp_preserve_single_line_statements= true 29 | csharp_preserve_single_line_blocks= true 30 | 31 | [*.sln] 32 | indent_style = tab 33 | 34 | [*.{csproj, yml, config, cake}] 35 | indent_style = space 36 | indent_size = 2 37 | 38 | [*.md] 39 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.cs text diff=csharp eol=crlf 4 | *.sln text merge=union eol=crlf 5 | *.csproj text merge=union eol=crlf -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch (console)", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "build", 9 | "program": "${workspaceRoot}/tests/Valit.Tests/bin/Debug/netcoreapp2.0/Valit.Tests.dll", 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "stopAtEntry": false, 13 | "console": "internalConsole" 14 | }, 15 | { 16 | "name": ".NET Core Launch (web)", 17 | "type": "coreclr", 18 | "request": "launch", 19 | "preLaunchTask": "build", 20 | "program": "${workspaceRoot}/tests/Valit.Tests/bin/Debug/netcoreapp2.0/Valit.Tests.dll", 21 | "args": [], 22 | "cwd": "${workspaceRoot}", 23 | "stopAtEntry": false, 24 | "launchBrowser": { 25 | "enabled": true, 26 | "args": "${auto-detect-url}", 27 | "windows": { 28 | "command": "cmd.exe", 29 | "args": "/C start ${auto-detect-url}" 30 | }, 31 | "osx": { 32 | "command": "open" 33 | }, 34 | "linux": { 35 | "command": "xdg-open" 36 | } 37 | }, 38 | "env": { 39 | "ASPNETCORE_ENVIRONMENT": "Development" 40 | }, 41 | "sourceFileMap": { 42 | "/Views": "${workspaceRoot}/Views" 43 | } 44 | }, 45 | { 46 | "name": ".NET Core Attach", 47 | "type": "coreclr", 48 | "request": "attach", 49 | "processId": "${command:pickProcess}" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "taskName": "build", 8 | "command": "dotnet build", 9 | "type": "shell", 10 | "group": "build", 11 | "presentation": { 12 | "reveal": "silent" 13 | }, 14 | "problemMatcher": "$msCompile" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Dariusz Pawlukiewicz 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 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Info 2 | This Pull Request is related to issue no. [] ([]) 3 | 4 | # Changes 5 | - ... -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Valit](https://avatars1.githubusercontent.com/u/32653478?s=200&v=4) 2 | 3 | Valit is **dead simple** validation for .NET Core. No more if-statements all around your code. Write nice and clean **fluent validators** instead! 4 | 5 | | | master | develop | 6 | |---|--------|----------| 7 | |AppVeyor|[![Build status](https://ci.appveyor.com/api/projects/status/github/valit-stack/Valit?branch=master&svg=true&passingText=master%20passing&failingText=master%20failing&pendingText=master%20pending)](https://ci.appveyor.com/project/GooRiOn/valit/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/github/valit-stack/Valit?branch=develop&svg=true&passingText=develop%20passing&failingText=develop%20failing&pendingText=develop%20pending)](https://ci.appveyor.com/project/GooRiOn/valit/branch/develop)| 8 | |Codecov|[![codecov](https://codecov.io/gh/valit-stack/valit/branch/master/graph/badge.svg)](https://codecov.io/gh/valit-stack/valit/branch/master)|[![codecov](https://codecov.io/gh/valit-stack/valit/branch/develop/graph/badge.svg)](https://codecov.io/gh/valit-stack/valit/branch/develop)| 9 | 10 | ![NuGet](https://img.shields.io/nuget/v/Valit.svg) 11 | 12 | 13 | # Installation 14 | Valit is available on [NuGet](https://www.nuget.org/packages/Valit/). 15 | 16 | ### Package manager 17 | ```bash 18 | Install-Package Valit -Version 2.0.0 19 | ``` 20 | 21 | ### .NET CLI 22 | ```bash 23 | dotnet add package Valit --version 2.0.0 24 | ``` 25 | 26 | # Getting started 27 | In order to create a validator you need to go through few steps. It's worth mentioning that not all of them are mandatory. The steps are: 28 | 29 | - creating new instance of validator using ``Create()`` static method. 30 | - choosing [validation strategy](http://valitdocs.readthedocs.io/en/latest/strategies/index.html) using ``WithStrategy()`` method **(not required)**. 31 | - selecting property using ``Ensure()`` method and defining rules for it. 32 | - Extending rules with [custom errors](http://valitdocs.readthedocs.io/en/latest/validation-errors/index.html) (such as messages or error codes), [tags and conditions](http://valitdocs.readthedocs.io/en/latest/validation-rules/index.html). **(not required)**. 33 | - applying created rules to an object using ``For()`` method. 34 | 35 | Having the validator created, simply invoke ``Validate()`` method which will produce the result with all the data. 36 | 37 | Let's try it out with very practical example. Imagine that your task is to validate model sent from registration page of your app. The example object might look as follows: 38 | 39 | ```cs 40 | 41 | public class RegisterModel 42 | { 43 | public string Email { get; set; } 44 | public string Password { get; set; } 45 | public ushort Age { get; set ;} 46 | } 47 | ``` 48 | 49 | These are the validation criteria: 50 | 51 | - ``Email`` is required and needs to be a proper email address 52 | - ``Password`` is required and needs to be at least 10 characters long 53 | - ``Age`` must be greater than 16 54 | 55 | 56 | This is how you can handle such scenario using Valit: 57 | 58 | ```cs 59 | 60 | void ValidateModel(RegisterModel model) 61 | { 62 | var result = ValitRules 63 | .Create() 64 | .Ensure(m => m.Email, _=>_ 65 | .Required() 66 | .Email()) 67 | .Ensure(m => m.Password, _=>_ 68 | .Required() 69 | .MinLength(10)) 70 | .Ensure(m => m.Age, _=>_ 71 | .IsGreaterThan(16)) 72 | .For(model) 73 | .Validate(); 74 | 75 | if(result.Succeeded) 76 | { 77 | // do something on success 78 | } 79 | else 80 | { 81 | // do something on failure 82 | } 83 | } 84 | ``` 85 | 86 | Pretty cool, right? Of course, the above example was fairly simple but trust us. From now on, even complicated validation criterias won't scare you anymore ;) 87 | 88 | # Documentation 89 | If you're looking for documentation, you can find it [here](http://valitdocs.readthedocs.io/en/latest/index.html). 90 | 91 | # Contributing 92 | Want to help us develop Valit? Awesome! Here you can find [contributor guide](https://github.com/valit-stack/Valit/blob/develop/CONTRIBUTING.md) ;) 93 | -------------------------------------------------------------------------------- /Valit.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Valit", "src\Valit\Valit.csproj", "{3FAD0018-061A-42A1-BF6D-8D3DB3F5F886}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Valit.Tests", "tests\Valit.Tests\Valit.Tests.csproj", "{E5741074-BE66-44C7-BF44-0342DC3B4B23}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3FAD0018-061A-42A1-BF6D-8D3DB3F5F886}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {3FAD0018-061A-42A1-BF6D-8D3DB3F5F886}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {3FAD0018-061A-42A1-BF6D-8D3DB3F5F886}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {3FAD0018-061A-42A1-BF6D-8D3DB3F5F886}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {E5741074-BE66-44C7-BF44-0342DC3B4B23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E5741074-BE66-44C7-BF44-0342DC3B4B23}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E5741074-BE66-44C7-BF44-0342DC3B4B23}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {E5741074-BE66-44C7-BF44-0342DC3B4B23}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {64D86518-110B-43D2-BE73-22BDEE6E8F5F} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - git config --global core.autocrlf true 3 | 4 | image: Visual Studio 2015 5 | 6 | before_build: 7 | - choco install opencover.portable 8 | - choco install codecov 9 | 10 | build_script: 11 | - ps: .\build.ps1 12 | - OpenCover.Console.exe -register:user -target:"C:/Program Files/dotnet/dotnet.exe" -targetargs:"test --logger:trx;LogFileName=results.trx /p:DebugType=full C:\projects\valit\tests\Valit.Tests\Valit.Tests.csproj" -filter:"+[Valit*]* -[Valit.Tests*]*" -output:".\valit_coverage.xml" -oldstyle 13 | - codecov -f .\valit_coverage.xml -t $(codecov_token) 14 | 15 | test: off 16 | 17 | branches: 18 | only: 19 | - develop 20 | - master 21 | 22 | cache: 23 | - tools -> build.cake 24 | - packages -> build.cake 25 | -------------------------------------------------------------------------------- /build.cake: -------------------------------------------------------------------------------- 1 | #tool "nuget:?package=xunit.runner.console" 2 | 3 | var target = Argument("target", "Default"); 4 | var configuration = Argument("configuration", "Release"); 5 | 6 | Task("dotnet-restore") 7 | .Does(() => 8 | { 9 | DotNetCoreRestore("./Valit.sln"); 10 | }); 11 | 12 | Task("dotnet-build") 13 | .IsDependentOn("dotnet-restore") 14 | .Does(() => 15 | { 16 | DotNetCoreBuild("./Valit.sln", new DotNetCoreBuildSettings 17 | { 18 | Configuration = configuration, 19 | MSBuildSettings = new DotNetCoreMSBuildSettings 20 | { 21 | TreatAllWarningsAs = MSBuildTreatAllWarningsAs.Error 22 | } 23 | }); 24 | }); 25 | 26 | Task("run-xunit-tests") 27 | .IsDependentOn("dotnet-build") 28 | .Does(() => 29 | { 30 | var settings = new DotNetCoreTestSettings 31 | { 32 | Configuration = configuration 33 | }; 34 | 35 | DotNetCoreTest("./tests/Valit.Tests/Valit.Tests.csproj", settings); 36 | }); 37 | 38 | Task("Default") 39 | .IsDependentOn("run-xunit-tests"); 40 | 41 | RunTarget(target); -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ########################################################################## 4 | # This is the Cake bootstrapper script for Linux and OS X. 5 | # This file was downloaded from https://github.com/cake-build/resources 6 | # Feel free to change this file to fit your needs. 7 | ########################################################################## 8 | 9 | # Define directories. 10 | SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 11 | TOOLS_DIR=$SCRIPT_DIR/tools 12 | ADDINS_DIR=$TOOLS_DIR/Addins 13 | MODULES_DIR=$TOOLS_DIR/Modules 14 | NUGET_EXE=$TOOLS_DIR/nuget.exe 15 | CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe 16 | PACKAGES_CONFIG=$TOOLS_DIR/packages.config 17 | PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum 18 | ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config 19 | MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config 20 | 21 | # Define md5sum or md5 depending on Linux/OSX 22 | MD5_EXE= 23 | if [[ "$(uname -s)" == "Darwin" ]]; then 24 | MD5_EXE="md5 -r" 25 | else 26 | MD5_EXE="md5sum" 27 | fi 28 | 29 | # Define default arguments. 30 | SCRIPT="build.cake" 31 | CAKE_ARGUMENTS=() 32 | 33 | # Parse arguments. 34 | for i in "$@"; do 35 | case $1 in 36 | -s|--script) SCRIPT="$2"; shift ;; 37 | --) shift; CAKE_ARGUMENTS+=("$@"); break ;; 38 | *) CAKE_ARGUMENTS+=("$1") ;; 39 | esac 40 | shift 41 | done 42 | 43 | # Make sure the tools folder exist. 44 | if [ ! -d "$TOOLS_DIR" ]; then 45 | mkdir "$TOOLS_DIR" 46 | fi 47 | 48 | # Make sure that packages.config exist. 49 | if [ ! -f "$TOOLS_DIR/packages.config" ]; then 50 | echo "Downloading packages.config..." 51 | curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages 52 | if [ $? -ne 0 ]; then 53 | echo "An error occured while downloading packages.config." 54 | exit 1 55 | fi 56 | fi 57 | 58 | # Download NuGet if it does not exist. 59 | if [ ! -f "$NUGET_EXE" ]; then 60 | echo "Downloading NuGet..." 61 | curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe 62 | if [ $? -ne 0 ]; then 63 | echo "An error occured while downloading nuget.exe." 64 | exit 1 65 | fi 66 | fi 67 | 68 | # Restore tools from NuGet. 69 | pushd "$TOOLS_DIR" >/dev/null 70 | if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then 71 | find . -type d ! -name . | xargs rm -rf 72 | fi 73 | 74 | mono "$NUGET_EXE" install -ExcludeVersion 75 | if [ $? -ne 0 ]; then 76 | echo "Could not restore NuGet tools." 77 | exit 1 78 | fi 79 | 80 | $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5" 81 | 82 | popd >/dev/null 83 | 84 | # Restore addins from NuGet. 85 | if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then 86 | pushd "$ADDINS_DIR" >/dev/null 87 | 88 | mono "$NUGET_EXE" install -ExcludeVersion 89 | if [ $? -ne 0 ]; then 90 | echo "Could not restore NuGet addins." 91 | exit 1 92 | fi 93 | 94 | popd >/dev/null 95 | fi 96 | 97 | # Restore modules from NuGet. 98 | if [ -f "$MODULES_PACKAGES_CONFIG" ]; then 99 | pushd "$MODULES_DIR" >/dev/null 100 | 101 | mono "$NUGET_EXE" install -ExcludeVersion 102 | if [ $? -ne 0 ]; then 103 | echo "Could not restore NuGet modules." 104 | exit 1 105 | fi 106 | 107 | popd >/dev/null 108 | fi 109 | 110 | # Make sure that Cake has been installed. 111 | if [ ! -f "$CAKE_EXE" ]; then 112 | echo "Could not find Cake.exe at '$CAKE_EXE'." 113 | exit 1 114 | fi 115 | 116 | # Start Cake 117 | exec mono "$CAKE_EXE" $SCRIPT "${CAKE_ARGUMENTS[@]}" 118 | -------------------------------------------------------------------------------- /cake.config: -------------------------------------------------------------------------------- 1 | ; This is the default configuration file for Cake. 2 | ; This file was downloaded from https://github.com/cake-build/resources 3 | 4 | [Nuget] 5 | Source=https://packages.nuget.org/api/v2 6 | 7 | [Roslyn] 8 | NuGetSource=https://packages.nuget.org/api/v2 9 | 10 | [Paths] 11 | Tools=./tools 12 | Addins=./tools/Addins 13 | Modules=./tools/Modules 14 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: 60...100 3 | round: down 4 | precision: 2 5 | notify: 6 | slack: 7 | default: 8 | url: $(codecov-webhook) 9 | threshold: 1% 10 | only_pulls: false 11 | branches: 12 | - master 13 | - develop 14 | -------------------------------------------------------------------------------- /src/Valit/CompleteValitStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public class CompleteValitStrategy : IValitStrategy 4 | { 5 | public void Fail(IValitRule rule, IValitResult result, out bool cancel) 6 | where TObject : class 7 | { 8 | cancel = false; 9 | } 10 | 11 | public void Done(IValitResult result) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Valit/Errors/ErrorMessages.cs: -------------------------------------------------------------------------------- 1 | namespace Valit.Errors 2 | { 3 | internal static class ErrorMessages 4 | { 5 | internal static string Required => "The {0} field is required."; 6 | internal static string Satisifes => "The {0} field does not satisfy the rule."; 7 | internal static string IsTrue => "The {0} field is not true."; 8 | internal static string IsFalse => "The {0} field is not false."; 9 | internal static string IsEqualTo => "The {0} field is not equal to {1}."; 10 | internal static string IsGreaterThan => "The {0} field is not greater than {1}."; 11 | internal static string IsGreaterThanOrEqualTo => "The {0} field is not greater than or equal to {1}."; 12 | internal static string IsLessThan => "The {0} field is not less than {1}."; 13 | internal static string IsLessThanOrEqualTo => "The {0} field is not less than or equal to {1}."; 14 | internal static string IsNonZero => "The {0} field is a zero."; 15 | internal static string IsAfter => "The {0} field is not after {1}."; 16 | internal static string IsAfterOrSameAs => "The {0} field is not after or same as {1}."; 17 | internal static string IsBefore => "The {0} field is not before {1}."; 18 | internal static string IsBeforeOrSameAs => "The {0} field is not before or same as {1}."; 19 | internal static string IsSameAs => "The {0} field is not same as {1}."; 20 | internal static string IsNegative => "The {0} field is not a negative number."; 21 | internal static string IsPositive => "The {0} field is not a positive number."; 22 | internal static string IsNaN => "The {0} field is not NaN."; 23 | internal static string IsNumber => "The {0} field is not a number."; 24 | internal static string MinItems => "The {0} field has less than {1} elements."; 25 | internal static string MaxItems => "The {0} field has more than {1} elements."; 26 | internal static string Email => "The {0} field is not valid email."; 27 | internal static string Matches => "The {0} field does not match the pattern."; 28 | internal static string MinLength => "The {0} field's length is less than {1}."; 29 | internal static string MaxLength => "The {0} field's length is greater than {1}."; 30 | internal static string IsNotEmpty => "The {0} field is empty."; 31 | } 32 | } -------------------------------------------------------------------------------- /src/Valit/Errors/ValitRuleError.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit.Errors 4 | { 5 | internal class ValitRuleError 6 | { 7 | private readonly Func _messageFunc; 8 | public string Message => _messageFunc(); 9 | public int? ErrorCode { get; } 10 | public bool IsDefault { get; } 11 | 12 | private ValitRuleError(Func messageFunc, bool isDefault) 13 | { 14 | IsDefault = isDefault; 15 | _messageFunc = messageFunc; 16 | } 17 | 18 | private ValitRuleError(int errorCode) 19 | { 20 | ErrorCode = errorCode; 21 | IsDefault = false; 22 | _messageFunc = () => string.Empty; 23 | } 24 | 25 | public static ValitRuleError CreateForMessage(Func messageFunc, bool isDefault = false) 26 | => new ValitRuleError(messageFunc, isDefault); 27 | 28 | public static ValitRuleError CreateForErrorCode(int errorCode) 29 | => new ValitRuleError(errorCode); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Valit/Exceptions/SemanticExceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit.Exceptions 4 | { 5 | internal static class SemanticExceptions 6 | { 7 | public static ValitException NullDereferenced(string message) 8 | => throw new ValitException(message, new ArgumentNullException()); 9 | 10 | public static ValitException NullDereferenced() 11 | => throw new ValitException("Null dereferenced", new ArgumentNullException()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Valit/Exceptions/ValitExceptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using static Valit.Exceptions.SemanticExceptions; 2 | 3 | namespace Valit.Exceptions 4 | { 5 | internal static class ValitExceptionExtensions 6 | { 7 | internal static void ThrowIfNull(this T @object) 8 | where T : class 9 | { 10 | if(@object == null) 11 | { 12 | throw NullDereferenced(); 13 | } 14 | } 15 | 16 | internal static void ThrowIfNull(this T @object, string message) 17 | where T: class 18 | { 19 | if(@object == null) 20 | { 21 | throw NullDereferenced(message); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Valit/Exceptions/ValitExceptionMessages.cs: -------------------------------------------------------------------------------- 1 | namespace Valit.Exceptions 2 | { 3 | internal static class ValitExceptionMessages 4 | { 5 | public static string NullRule => "Valit rule is null"; 6 | public static string NullPredicate => "Given predicate is null"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valit/FailFastValitStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public class FailFastValitStrategy : IValitStrategy 4 | { 5 | public void Fail(IValitRule rule, IValitResult result, out bool cancel) 6 | where TObject : class 7 | { 8 | cancel = true; 9 | } 10 | 11 | public void Done(IValitResult result) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Valit/IValitMessageProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public interface IValitMessageProvider 4 | { 5 | } 6 | 7 | public interface IValitMessageProvider : IValitMessageProvider 8 | { 9 | string GetByKey(TKey key); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Valit/IValitResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | 3 | namespace Valit 4 | { 5 | public interface IValitResult 6 | { 7 | bool Succeeded { get; } 8 | 9 | ImmutableArray ErrorMessages { get; } 10 | 11 | ImmutableArray ErrorCodes { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Valit/IValitRule.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Valit 4 | { 5 | public interface IValitRule 6 | { 7 | IEnumerable Tags { get; } 8 | } 9 | 10 | public interface IValitRule : IValitRule where TObject : class 11 | { 12 | IValitResult Validate(TObject @object); 13 | } 14 | public interface IValitRule : IValitRule where TObject : class 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Valit/IValitRules.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | 5 | namespace Valit 6 | { 7 | public interface IValitRules where TObject : class 8 | { 9 | IValitRules Ensure(Expression> selector, Func, IValitRule> ruleFunc); 10 | IValitRules Ensure(Expression> selector, IValitator valitator) where TProperty : class; 11 | IValitRules EnsureFor(Expression>> selector, Func, IValitRule> ruleFunc); 12 | IValitRules EnsureFor(Expression>> selector, IValitator valitator) where TProperty : class; 13 | IValitRules For(TObject @object); 14 | IEnumerable> GetAllRules(); 15 | IEnumerable> GetTaggedRules(); 16 | IEnumerable> GetUntaggedRules(); 17 | IValitResult Validate(); 18 | IValitResult Validate(params string[] tags); 19 | IValitResult Validate(Func, bool> predicate); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Valit/IValitRulesMessageProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public interface IValitRulesMessageProvider : IValitRulesStrategyPicker 4 | where TObject : class 5 | { 6 | IValitRulesStrategyPicker WithMessageProvider(IValitMessageProvider messageProvider); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valit/IValitRulesStrategyPicker.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public interface IValitRulesStrategyPicker : IValitRules 4 | where TObject : class 5 | { 6 | IValitRules WithStrategy(IValitStrategy strategy); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valit/IValitStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public interface IValitStrategy 4 | { 5 | void Fail(IValitRule rule, IValitResult result, out bool cancel) where TObject : class; 6 | void Done(IValitResult result); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valit/IValitator.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public interface IValitator where TObject : class 4 | { 5 | IValitResult Validate(TObject @object, IValitStrategy strategy = null); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Valit/MessageProvider/EmptyMessageProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Valit.MessageProvider 2 | { 3 | internal sealed class EmptyMessageProvider : IValitMessageProvider 4 | { 5 | public string GetByKey(string key) 6 | => string.Empty; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Valit/Result/ValitResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Immutable; 3 | using System.Linq; 4 | using Valit.Errors; 5 | 6 | namespace Valit.Result 7 | { 8 | internal class ValitResult : IValitResult 9 | { 10 | public static readonly ValitResult Success = new ValitResult(); 11 | 12 | public bool Succeeded { get; } 13 | 14 | public ImmutableArray ErrorCodes { get; private set; } 15 | public ImmutableArray ErrorMessages { get; } 16 | 17 | private ValitResult() 18 | { 19 | Succeeded = true; 20 | ErrorMessages = ImmutableArray.Empty; 21 | ErrorCodes = ImmutableArray.Empty; 22 | } 23 | 24 | private ValitResult(IEnumerable errors) 25 | { 26 | Succeeded = false; 27 | 28 | ErrorMessages = errors 29 | .Where(e => !string.IsNullOrEmpty(e.Message)) 30 | .Select(e => e.Message) 31 | .ToImmutableArray(); 32 | 33 | ErrorCodes = errors 34 | .Where(e => e.ErrorCode.HasValue) 35 | .Select(e => e.ErrorCode.Value) 36 | .ToImmutableArray(); 37 | } 38 | 39 | private ValitResult(ImmutableArray errorMessages, ImmutableArray errorCodes) 40 | { 41 | ErrorMessages = errorMessages; 42 | ErrorCodes = errorCodes; 43 | } 44 | 45 | internal static ValitResult Fail(IEnumerable errors) 46 | => new ValitResult(errors); 47 | 48 | internal static ValitResult Fail(ImmutableArray errorMessages, ImmutableArray errorCodes) 49 | => new ValitResult(errorMessages, errorCodes); 50 | 51 | public static ValitResult operator &(ValitResult result1, IValitResult result2) 52 | { 53 | var succeed = result1.Succeeded && result2.Succeeded; 54 | var errorMessages = result1.ErrorMessages.Concat(result2.ErrorMessages).ToImmutableArray(); 55 | var errorCodes = result1.ErrorCodes.Concat(result2.ErrorCodes).ToImmutableArray(); 56 | return succeed ? Success : Fail(errorMessages, errorCodes); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Valit/Rules/CollectionValitRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using Valit.Exceptions; 6 | using Valit.Result; 7 | 8 | namespace Valit.Rules 9 | { 10 | internal class CollectionValitRule : IValitRule where TObject : class 11 | { 12 | public IEnumerable Tags { get; private set; } 13 | 14 | private readonly Expression>> _collectionSelector; 15 | private readonly Func,IValitRule> _ruleFunc; 16 | private readonly IValitStrategy _strategy; 17 | private readonly IValitMessageProvider _messageProvider; 18 | 19 | public CollectionValitRule( 20 | Expression>> collectionSelector, 21 | Func,IValitRule> ruleFunc, 22 | IValitStrategy strategy, 23 | IValitMessageProvider messageProvider) 24 | { 25 | Tags = Enumerable.Empty(); 26 | _collectionSelector = collectionSelector; 27 | _ruleFunc = ruleFunc; 28 | _strategy = strategy; 29 | _messageProvider = messageProvider; 30 | } 31 | 32 | IValitResult IValitRule.Validate(TObject @object) 33 | { 34 | @object.ThrowIfNull(); 35 | 36 | var collection = _collectionSelector.Compile().Invoke(@object); 37 | 38 | var rules = collection.SelectMany(p => 39 | { 40 | Expression> selector = _ => p; 41 | var lastEnsureRule = _ruleFunc(new ValitRule(selector, _messageProvider)); 42 | return lastEnsureRule.GetAllEnsureRules(); 43 | }); 44 | 45 | return rules.ValidateRules(_strategy, @object); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Valit/Rules/IValitRuleAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using Valit.Errors; 4 | 5 | namespace Valit.Rules 6 | { 7 | internal interface IValitRuleAccessor 8 | { 9 | IValitMessageProvider GetMessageProvider(); 10 | IValitMessageProvider GetMessageProvider(); 11 | void AddError(ValitRuleError error); 12 | void AddTags(params string[] tags); 13 | bool HasPredicate(); 14 | } 15 | 16 | internal interface IValitRuleAccessor : IValitRuleAccessor where TObject : class 17 | { 18 | Expression> PropertySelector { get; } 19 | IValitRule PreviousRule { get; } 20 | void SetPredicate(Predicate predicate); 21 | void AddCondition(Predicate condition); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Valit/Rules/NestedObjectCollectionValitRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using Valit.Exceptions; 6 | using Valit.Result; 7 | 8 | namespace Valit.Rules 9 | { 10 | internal class NestedObjectCollectionValitRule : IValitRule where TObject : class where TProperty : class 11 | { 12 | public IEnumerable Tags { get; private set; } 13 | private readonly Expression>> _collectionSelector; 14 | private readonly IValitator _valitator; 15 | private readonly IValitStrategy _strategy; 16 | 17 | public NestedObjectCollectionValitRule( 18 | Expression>> collectionSelector, 19 | IValitator valitator, 20 | IValitStrategy strategy) 21 | { 22 | Tags = Enumerable.Empty(); 23 | _collectionSelector = collectionSelector; 24 | _valitator = valitator; 25 | _strategy = strategy; 26 | } 27 | 28 | IValitResult IValitRule.Validate(TObject @object) 29 | { 30 | @object.ThrowIfNull(); 31 | 32 | var collection = _collectionSelector.Compile().Invoke(@object); 33 | 34 | var rules = collection.Select(p => 35 | { 36 | Expression> selector = _ => p; 37 | return new NestedObjectValitRule(selector, _valitator, _strategy); 38 | }); 39 | 40 | return rules.ValidateRules(_strategy, @object); 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Valit/Rules/NestedObjectValitRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using Valit.Exceptions; 6 | 7 | namespace Valit.Rules 8 | { 9 | internal class NestedObjectValitRule : IValitRule where TObject : class where TProperty : class 10 | { 11 | public IEnumerable Tags { get; set; } 12 | private readonly Expression> _propertySelector; 13 | private readonly IValitator _valitator; 14 | private readonly IValitStrategy _strategy; 15 | 16 | public NestedObjectValitRule( 17 | Expression> propertySelector, 18 | IValitator valitator, 19 | IValitStrategy strategy) 20 | { 21 | Tags = Enumerable.Empty(); 22 | _propertySelector = propertySelector; 23 | _valitator = valitator; 24 | _strategy = strategy; 25 | } 26 | 27 | public IValitResult Validate(TObject @object) 28 | { 29 | @object.ThrowIfNull(); 30 | 31 | var property = _propertySelector.Compile().Invoke(@object); 32 | return _valitator.Validate(property, _strategy); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Valit/Rules/ValitRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using Valit.Errors; 6 | using Valit.Exceptions; 7 | using Valit.Result; 8 | 9 | namespace Valit.Rules 10 | { 11 | internal class ValitRule : IValitRule, IValitRuleAccessor where TObject : class 12 | { 13 | public IEnumerable Tags => _tags; 14 | 15 | Expression> IValitRuleAccessor.PropertySelector => _propertySelector; 16 | IValitRule IValitRuleAccessor.PreviousRule => _previousRule; 17 | 18 | private readonly Expression> _propertySelector; 19 | private Predicate _predicate; 20 | private readonly List> _conditions; 21 | private readonly IValitRule _previousRule; 22 | private readonly List _errors; 23 | private readonly List _tags; 24 | private readonly IValitMessageProvider _messageProvider; 25 | 26 | internal ValitRule(IValitRule previousRule) : this() 27 | { 28 | var previousRuleAccessor = previousRule.GetAccessor(); 29 | _propertySelector = previousRuleAccessor.PropertySelector; 30 | _previousRule = previousRule; 31 | _messageProvider = previousRuleAccessor.GetMessageProvider(); 32 | } 33 | 34 | internal ValitRule(Expression> propertySelector, IValitMessageProvider messageProvider) : this() 35 | { 36 | _propertySelector = propertySelector; 37 | _messageProvider = messageProvider; 38 | } 39 | 40 | private ValitRule() 41 | { 42 | _errors = new List(); 43 | _conditions = new List>(); 44 | _tags = new List(); 45 | } 46 | 47 | void IValitRuleAccessor.SetPredicate(Predicate predicate) 48 | => _predicate = predicate; 49 | 50 | bool IValitRuleAccessor.HasPredicate() 51 | => _predicate != null; 52 | 53 | void IValitRuleAccessor.AddError(ValitRuleError error) 54 | { 55 | var areAnyDefaultMessages = _errors.Any(e => e.IsDefault); 56 | 57 | if(error.IsDefault && areAnyDefaultMessages) 58 | { 59 | _errors.Clear(); 60 | } 61 | 62 | _errors.Add(error); 63 | } 64 | 65 | void IValitRuleAccessor.AddCondition(Predicate condition) 66 | => _conditions.Add(condition); 67 | 68 | void IValitRuleAccessor.AddTags(params string[] tags) 69 | => _tags.AddRange(tags); 70 | 71 | IValitMessageProvider IValitRuleAccessor.GetMessageProvider() 72 | => _messageProvider; 73 | 74 | IValitMessageProvider IValitRuleAccessor.GetMessageProvider() 75 | => _messageProvider as IValitMessageProvider; 76 | 77 | public IValitResult Validate(TObject @object) 78 | { 79 | @object.ThrowIfNull(); 80 | 81 | var property = _propertySelector.Compile().Invoke(@object); 82 | var hasAllConditionsFulfilled = true; 83 | 84 | foreach (var condition in _conditions) 85 | hasAllConditionsFulfilled &= condition(@object); 86 | 87 | if (!hasAllConditionsFulfilled) 88 | { 89 | return ValitResult.Success; 90 | } 91 | 92 | var isSatisfied = _predicate?.Invoke(property) ?? false; 93 | var errors = _errors.Any(e => !e.IsDefault) ? _errors.Where(e => !e.IsDefault) : _errors; 94 | 95 | return isSatisfied ? ValitResult.Success : ValitResult.Fail(errors.ToArray()); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Valit/Rules/ValitRuleAccessorExtensions.cs: -------------------------------------------------------------------------------- 1 | using Valit.Exceptions; 2 | 3 | namespace Valit.Rules 4 | { 5 | internal static class ValitRuleAccessorExtensions 6 | { 7 | internal static IValitRuleAccessor GetAccessor(this IValitRule rule) where TObject : class 8 | { 9 | var accessor = rule as IValitRuleAccessor; 10 | accessor.ThrowIfNull("Rule doesn't have an accessor"); 11 | 12 | return accessor; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Valit/Rules/ValitRuleExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Valit.Exceptions; 4 | using Valit.Result; 5 | 6 | namespace Valit.Rules 7 | { 8 | internal static class ValitRuleExtensions 9 | { 10 | internal static IValitResult ValidateRules(this IEnumerable> rules, IValitStrategy strategy, TObject @object) where TObject : class 11 | { 12 | rules.ThrowIfNull(); 13 | 14 | var result = ValitResult.Success; 15 | 16 | foreach(var rule in rules.ToList()) 17 | { 18 | result &= rule.Validate(@object); 19 | 20 | if(!result.Succeeded) 21 | { 22 | strategy.Fail(rule, result, out bool cancel); 23 | if(cancel) 24 | { 25 | break; 26 | } 27 | } 28 | } 29 | 30 | strategy.Done(result); 31 | 32 | return result; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Valit/Validators/Valitator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Valit.Validators 4 | { 5 | internal sealed class Valitator : IValitator where TObject : class 6 | { 7 | private readonly IValitRulesStrategyPicker _strategyPicker; 8 | 9 | internal Valitator(IValitRules valitRules) 10 | { 11 | _strategyPicker = ValitRules.Create(valitRules); 12 | } 13 | 14 | IValitResult IValitator.Validate(TObject @object, IValitStrategy strategy) 15 | { 16 | var selectedStrategy = strategy ?? new CompleteValitStrategy(); 17 | 18 | return _strategyPicker 19 | .WithStrategy(selectedStrategy) 20 | .For(@object) 21 | .Validate(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Valit/Valit.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Valit 5 | Valit 6 | Valit 7 | valit;validation;fluentapi 8 | Valit is dead simple validation for .NET Core. No more if-statements all around your code. Write nice and clean fluent validators instead! 9 | Dariusz Pawlukiewicz, Daniel Barwikowski, Arkadiusz Bal 10 | https://github.com/valit-stack/Valit 11 | https://github.com/valit-stack/Valit/blob/master/LICENSE 12 | https://user-images.githubusercontent.com/7096476/32700023-298ffb9e-c7bf-11e7-9d83-82690b7e260b.png 13 | 2.0.0 14 | netstandard2.0 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Valit/ValitException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit 4 | { 5 | public class ValitException : Exception 6 | { 7 | public ValitException(string message, Exception innerException) 8 | :base(message, innerException) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Valit/ValitRuleBooleanExtensions.cs: -------------------------------------------------------------------------------- 1 | using Valit.Errors; 2 | 3 | namespace Valit 4 | { 5 | public static class ValitRuleBooleanExtensions 6 | { 7 | public static IValitRule IsTrue(this IValitRule rule) where TObject : class 8 | => rule.Satisfies(p => p).WithDefaultMessage(ErrorMessages.IsTrue); 9 | 10 | public static IValitRule IsTrue(this IValitRule rule) where TObject : class 11 | => rule.Satisfies(p => p.HasValue && p == true).WithDefaultMessage(ErrorMessages.IsTrue); 12 | 13 | public static IValitRule IsFalse(this IValitRule rule) where TObject : class 14 | => rule.Satisfies(p => !p).WithDefaultMessage(ErrorMessages.IsFalse); 15 | 16 | public static IValitRule IsFalse(this IValitRule rule) where TObject : class 17 | => rule.Satisfies(p => p.HasValue && p == false).WithDefaultMessage(ErrorMessages.IsFalse); 18 | 19 | public static IValitRule IsEqualTo(this IValitRule rule, bool value) where TObject : class 20 | => rule.Satisfies(p => p == value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 21 | 22 | public static IValitRule IsEqualTo(this IValitRule rule, bool? value) where TObject : class 23 | => rule.Satisfies(p => value.HasValue && p == value.Value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 24 | 25 | public static IValitRule IsEqualTo(this IValitRule rule, bool value) where TObject : class 26 | => rule.Satisfies(p => p.HasValue && p.Value == value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 27 | 28 | public static IValitRule IsEqualTo(this IValitRule rule, bool? value) where TObject : class 29 | => rule.Satisfies(p => p.HasValue && value.HasValue && p.Value == value.Value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 30 | 31 | public static IValitRule Required(this IValitRule rule) where TObject : class 32 | => rule.Satisfies(p => p.HasValue).WithDefaultMessage(ErrorMessages.Required); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Valit/ValitRuleEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Valit.Errors; 4 | 5 | namespace Valit 6 | { 7 | public static class ValitRuleEnumerableExtensions 8 | { 9 | 10 | public static IValitRule> MinItems(this IValitRule> rule, int expectedItemsNumber) where TObject : class 11 | => rule.Satisfies(p => p != null && p.Count() >= expectedItemsNumber).WithDefaultMessage(ErrorMessages.MinItems, expectedItemsNumber); 12 | 13 | public static IValitRule> MaxItems(this IValitRule> rule, int expectedItemsNumber) where TObject : class 14 | => rule.Satisfies(p => p != null && p.Count() <= expectedItemsNumber).WithDefaultMessage(ErrorMessages.MaxItems, expectedItemsNumber); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Valit/ValitRuleGuidExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Valit.Errors; 3 | 4 | namespace Valit 5 | { 6 | public static class ValitRuleGuidExtensions 7 | { 8 | public static IValitRule IsEqualTo(this IValitRule rule, Guid value) where TObject : class 9 | => rule.Satisfies(p => p == value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 10 | 11 | public static IValitRule IsEqualTo(this IValitRule rule, Guid? value) where TObject : class 12 | => rule.Satisfies(p => value.HasValue && p == value.Value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 13 | 14 | public static IValitRule IsEqualTo(this IValitRule rule, Guid? value) where TObject : class 15 | => rule.Satisfies(p => p.HasValue && value.HasValue && p.Value == value.Value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 16 | 17 | public static IValitRule IsEqualTo(this IValitRule rule, Guid value) where TObject : class 18 | => rule.Satisfies(p => p.HasValue && p.Value == value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 19 | 20 | public static IValitRule Required(this IValitRule rule) where TObject : class 21 | => rule.Satisfies(p => p.HasValue).WithDefaultMessage(ErrorMessages.Required); 22 | 23 | public static IValitRule IsNotEmpty(this IValitRule rule) where TObject : class 24 | => rule.Satisfies(p => p != Guid.Empty).WithDefaultMessage(ErrorMessages.IsNotEmpty); 25 | 26 | public static IValitRule IsNotEmpty(this IValitRule rule) where TObject : class 27 | => rule.Satisfies(p => p.HasValue && p.Value != Guid.Empty).WithDefaultMessage(ErrorMessages.IsNotEmpty); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Valit/ValitRuleStringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | using Valit.Errors; 4 | 5 | namespace Valit 6 | { 7 | public static class ValitRuleStringExtensions 8 | { 9 | private static string _emailRegularExpression => @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z"; 10 | public static IValitRule IsEqualTo(this IValitRule rule, string value) where TObject : class 11 | => rule.Satisfies(p => p != null && value != null && p == value).WithDefaultMessage(ErrorMessages.IsEqualTo, value); 12 | 13 | public static IValitRule MinLength(this IValitRule rule, int length) where TObject : class 14 | => rule.Satisfies(p => p != null && p.Length >= length).WithDefaultMessage(ErrorMessages.MinLength, length); 15 | 16 | public static IValitRule MaxLength(this IValitRule rule, int length) where TObject : class 17 | => rule.Satisfies(p => p != null && p.Length <= length).WithDefaultMessage(ErrorMessages.MaxLength, length); 18 | 19 | public static IValitRule Matches(this IValitRule rule, string regularExpression) where TObject : class 20 | => rule.Satisfies(p => p != null && !String.IsNullOrEmpty(regularExpression) && Regex.IsMatch(p, regularExpression)).WithDefaultMessage(ErrorMessages.Matches, regularExpression); 21 | 22 | public static IValitRule Email(this IValitRule rule) where TObject : class 23 | => rule.Satisfies(p => p != null && !String.IsNullOrEmpty(_emailRegularExpression) && Regex.IsMatch(p, _emailRegularExpression)).WithDefaultMessage(ErrorMessages.Email); 24 | 25 | public static IValitRule Required(this IValitRule rule) where TObject : class 26 | => rule.Satisfies(p => p != null).WithDefaultMessage(ErrorMessages.Required); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Valit/ValitRulesExtensions.cs: -------------------------------------------------------------------------------- 1 | using Valit.Exceptions; 2 | using Valit.Validators; 3 | 4 | namespace Valit 5 | { 6 | public static class ValitRulesExtensions 7 | { 8 | public static IValitator CreateValitator(this IValitRules valitRules) where TObject : class 9 | { 10 | valitRules.ThrowIfNull(); 11 | return new Valitator(valitRules); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Valit/ValitStrategies.cs: -------------------------------------------------------------------------------- 1 | namespace Valit 2 | { 3 | public struct DefaultValitStrategies 4 | { 5 | static readonly CompleteValitStrategy _complete = new CompleteValitStrategy(); 6 | static readonly FailFastValitStrategy _failFast = new FailFastValitStrategy(); 7 | 8 | public CompleteValitStrategy Complete => _complete; 9 | 10 | public FailFastValitStrategy FailFast => _failFast; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Valit/ValitStrategiesExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit 4 | { 5 | public static class ValitStrategyExtensions 6 | { 7 | public static IValitRules WithStrategy(this IValitRulesStrategyPicker that, Func picker) 8 | where TObject : class 9 | { 10 | var strat = picker(new DefaultValitStrategies()); 11 | 12 | return that.WithStrategy(strat); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Boolean/Boolean_IsEqual_To_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Boolean 6 | { 7 | public class Boolean_IsEqualTo_Tests 8 | { 9 | [Fact] 10 | public void Boolean_IsEqualTo_For_Not_Nullable_Values_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsEqualTo(true); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Boolean_IsEqualTo_For_Not_Nullable_Value_And_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsEqualTo((bool?)true); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | [Fact] 34 | public void Boolean_IsEqualTo_For_Nullable_Value_And_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 35 | { 36 | var exception = Record.Exception(() => 37 | { 38 | ((IValitRule)null) 39 | .IsEqualTo(true); 40 | }); 41 | 42 | exception.ShouldBeOfType(typeof(ValitException)); 43 | } 44 | 45 | [Fact] 46 | public void Boolean_IsEqualTo_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 47 | { 48 | var exception = Record.Exception(() => 49 | { 50 | ((IValitRule)null) 51 | .IsEqualTo((bool?)true); 52 | }); 53 | 54 | exception.ShouldBeOfType(typeof(ValitException)); 55 | } 56 | 57 | [Theory] 58 | [InlineData(true, true)] 59 | [InlineData(false, false)] 60 | public void Boolean_IsEqualTo_Returns_Proper_Results_For_Not_Nullable_Values(bool value, bool expected) 61 | { 62 | IValitResult result = ValitRules 63 | .Create() 64 | .Ensure(m => m.Value, _ => _ 65 | .IsEqualTo(value)) 66 | .For(_model) 67 | .Validate(); 68 | 69 | result.Succeeded.ShouldBe(expected); 70 | } 71 | 72 | [Theory] 73 | [InlineData(false, true, true)] 74 | [InlineData(false, false, false)] 75 | [InlineData(true, true, false)] 76 | [InlineData(true, false, false)] 77 | public void Boolean_IsEqualTo_Returns_Proper_Results_For_Nullable_Value_And_Not_Nullable_Value(bool useNullValue, bool value, bool expected) 78 | { 79 | IValitResult result = ValitRules 80 | .Create() 81 | .Ensure(m => useNullValue ? m.NullValue : m.NullableValue, _ => _ 82 | .IsEqualTo(value)) 83 | .For(_model) 84 | .Validate(); 85 | 86 | result.Succeeded.ShouldBe(expected); 87 | } 88 | 89 | #region ARRANGE 90 | public Boolean_IsEqualTo_Tests() 91 | { 92 | _model = new Model(); 93 | } 94 | 95 | private readonly Model _model; 96 | 97 | class Model 98 | { 99 | public bool Value => true; 100 | public bool? NullableValue => true; 101 | public bool? NullValue => null; 102 | } 103 | #endregion 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Boolean/Boolean_IsFalse_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Boolean 6 | { 7 | public class Boolean_IsFalse_Tests 8 | { 9 | [Fact] 10 | public void Boolean_IsFalse_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsFalse(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Boolean_IsFalse_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsFalse(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | [Theory] 34 | [InlineData(true, false)] 35 | [InlineData(false, true)] 36 | public void Boolean_IsFalse_Returns_Proper_Results_For_Not_Nullable_Values(bool useTrueValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useTrueValue ? m.TrueValue : m.FalseValue, _ => _ 41 | .IsFalse()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(true, false)] 50 | [InlineData(false, true)] 51 | public void Boolean_IsFalse_Returns_Proper_Results_For_Nullable_Values(bool useTrueValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useTrueValue ? m.NullableTrueValue : m.NullableFalseValue, _ => _ 56 | .IsFalse()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Boolean_IsFalse_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsFalse()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | 77 | #region ARRANGE 78 | public Boolean_IsFalse_Tests() 79 | { 80 | _model = new Model(); 81 | } 82 | 83 | private readonly Model _model; 84 | 85 | class Model 86 | { 87 | public bool TrueValue => true; 88 | public bool FalseValue => false; 89 | public bool? NullableTrueValue => true; 90 | public bool? NullableFalseValue => false; 91 | public bool? NullValue => null; 92 | } 93 | #endregion 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Boolean/Boolean_IsTrue_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Boolean 6 | { 7 | public class Boolean_IsTrue_Tests 8 | { 9 | [Fact] 10 | public void Boolean_IsTrue_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsTrue(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Boolean_IsTrue_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsTrue(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | [Theory] 34 | [InlineData(true, true)] 35 | [InlineData(false, false)] 36 | public void Boolean_IsTrue_Returns_Proper_Results_For_Not_Nullable_Values(bool useTrueValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useTrueValue ? m.TrueValue : m.FalseValue, _ => _ 41 | .IsTrue()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(true, true)] 50 | [InlineData(false, false)] 51 | public void Boolean_IsTrue_Returns_Proper_Results_For_Nullable_Values(bool useTrueValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useTrueValue ? m.NullableTrueValue : m.NullableFalseValue, _ => _ 56 | .IsTrue()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Boolean_IsTrue_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsTrue()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | 77 | #region ARRANGE 78 | public Boolean_IsTrue_Tests() 79 | { 80 | _model = new Model(); 81 | } 82 | 83 | private readonly Model _model; 84 | 85 | class Model 86 | { 87 | public bool TrueValue => true; 88 | public bool FalseValue => false; 89 | public bool? NullableTrueValue => true; 90 | public bool? NullableFalseValue => false; 91 | public bool? NullValue => null; 92 | } 93 | #endregion 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Boolean/Boolean_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Boolean 5 | { 6 | public class Boolean_Required_Tests 7 | { 8 | [Fact] 9 | public void Boolean_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void Boolean_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue ? m.NullValue : m.NullableValue, _ => _ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public Boolean_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public bool? NullableValue => true; 47 | public bool? NullValue => null; 48 | } 49 | #endregion 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Byte/Byte_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Byte 5 | { 6 | public class Byte_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void Byte_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Byte_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void Byte_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void Byte_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Byte_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public Byte_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public byte Value => 10; 87 | public byte ZeroValue => 0; 88 | public byte? NullableValue => 10; 89 | public byte? NullableZeroValue => 0; 90 | public byte? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Byte/Byte_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Byte 5 | { 6 | public class Byte_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void Byte_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .Required(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | 22 | [Theory] 23 | [InlineData(false, true)] 24 | [InlineData(true, false)] 25 | public void Byte_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 26 | { 27 | IValitResult result = ValitRules 28 | .Create() 29 | .Ensure(m => useNullValue ? m.NullValue : m.NullableValue, _ => _ 30 | .Required()) 31 | .For(_model) 32 | .Validate(); 33 | 34 | result.Succeeded.ShouldBe(expected); 35 | } 36 | 37 | #region ARRANGE 38 | public Byte_Required_Tests() 39 | { 40 | _model = new Model(); 41 | } 42 | 43 | private readonly Model _model; 44 | 45 | class Model 46 | { 47 | public byte Value => 10; 48 | public byte ZeroValue => 0; 49 | public byte? NullableValue => 10; 50 | public byte? NullableZeroValue => 0; 51 | public byte? NullValue => null; 52 | } 53 | #endregion 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTimeOffset_/DateTimeOffset_IsAfterNow_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTimeOffset_ 7 | { 8 | public class DateTimeOffset_IsAfterNow_Tests 9 | { 10 | [Fact] 11 | public void DateTimeOffset_IsAfterNow_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .IsAfterNow(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void DateTimeOffset_IsAfterNow_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 24 | { 25 | var exception = Record.Exception(() => 26 | { 27 | ((IValitRule)null) 28 | .IsAfterNow(); 29 | }); 30 | 31 | exception.ShouldBeOfType(typeof(ValitException)); 32 | } 33 | 34 | [Fact] 35 | public void DateTimeOffset_IsAfterNow_For_Not_Nullable_Value_Succeeds_When_Value_Is_After_DateTimeOffset_Now() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.AfterNowValue, _ => _ 40 | .IsAfterNow()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void DateTimeOffset_IsAfterNow_For_Not_Nullable_Value_Fails_When_Value_Is_Before_DateTimeOffset_Now() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.BeforeNowValue, _ => _ 53 | .IsAfterNow()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void DateTimeOffset_IsAfterNow_For_Nullable_Value_Succeeds_When_Value_Is_After_DateTimeOffset_Now() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableAfterNowValue, _ => _ 66 | .IsAfterNow()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void DateTimeOffset_IsAfterNow_For_Nullable_Value_Fails_When_Value_Is_Before_DateTimeOffset_Now() 75 | { 76 | var result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullableBeforeNowValue, _ => _ 79 | .IsAfterNow()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void DateTimeOffset_IsAfterNow_For_Nullable_Value_Fails_When_Value_Is_Null() 88 | { 89 | var result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsAfterNow()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public DateTimeOffset_IsAfterNow_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public DateTimeOffset BeforeNowValue => DateTimeOffset.Now.AddDays(-1); 110 | public DateTimeOffset AfterNowValue => DateTimeOffset.Now.AddDays(1); 111 | public DateTimeOffset? NullableBeforeNowValue => DateTimeOffset.Now.AddDays(-1); 112 | public DateTimeOffset? NullableAfterNowValue => DateTimeOffset.Now.AddDays(1); 113 | public DateTimeOffset? NullValue => null; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTimeOffset_/DateTimeOffset_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTimeOffset_ 7 | { 8 | public class DateTimeOffset_Required_Tests 9 | { 10 | [Fact] 11 | public void DateTimeOffset_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => { 14 | ((IValitRule)null) 15 | .Required(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | 22 | [Theory] 23 | [InlineData(false, true)] 24 | [InlineData(true, false)] 25 | public void DateTimeOffset_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 26 | { 27 | IValitResult result = ValitRules 28 | .Create() 29 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 30 | .Required()) 31 | .For(_model) 32 | .Validate(); 33 | 34 | result.Succeeded.ShouldBe(expected); 35 | } 36 | 37 | #region ARRANGE 38 | public DateTimeOffset_Required_Tests() 39 | { 40 | _model = new Model(); 41 | } 42 | 43 | private readonly Model _model; 44 | 45 | class Model 46 | { 47 | public DateTimeOffset? NullableValue => DateTimeOffset.Now; 48 | public DateTimeOffset? NullValue => null; 49 | } 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTime_/DateTime_IsAfterNow_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTime_ 7 | { 8 | public class DateTime_IsAfterNow_Tests 9 | { 10 | [Fact] 11 | public void DateTime_IsAfterNow_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .IsAfterNow(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void DateTime_IsAfterNow_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 24 | { 25 | var exception = Record.Exception(() => 26 | { 27 | ((IValitRule)null) 28 | .IsAfterNow(); 29 | }); 30 | 31 | exception.ShouldBeOfType(typeof(ValitException)); 32 | } 33 | 34 | [Fact] 35 | public void DateTime_IsAfterNow_For_Not_Nullable_Value_Succeeds_When_Value_Is_After_DateTime_Now() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.AfterNowValue, _ => _ 40 | .IsAfterNow()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void DateTime_IsAfterNow_For_Not_Nullable_Value_Fails_When_Value_Is_Before_DateTime_Now() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.BeforeNowValue, _ => _ 53 | .IsAfterNow()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void DateTime_IsAfterNow_For_Nullable_Value_Succeeds_When_Value_Is_After_DateTime_Now() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableAfterNowValue, _ => _ 66 | .IsAfterNow()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void DateTime_IsAfterNow_For_Nullable_Value_Fails_When_Value_Is_Before_DateTime_Now() 75 | { 76 | var result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullableBeforeNowValue, _ => _ 79 | .IsAfterNow()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void DateTime_IsAfterNow_For_Nullable_Value_Fails_When_Value_Is_Null() 88 | { 89 | var result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsAfterNow()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public DateTime_IsAfterNow_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public DateTime BeforeNowValue => DateTime.Now.AddDays(-1); 110 | public DateTime AfterNowValue => DateTime.Now.AddDays(1); 111 | public DateTime? NullableBeforeNowValue => DateTime.Now.AddDays(-1); 112 | public DateTime? NullableAfterNowValue => DateTime.Now.AddDays(1); 113 | public DateTime? NullValue => null; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTime_/DateTime_IsAfterUtcNow_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTime_ 7 | { 8 | public class DateTime_IsAfterUtcNow_Tests 9 | { 10 | [Fact] 11 | public void DateTime_IsAfterUtcNow_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .IsAfterUtcNow(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void DateTime_IsAfterUtcNow_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 24 | { 25 | var exception = Record.Exception(() => 26 | { 27 | ((IValitRule)null) 28 | .IsAfterUtcNow(); 29 | }); 30 | 31 | exception.ShouldBeOfType(typeof(ValitException)); 32 | } 33 | 34 | [Fact] 35 | public void DateTime_IsAfterUtcNow_For_Not_Nullable_Value_Succeeds_When_Value_Is_After_DateTime_Now() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.AfterNowValue, _ => _ 40 | .IsAfterUtcNow()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void DateTime_IsAfterUtcNow_For_Not_Nullable_Value_Fails_When_Value_Is_Before_DateTime_Now() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.BeforeNowValue, _ => _ 53 | .IsAfterUtcNow()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void DateTime_IsAfterUtcNow_For_Nullable_Value_Succeeds_When_Value_Is_After_DateTime_Now() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableAfterNowValue, _ => _ 66 | .IsAfterUtcNow()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void DateTime_IsAfterUtcNow_For_Nullable_Value_Fails_When_Value_Is_Before_DateTime_Now() 75 | { 76 | var result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullableBeforeNowValue, _ => _ 79 | .IsAfterUtcNow()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void DateTime_IsAfterUtcNow_For_Nullable_Value_Fails_When_Value_Is_Null() 88 | { 89 | var result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsAfterUtcNow()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public DateTime_IsAfterUtcNow_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public DateTime BeforeNowValue => DateTime.UtcNow.AddDays(-1); 110 | public DateTime AfterNowValue => DateTime.UtcNow.AddDays(1); 111 | public DateTime? NullableBeforeNowValue => DateTime.UtcNow.AddDays(-1); 112 | public DateTime? NullableAfterNowValue => DateTime.UtcNow.AddDays(1); 113 | public DateTime? NullValue => null; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTime_/DateTime_IsBeforeNow_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTime_ 7 | { 8 | public class DateTime_IsBeforeNow_Tests 9 | { 10 | [Fact] 11 | public void DateTime_IsBeforeNow_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .IsBeforeNow(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void DateTime_IsBeforeNow_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 24 | { 25 | var exception = Record.Exception(() => 26 | { 27 | ((IValitRule)null) 28 | .IsBeforeNow(); 29 | }); 30 | 31 | exception.ShouldBeOfType(typeof(ValitException)); 32 | } 33 | 34 | [Fact] 35 | public void DateTime_IsBeforeNow_For_Not_Nullable_Value_Succeeds_When_Value_Is_Before_DateTime_Now() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.BeforeNowValue, _ => _ 40 | .IsBeforeNow()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void DateTime_IsBeforeNow_For_Not_Nullable_Value_Fails_When_Value_Is_After_DateTime_Now() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.AfterNowValue, _ => _ 53 | .IsBeforeNow()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void DateTime_IsBeforeNow_For_Nullable_Value_Succeeds_When_Value_Is_Before_DateTime_Now() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableBeforeNowValue, _ => _ 66 | .IsBeforeNow()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void DateTime_IsBeforeNow_For_Nullable_Value_Fails_When_Value_Is_After_DateTime_Now() 75 | { 76 | var result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullableAfterNowValue, _ => _ 79 | .IsBeforeNow()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void DateTime_IsBeforeNow_For_Nullable_Value_Fails_When_Value_Is_Null() 88 | { 89 | var result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsBeforeNow()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public DateTime_IsBeforeNow_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public DateTime BeforeNowValue => DateTime.Now.AddDays(-1); 110 | public DateTime AfterNowValue => DateTime.Now.AddDays(1); 111 | public DateTime? NullableBeforeNowValue => DateTime.Now.AddDays(-1); 112 | public DateTime? NullableAfterNowValue => DateTime.Now.AddDays(1); 113 | public DateTime? NullValue => null; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTime_/DateTime_IsBeforeUtcNow_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTime_ 7 | { 8 | public class DateTime_IsBeforeUtcNow_Tests 9 | { 10 | [Fact] 11 | public void DateTime_IsBeforeUtcNow_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .IsBeforeUtcNow(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void DateTime_IsBeforeUtcNow_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 24 | { 25 | var exception = Record.Exception(() => 26 | { 27 | ((IValitRule)null) 28 | .IsBeforeUtcNow(); 29 | }); 30 | 31 | exception.ShouldBeOfType(typeof(ValitException)); 32 | } 33 | 34 | [Fact] 35 | public void DateTime_IsBeforeUtcNow_For_Not_Nullable_Value_Succeeds_When_Value_Is_Before_DateTime_Now() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.BeforeNowValue, _ => _ 40 | .IsBeforeUtcNow()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void DateTime_IsBeforeUtcNow_For_Not_Nullable_Value_Fails_When_Value_Is_After_DateTime_Now() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.AfterNowValue, _ => _ 53 | .IsBeforeUtcNow()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void DateTime_IsBeforeUtcNow_For_Nullable_Value_Succeeds_When_Value_Is_Before_DateTime_Now() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableBeforeNowValue, _ => _ 66 | .IsBeforeUtcNow()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void DateTime_IsBeforeUtcNow_For_Nullable_Value_Fails_When_Value_Is_After_DateTime_Now() 75 | { 76 | var result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullableAfterNowValue, _ => _ 79 | .IsBeforeUtcNow()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void DateTime_IsBeforeUtcNow_For_Nullable_Value_Fails_When_Value_Is_Null() 88 | { 89 | var result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsBeforeUtcNow()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public DateTime_IsBeforeUtcNow_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public DateTime BeforeNowValue => DateTime.UtcNow.AddDays(-1); 110 | public DateTime AfterNowValue => DateTime.UtcNow.AddDays(1); 111 | public DateTime? NullableBeforeNowValue => DateTime.UtcNow.AddDays(-1); 112 | public DateTime? NullableAfterNowValue => DateTime.UtcNow.AddDays(1); 113 | public DateTime? NullValue => null; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/DateTime_/DateTime_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Valit.Tests.HelperExtensions; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.DateTime_ 7 | { 8 | public class DateTime_Required_Tests 9 | { 10 | [Fact] 11 | public void DateTime_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => { 14 | ((IValitRule)null) 15 | .Required(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | 22 | [Theory] 23 | [InlineData(false, true)] 24 | [InlineData(true, false)] 25 | public void DateTime_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 26 | { 27 | IValitResult result = ValitRules 28 | .Create() 29 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 30 | .Required()) 31 | .For(_model) 32 | .Validate(); 33 | 34 | result.Succeeded.ShouldBe(expected); 35 | } 36 | 37 | #region ARRANGE 38 | public DateTime_Required_Tests() 39 | { 40 | _model = new Model(); 41 | } 42 | 43 | private readonly Model _model; 44 | 45 | class Model 46 | { 47 | public DateTime? NullableValue => DateTime.Now; 48 | public DateTime? NullValue => null; 49 | } 50 | #endregion 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Decimal/Decimal_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Decimal 5 | { 6 | public class Decimal_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void Decimal_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Decimal_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void Decimal_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void Decimal_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Decimal_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public Decimal_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public decimal Value => 10; 87 | public decimal ZeroValue => 0; 88 | public decimal? NullableValue => 10; 89 | public decimal? NullableZeroValue => 0; 90 | public decimal? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Decimal/Decimal_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Decimal 5 | { 6 | public class Decimal_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void Decimal_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void Decimal_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public Decimal_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public decimal Value => 10; 47 | public decimal ZeroValue => 0; 48 | public decimal? NullableValue => 10; 49 | public decimal? NullableZeroValue => 0; 50 | public decimal? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Double/Double_IsNaN_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Double 6 | { 7 | public class Double_IsNaN_Tests 8 | { 9 | [Fact] 10 | public void Double_IsNaN_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNaN(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Double_IsNaN_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNaN(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | 34 | [Fact] 35 | public void Double_IsNaN_Fails_When_Value_Is_Given() 36 | { 37 | IValitResult result = ValitRules 38 | .Create() 39 | .Ensure(m => m.Value, _ => _ 40 | .IsNaN()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeFalse(); 45 | } 46 | 47 | [Fact] 48 | public void Double_IsNaN_Succeeds_When_NaN_Is_Given() 49 | { 50 | IValitResult result = ValitRules 51 | .Create() 52 | .Ensure(m => m.NaN, _ => _ 53 | .IsNaN()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeTrue(); 58 | } 59 | 60 | [Fact] 61 | public void Double_IsNaN_False_When_NullableValue_Is_Given() 62 | { 63 | IValitResult result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableValue, _ => _ 66 | .IsNaN()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeFalse(); 71 | } 72 | 73 | [Fact] 74 | public void Double_IsNaN_Fails_When_Null_Is_Given() 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullValue, _ => _ 79 | .IsNaN()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void Double_IsNaN_Fails_When_NullableNaN_Is_Given() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullableNaN, _ => _ 92 | .IsNaN()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeTrue(); 97 | } 98 | 99 | #region ARRANGE 100 | public Double_IsNaN_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public double Value => 0; 110 | public double NaN => double.NaN; 111 | public double? NullableValue => 0; 112 | public double? NullValue => null; 113 | public double? NullableNaN => double.NaN; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Double/Double_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Double 6 | { 7 | public class Double_IsNonZero_Tests 8 | { 9 | [Fact] 10 | public void Double_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNonZero(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Double_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNonZero(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | public void Double_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 34 | { 35 | IValitResult result = ValitRules 36 | .Create() 37 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 38 | .IsNonZero()) 39 | .For(_model) 40 | .Validate(); 41 | 42 | result.Succeeded.ShouldBe(expected); 43 | } 44 | 45 | [Fact] 46 | public void Double_IsNonZero_Fails_For_NaN() 47 | { 48 | IValitResult result = ValitRules 49 | .Create() 50 | .Ensure(m => m.NaN, _ => _ 51 | .IsNonZero()) 52 | .For(_model) 53 | .Validate(); 54 | 55 | result.Succeeded.ShouldBeFalse(); 56 | } 57 | 58 | [Fact] 59 | public void Double_IsNonZero_Fails_For_NullableNaN() 60 | { 61 | IValitResult result = ValitRules 62 | .Create() 63 | .Ensure(m => m.NullableNaN, _ => _ 64 | .IsNonZero()) 65 | .For(_model) 66 | .Validate(); 67 | 68 | result.Succeeded.ShouldBeFalse(); 69 | } 70 | 71 | [Theory] 72 | [InlineData(false, true)] 73 | [InlineData(true, false)] 74 | public void Double_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 79 | .IsNonZero()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBe(expected); 84 | } 85 | 86 | [Fact] 87 | public void Double_IsNonZero_Fails_For_Null_Value() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsNonZero()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public Double_IsNonZero_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public double Value => 10; 110 | public double ZeroValue => 0; 111 | public double NaN => double.NaN; 112 | public double? NullableValue => 10; 113 | public double? NullableZeroValue => 0; 114 | public double? NullValue => null; 115 | public double? NullableNaN => double.NaN; 116 | } 117 | #endregion 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Double/Double_IsNumber_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Double 6 | { 7 | public class Double_IsNumber_Tests 8 | { 9 | [Fact] 10 | public void Double_IsNumber_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNumber(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Double_IsNumber_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNumber(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | 34 | [Fact] 35 | public void Double_IsNumber_Succeeds_When_Value_Is_Given() 36 | { 37 | IValitResult result = ValitRules 38 | .Create() 39 | .Ensure(m => m.Value, _ => _ 40 | .IsNumber()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void Double_IsNumber_Fails_When_NaN_Is_Given() 49 | { 50 | IValitResult result = ValitRules 51 | .Create() 52 | .Ensure(m => m.NaN, _ => _ 53 | .IsNumber()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void Double_IsNumber_Succeeds_When_NullableValue_Is_Given() 62 | { 63 | IValitResult result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableValue, _ => _ 66 | .IsNumber()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void Double_IsNumber_Fails_When_Null_Is_Given() 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullValue, _ => _ 79 | .IsNumber()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void Double_IsNumber_Fails_When_NullableNaN_Is_Given() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullableNaN, _ => _ 92 | .IsNumber()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public Double_IsNumber_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public double Value => 0; 110 | public double NaN => double.NaN; 111 | public double? NullableValue => 0; 112 | public double? NullValue => null; 113 | public double? NullableNaN => double.NaN; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Double/Double_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Double 6 | { 7 | public class Double_Required_Tests 8 | { 9 | 10 | [Fact] 11 | public void Double_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .Required(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void Double_Required_Succeeds_For_NullableValue() 24 | { 25 | IValitResult result = ValitRules 26 | .Create() 27 | .Ensure(m => m.NullableValue, _ => _ 28 | .Required()) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBeTrue(); 33 | } 34 | 35 | [Fact] 36 | public void Double_Required_Fails_For_NullValue() 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => m.NullValue, _ => _ 41 | .Required()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBeFalse(); 46 | } 47 | 48 | [Fact] 49 | public void Double_Required_Succeeds_For_NullableNaN() 50 | { 51 | IValitResult result = ValitRules 52 | .Create() 53 | .Ensure(m => m.NullableNaN, _ => _ 54 | .Required()) 55 | .For(_model) 56 | .Validate(); 57 | 58 | result.Succeeded.ShouldBeTrue(); 59 | } 60 | 61 | #region ARRANGE 62 | public Double_Required_Tests() 63 | { 64 | _model = new Model(); 65 | } 66 | 67 | private readonly Model _model; 68 | 69 | class Model 70 | { 71 | public double? NullableValue => 10; 72 | public double? NullValue => null; 73 | public double? NullableNaN => double.NaN; 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Enumerable/Enumerable_MaxItems_Tests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace Valit.Tests.Enumerable 7 | { 8 | public class Enumerable_MaxItems_Tests 9 | { 10 | [Fact] 11 | public void Enumerable_MaxItems_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule>)null) 16 | .MaxItems(1); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void Enumerable_MaxItems_Succeeds_If_ExpectedItemsNumber_Is_Greater_Than_Number_Of_Items_In_Collection() 24 | { 25 | var result = ValitRules 26 | .Create() 27 | .Ensure(m => m.Collection, _ => _ 28 | .MaxItems(5)) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBeTrue(); 33 | } 34 | 35 | [Fact] 36 | public void Enumerable_MaxItems_Succeeds_If_ExpectedItemsNumber_Is_Equal_To_Number_Of_Items_In_Collection() 37 | { 38 | var result = ValitRules 39 | .Create() 40 | .Ensure(m => m.Collection, _ => _ 41 | .MaxItems(3)) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBeTrue(); 46 | } 47 | 48 | [Fact] 49 | public void Enumerable_MaxItems_Fails_If_ExpectedItemsNumber_Is_Less_Than_Number_Of_Items_In_Collection() 50 | { 51 | var result = ValitRules 52 | .Create() 53 | .Ensure(m => m.Collection, _ => _ 54 | .MaxItems(2)) 55 | .For(_model) 56 | .Validate(); 57 | 58 | result.Succeeded.ShouldBeFalse(); 59 | } 60 | 61 | [Fact] 62 | public void Enumerable_MaxItems_Fails_If_Null_Collection_Is_Given() 63 | { 64 | var result = ValitRules 65 | .Create() 66 | .Ensure(m => m.NullCollection, _ => _ 67 | .MaxItems(5)) 68 | .For(_model) 69 | .Validate(); 70 | 71 | result.Succeeded.ShouldBeFalse(); 72 | } 73 | 74 | #region ARRANGE 75 | public Enumerable_MaxItems_Tests() 76 | { 77 | _model = new Model(); 78 | } 79 | 80 | private readonly Model _model; 81 | 82 | class Model 83 | { 84 | public IEnumerable Collection => new List { 1, 2, 3 }; 85 | public IEnumerable NullCollection => null; 86 | } 87 | #endregion 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Enumerable/Enumerable_MinItems_Tests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Enumerable 6 | { 7 | public class Enumerable_MinItems_Tests 8 | { 9 | [Fact] 10 | public void Enumerable_MinItems_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule>)null) 15 | .MinItems(1); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Enumerable_MinItems_Succeeds_If_ExpectedItemsNumber_Is_Less_Than_Number_Of_Items_In_Collection() 23 | { 24 | var result = ValitRules 25 | .Create() 26 | .Ensure(m => m.Collection, _ => _ 27 | .MinItems(1)) 28 | .For(_model) 29 | .Validate(); 30 | 31 | result.Succeeded.ShouldBeTrue(); 32 | } 33 | 34 | [Fact] 35 | public void Enumerable_MinItems_Succeeds_If_ExpectedItemsNumber_Is_Equal_To_Number_Of_Items_In_Collection() 36 | { 37 | var result = ValitRules 38 | .Create() 39 | .Ensure(m => m.Collection, _ => _ 40 | .MinItems(3)) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void Enumerable_MinItems_Fails_If_ExpectedItemsNumber_Is_Greater_Than_Number_Of_Items_In_Collection() 49 | { 50 | var result = ValitRules 51 | .Create() 52 | .Ensure(m => m.Collection, _ => _ 53 | .MinItems(5)) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void Enumerable_MaxItems_Fails_If_Null_Collection_Is_Given() 62 | { 63 | var result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullCollection, _ => _ 66 | .MinItems(1)) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeFalse(); 71 | } 72 | 73 | 74 | #region ARRANGE 75 | public Enumerable_MinItems_Tests() 76 | { 77 | _model = new Model(); 78 | } 79 | 80 | private readonly Model _model; 81 | 82 | class Model 83 | { 84 | public IEnumerable Collection => new List { 1, 2, 3 }; 85 | public IEnumerable NullCollection => null; 86 | } 87 | #endregion 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Float/Float_IsNaN_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Float 6 | { 7 | public class Float_IsNaN_Tests 8 | { 9 | [Fact] 10 | public void Float_IsNaN_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNaN(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Float_IsNaN_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNaN(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | 34 | [Fact] 35 | public void Float_IsNaN_Fails_When_Value_Is_Given() 36 | { 37 | IValitResult result = ValitRules 38 | .Create() 39 | .Ensure(m => m.Value, _ => _ 40 | .IsNaN()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeFalse(); 45 | } 46 | 47 | [Fact] 48 | public void Float_IsNaN_Succeeds_When_NaN_Is_Given() 49 | { 50 | IValitResult result = ValitRules 51 | .Create() 52 | .Ensure(m => m.NaN, _ => _ 53 | .IsNaN()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeTrue(); 58 | } 59 | 60 | [Fact] 61 | public void Float_IsNaN_False_When_NullableValue_Is_Given() 62 | { 63 | IValitResult result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableValue, _ => _ 66 | .IsNaN()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeFalse(); 71 | } 72 | 73 | [Fact] 74 | public void Float_IsNaN_Fails_When_Null_Is_Given() 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullValue, _ => _ 79 | .IsNaN()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void Float_IsNaN_Fails_When_NullableNaN_Is_Given() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullableNaN, _ => _ 92 | .IsNaN()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeTrue(); 97 | } 98 | 99 | #region ARRANGE 100 | public Float_IsNaN_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public float Value => 0; 110 | public float NaN => Single.NaN; 111 | public float? NullableValue => 0; 112 | public float? NullValue => null; 113 | public float? NullableNaN => Single.NaN; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Float/Float_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Float 6 | { 7 | public class Float_IsNonZero_Tests 8 | { 9 | [Fact] 10 | public void Float_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNonZero(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Float_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNonZero(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | public void Float_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 34 | { 35 | IValitResult result = ValitRules 36 | .Create() 37 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 38 | .IsNonZero()) 39 | .For(_model) 40 | .Validate(); 41 | 42 | result.Succeeded.ShouldBe(expected); 43 | } 44 | 45 | [Fact] 46 | public void Float_IsNonZero_Fails_For_NaN() 47 | { 48 | IValitResult result = ValitRules 49 | .Create() 50 | .Ensure(m => m.NaN, _ => _ 51 | .IsNonZero()) 52 | .For(_model) 53 | .Validate(); 54 | 55 | result.Succeeded.ShouldBeFalse(); 56 | } 57 | 58 | [Fact] 59 | public void Float_IsNonZero_Fails_For_NullableNaN() 60 | { 61 | IValitResult result = ValitRules 62 | .Create() 63 | .Ensure(m => m.NullableNaN, _ => _ 64 | .IsNonZero()) 65 | .For(_model) 66 | .Validate(); 67 | 68 | result.Succeeded.ShouldBeFalse(); 69 | } 70 | 71 | [Theory] 72 | [InlineData(false, true)] 73 | [InlineData(true, false)] 74 | public void Float_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 79 | .IsNonZero()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBe(expected); 84 | } 85 | 86 | [Fact] 87 | public void Float_IsNonZero_Fails_For_Null_Value() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullValue, _ => _ 92 | .IsNonZero()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public Float_IsNonZero_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public float Value => 10; 110 | public float ZeroValue => 0; 111 | public float NaN => Single.NaN; 112 | public float? NullableValue => 10; 113 | public float? NullableZeroValue => 0; 114 | public float? NullValue => null; 115 | public float? NullableNaN => Single.NaN; 116 | } 117 | #endregion 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Float/Float_IsNumber_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Float 6 | { 7 | public class Float_IsNumber_Tests 8 | { 9 | [Fact] 10 | public void Float_IsNumber_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .IsNumber(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | [Fact] 22 | public void Float_IsNumber_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 23 | { 24 | var exception = Record.Exception(() => 25 | { 26 | ((IValitRule)null) 27 | .IsNumber(); 28 | }); 29 | 30 | exception.ShouldBeOfType(typeof(ValitException)); 31 | } 32 | 33 | 34 | [Fact] 35 | public void Float_IsNumber_Succeeds_When_Value_Is_Given() 36 | { 37 | IValitResult result = ValitRules 38 | .Create() 39 | .Ensure(m => m.Value, _ => _ 40 | .IsNumber()) 41 | .For(_model) 42 | .Validate(); 43 | 44 | result.Succeeded.ShouldBeTrue(); 45 | } 46 | 47 | [Fact] 48 | public void Float_IsNumber_Fails_When_NaN_Is_Given() 49 | { 50 | IValitResult result = ValitRules 51 | .Create() 52 | .Ensure(m => m.NaN, _ => _ 53 | .IsNumber()) 54 | .For(_model) 55 | .Validate(); 56 | 57 | result.Succeeded.ShouldBeFalse(); 58 | } 59 | 60 | [Fact] 61 | public void Float_IsNumber_Succeeds_When_NullableValue_Is_Given() 62 | { 63 | IValitResult result = ValitRules 64 | .Create() 65 | .Ensure(m => m.NullableValue, _ => _ 66 | .IsNumber()) 67 | .For(_model) 68 | .Validate(); 69 | 70 | result.Succeeded.ShouldBeTrue(); 71 | } 72 | 73 | [Fact] 74 | public void Float_IsNumber_Fails_When_Null_Is_Given() 75 | { 76 | IValitResult result = ValitRules 77 | .Create() 78 | .Ensure(m => m.NullValue, _ => _ 79 | .IsNumber()) 80 | .For(_model) 81 | .Validate(); 82 | 83 | result.Succeeded.ShouldBeFalse(); 84 | } 85 | 86 | [Fact] 87 | public void Float_IsNumber_Fails_When_NullableNaN_Is_Given() 88 | { 89 | IValitResult result = ValitRules 90 | .Create() 91 | .Ensure(m => m.NullableNaN, _ => _ 92 | .IsNumber()) 93 | .For(_model) 94 | .Validate(); 95 | 96 | result.Succeeded.ShouldBeFalse(); 97 | } 98 | 99 | #region ARRANGE 100 | public Float_IsNumber_Tests() 101 | { 102 | _model = new Model(); 103 | } 104 | 105 | private readonly Model _model; 106 | 107 | class Model 108 | { 109 | public float Value => 0; 110 | public float NaN => Single.NaN; 111 | public float? NullableValue => 0; 112 | public float? NullValue => null; 113 | public float? NullableNaN => Single.NaN; 114 | } 115 | #endregion 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Float/Float_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Float 6 | { 7 | public class Float_Required_Tests 8 | { 9 | 10 | [Fact] 11 | public void Float_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 12 | { 13 | var exception = Record.Exception(() => 14 | { 15 | ((IValitRule)null) 16 | .Required(); 17 | }); 18 | 19 | exception.ShouldBeOfType(typeof(ValitException)); 20 | } 21 | 22 | [Fact] 23 | public void Float_Required_Succeeds_For_NullableValue() 24 | { 25 | IValitResult result = ValitRules 26 | .Create() 27 | .Ensure(m => m.NullableValue, _ => _ 28 | .Required()) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBeTrue(); 33 | } 34 | 35 | [Fact] 36 | public void Float_Required_Fails_For_NullValue() 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => m.NullValue, _ => _ 41 | .Required()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBeFalse(); 46 | } 47 | 48 | [Fact] 49 | public void Float_Required_Succeeds_For_NullableNaN() 50 | { 51 | IValitResult result = ValitRules 52 | .Create() 53 | .Ensure(m => m.NullableNaN, _ => _ 54 | .Required()) 55 | .For(_model) 56 | .Validate(); 57 | 58 | result.Succeeded.ShouldBeTrue(); 59 | } 60 | 61 | #region ARRANGE 62 | public Float_Required_Tests() 63 | { 64 | _model = new Model(); 65 | } 66 | 67 | private readonly Model _model; 68 | 69 | class Model 70 | { 71 | public float? NullableValue => 10; 72 | public float? NullValue => null; 73 | public float? NullableNaN => Single.NaN; 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Guid_/Guid_IsNotEmpty_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Guid_ 6 | { 7 | public class Guid_IsNotEmpty_Tests 8 | { 9 | [Fact] 10 | public void Guid_IsNotEmpty_For_Not_Nullable_Values_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .IsNotEmpty(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Guid_IsNotEmpty_For_Nullable_Value_And_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => { 24 | ((IValitRule)null) 25 | .IsNotEmpty(); 26 | }); 27 | 28 | exception.ShouldBeOfType(typeof(ValitException)); 29 | } 30 | 31 | [Fact] 32 | public void Guid_IsNotEmpty_Succeeds_For_Value() 33 | { 34 | var result = ValitRules 35 | .Create() 36 | .Ensure(m => m.Value, _ => _ 37 | .IsNotEmpty()) 38 | .For(_model) 39 | .Validate(); 40 | 41 | result.Succeeded.ShouldBe(true); 42 | } 43 | 44 | [Fact] 45 | public void Guid_IsNotEmpty_Fails_For_Empty_Value() 46 | { 47 | var result = ValitRules 48 | .Create() 49 | .Ensure(m => m.Empty, _ => _ 50 | .IsNotEmpty()) 51 | .For(_model) 52 | .Validate(); 53 | 54 | result.Succeeded.ShouldBe(false); 55 | } 56 | 57 | [Fact] 58 | public void Guid_IsNotEmpty_Succeeds_For_Nullable_Value() 59 | { 60 | var result = ValitRules 61 | .Create() 62 | .Ensure(m => m.Value, _ => _ 63 | .IsNotEmpty()) 64 | .For(_model) 65 | .Validate(); 66 | 67 | result.Succeeded.ShouldBe(true); 68 | } 69 | 70 | [Fact] 71 | public void Guid_IsNotEmpty_Fails_For_Nullable_Empty_Value() 72 | { 73 | var result = ValitRules 74 | .Create() 75 | .Ensure(m => m.NullableEmpty, _ => _ 76 | .IsNotEmpty()) 77 | .For(_model) 78 | .Validate(); 79 | 80 | result.Succeeded.ShouldBe(false); 81 | } 82 | 83 | [Fact] 84 | public void Guid_IsNotEmpty_Fails_For_Nullable_Null() 85 | { 86 | var result = ValitRules 87 | .Create() 88 | .Ensure(m => m.NullValue, _ => _ 89 | .IsNotEmpty()) 90 | .For(_model) 91 | .Validate(); 92 | 93 | result.Succeeded.ShouldBe(false); 94 | } 95 | 96 | #region ARRANGE 97 | public Guid_IsNotEmpty_Tests() 98 | { 99 | _model = new Model(); 100 | } 101 | 102 | private readonly Model _model; 103 | 104 | class Model 105 | { 106 | public Guid Value => System.Guid.Parse("6f72f4ab-c2fc-4fca-b70e-b5ac7eccd054"); 107 | public Guid Empty => Guid.Empty; 108 | public Guid? NullableValue => System.Guid.Parse("6f72f4ab-c2fc-4fca-b70e-b5ac7eccd054"); 109 | public Guid? NullableEmpty => Guid.Empty; 110 | public Guid? NullValue => null; 111 | } 112 | #endregion 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Guid_/Guid_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Guid_ 6 | { 7 | public class Guid_Required_Tests 8 | { 9 | [Fact] 10 | public void Guid_Required_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Guid_Required_Succeeds_For_Nullable_Value() 22 | { 23 | var result = ValitRules 24 | .Create() 25 | .Ensure(m => m.NullableValue, _ => _ 26 | .Required()) 27 | .For(_model) 28 | .Validate(); 29 | 30 | result.Succeeded.ShouldBe(true); 31 | } 32 | 33 | [Fact] 34 | public void Guid_Required_Fails_For_Nullable_Null() 35 | { 36 | var result = ValitRules 37 | .Create() 38 | .Ensure(m => m.NullValue, _ => _ 39 | .Required()) 40 | .For(_model) 41 | .Validate(); 42 | 43 | result.Succeeded.ShouldBe(false); 44 | } 45 | 46 | #region ARRANGE 47 | public Guid_Required_Tests() 48 | { 49 | _model = new Model(); 50 | } 51 | 52 | private readonly Model _model; 53 | 54 | class Model 55 | { 56 | public Guid? NullableValue => System.Guid.Parse("6f72f4ab-c2fc-4fca-b70e-b5ac7eccd054"); 57 | public Guid? NullValue => null; 58 | } 59 | #endregion 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Valit.Tests/HelperExtensions/DateTimeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit.Tests.HelperExtensions 4 | { 5 | public static class DateTimeExtensions 6 | { 7 | public static DateTime? AsNullableDateTime(this string stringValue) 8 | => string.IsNullOrWhiteSpace(stringValue)? (DateTime?)null : Convert.ToDateTime(stringValue); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/Valit.Tests/HelperExtensions/DateTimeOffsetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit.Tests.HelperExtensions 4 | { 5 | public static class DateTimeOffsetExtensions 6 | { 7 | public static DateTimeOffset AsDateTimeOffset(this string stringValue) 8 | => Convert.ToDateTime(stringValue); 9 | 10 | public static DateTimeOffset? AsNullableDateTimeOffset(this string stringValue) 11 | => string.IsNullOrWhiteSpace(stringValue)? (DateTimeOffset?)null : Convert.ToDateTime(stringValue); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/Valit.Tests/HelperExtensions/DecimalExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Valit.Tests.HelperExtensions 4 | { 5 | public static class DecimalExtensions 6 | { 7 | public static decimal? AsNullableDecimal(this string stringValue) 8 | => Convert.ToDecimal(stringValue) > 0? Convert.ToDecimal(stringValue) : (decimal?) null; 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int16/Int16_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int16 5 | { 6 | public class Int16_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void Int16_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Int16_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void Int16_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void Int16_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Int16_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public Int16_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public short Value => 10; 87 | public short ZeroValue => 0; 88 | public short? NullableValue => 10; 89 | public short? NullableZeroValue => 0; 90 | public short? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int16/Int16_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int16 5 | { 6 | public class Int16_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void Int16_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void Int16_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public Int16_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public short Value => 10; 47 | public short ZeroValue => 0; 48 | public short? NullableValue => 10; 49 | public short? NullableZeroValue => 0; 50 | public short? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int32/Int32_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int32 5 | { 6 | public class Int32_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void Int32_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Int32_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void Int32_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void Int32_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Int32_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public Int32_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public int Value => 10; 87 | public int ZeroValue => 0; 88 | public int? NullableValue => 10; 89 | public int? NullableZeroValue => 0; 90 | public int? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int32/Int32_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int32 5 | { 6 | public class Int32_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void Int32_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void Int32_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public Int32_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public int Value => 10; 47 | public int ZeroValue => 0; 48 | public int? NullableValue => 10; 49 | public int? NullableZeroValue => 0; 50 | public int? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int64/Int64_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int64 5 | { 6 | public class Int64_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void Int64_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void Int64_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void Int64_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void Int64_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void Int64_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public Int64_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public long Value => 10; 87 | public long ZeroValue => 0; 88 | public long? NullableValue => 10; 89 | public long? NullableZeroValue => 0; 90 | public long? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Int64/Int64_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Int64 5 | { 6 | public class Int64_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void Int64_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void Int64_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public Int64_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public long Value => 10; 47 | public long ZeroValue => 0; 48 | public long? NullableValue => 10; 49 | public long? NullableZeroValue => 0; 50 | public long? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/MessageProvider/CustomMessageProvider_Tests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Xunit; 3 | using Shouldly; 4 | 5 | namespace Valit.Tests.MessageProvider 6 | { 7 | public class CustomMessageProvider_Tests 8 | { 9 | [Fact] 10 | public void CustomMessageProvider_Adds_Proper_Messages() 11 | { 12 | var result = ValitRules 13 | .Create() 14 | .WithMessageProvider(new CustomMessageProvider()) 15 | .Ensure(m => m.Value, _ => _ 16 | .MaxLength(10) 17 | .WithMessageKey(1) 18 | .MinLength(5) 19 | .WithMessageKey(2) 20 | .Matches(@"^\d") 21 | .WithMessageKey(3)) 22 | .For(_model) 23 | .Validate(); 24 | 25 | result.Succeeded.ShouldBe(false); 26 | result.ErrorCodes.ShouldBeEmpty(); 27 | result.ErrorMessages.ShouldNotBeEmpty(); 28 | result.ErrorMessages.ShouldContain("One"); 29 | result.ErrorMessages.ShouldNotContain("Two"); 30 | result.ErrorMessages.ShouldContain("Three"); 31 | } 32 | 33 | #region ARRANGE 34 | public CustomMessageProvider_Tests() 35 | { 36 | _model = new Model(); 37 | } 38 | 39 | private readonly Model _model; 40 | 41 | class Model 42 | { 43 | public string Value => "This text has 28 characters!"; 44 | } 45 | #endregion 46 | } 47 | 48 | class CustomMessageProvider : IValitMessageProvider 49 | { 50 | private IDictionary _messages = 51 | new Dictionary 52 | { 53 | [1] = "One", 54 | [2] = "Two", 55 | [3] = "Three", 56 | }; 57 | 58 | public string GetByKey(int key) 59 | { 60 | if (_messages.TryGetValue(key, out var message)) 61 | return message; 62 | return string.Empty; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Valit.Tests/MessageProvider/EmptyMessageProvider_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.MessageProvider 5 | { 6 | public class EmptyMessageProvider_Tests 7 | { 8 | const string Key = "KEY"; 9 | 10 | [Fact] 11 | public void EmptyMessageProvider_Does_Not_Add_Any_Message() 12 | { 13 | var result = ValitRules.Create() 14 | .Ensure(m => m.Value, _ => _ 15 | .MaxLength(4) 16 | .WithMessageKey(Key)) 17 | .For(_model) 18 | .Validate(); 19 | 20 | result.Succeeded.ShouldBe(false); 21 | result.ErrorMessages.ShouldBeEmpty(); 22 | } 23 | 24 | Model _model => new Model(); 25 | 26 | class Model 27 | { 28 | public string Value => "This text has 28 characters!"; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Property/Property_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Property 5 | { 6 | public class Property_Required_Tests 7 | { 8 | [Fact] 9 | public void Property_Required_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .Required(); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Fact] 20 | public void Property_Required_Succeeds_For_Not_Null_Property() 21 | { 22 | var result = ValitRules.Create() 23 | .Ensure(m => m.RefProperty, _ => _ 24 | .Required()) 25 | .For(_model) 26 | .Validate(); 27 | 28 | result.Succeeded.ShouldBe(true); 29 | } 30 | 31 | [Fact] 32 | public void Property_Required_SFails_For_Null_Property() 33 | { 34 | var result = ValitRules.Create() 35 | .Ensure(m => m.NullRefProperty, _ => _ 36 | .Required()) 37 | .For(_model) 38 | .Validate(); 39 | 40 | result.Succeeded.ShouldBe(false); 41 | } 42 | 43 | private Model _model => new Model(); 44 | 45 | class Model 46 | { 47 | public object RefProperty => new object(); 48 | public object NullRefProperty => null; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Property/Property_When_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Property 5 | { 6 | public class Property_When_Tests 7 | { 8 | [Fact] 9 | public void Property_When_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .When(_ => true); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Fact] 20 | public void Property_Required_When_Succeeds_When_Predicate_Is_Satisfied_And_Not_Null_Property_Is_Passed() 21 | { 22 | var result = ValitRules.Create() 23 | .Ensure(m => m.RefProperty, _ => _ 24 | .Required() 25 | .When(m => true)) 26 | .For(_model) 27 | .Validate(); 28 | 29 | result.Succeeded.ShouldBe(true); 30 | } 31 | 32 | [Fact] 33 | public void Property_Required_When_Succeeds_When_Predicate_Is_Not_Satisfied_And_Not_Null_Property_Is_Passed() 34 | { 35 | var result = ValitRules.Create() 36 | .Ensure(m => m.RefProperty, _ => _ 37 | .Required() 38 | .When(m => false)) 39 | .For(_model) 40 | .Validate(); 41 | 42 | result.Succeeded.ShouldBe(true); 43 | } 44 | 45 | [Fact] 46 | public void Property_Required_When_Fails_When_Predicate_Is_Satisfied_And_Null_Property_Is_Passed() 47 | { 48 | var result = ValitRules.Create() 49 | .Ensure(m => m.NullRefProperty, _ => _ 50 | .Required() 51 | .When(m => true)) 52 | .For(_model) 53 | .Validate(); 54 | 55 | result.Succeeded.ShouldBe(false); 56 | } 57 | 58 | [Fact] 59 | public void Property_Required_When_Succeeds_When_Predicate_Is_Not_Satisfied_And_Null_Property_Is_Passed() 60 | { 61 | var result = ValitRules.Create() 62 | .Ensure(m => m.NullRefProperty, _ => _ 63 | .Required() 64 | .When(m => false)) 65 | .For(_model) 66 | .Validate(); 67 | 68 | result.Succeeded.ShouldBe(true); 69 | } 70 | 71 | [Theory] 72 | [InlineData(false, false, true)] 73 | [InlineData(false, true, true)] 74 | [InlineData(true, false, true)] 75 | [InlineData(true, true, false)] 76 | public void Property_When_Returns_ProperResult(bool r1, bool r2, bool expected) 77 | { 78 | var result = ValitRules.Create() 79 | .Ensure(m => m.NullRefProperty, _ => _ 80 | .Required() 81 | .When(m => r1) 82 | .When(m => r2)) 83 | .For(_model) 84 | .Validate(); 85 | 86 | result.Succeeded.ShouldBe(expected); 87 | } 88 | 89 | private Model _model => new Model(); 90 | 91 | class Model 92 | { 93 | public object RefProperty => new object(); 94 | public object NullRefProperty => null; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Property/Property_WithDefaultMessage_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.Property 5 | { 6 | public class Property_WithDefaultMessage_Tests 7 | { 8 | [Fact] 9 | public void DefaultMessage_Is_Added_If_No_ErrorMessage_Is_Given() 10 | { 11 | var result = ValitRules.Create() 12 | .Ensure(m => m.Value, _ => _ 13 | .IsNegative()) 14 | .Ensure(m => m.NullValue, _ => _ 15 | .Required()) 16 | .For(_model) 17 | .Validate(); 18 | 19 | result.ErrorMessages.Length.ShouldBe(2); 20 | } 21 | 22 | [Fact] 23 | public void DefaultMessage_Is_Overriten_If_ErrorMessage_Is_Given() 24 | { 25 | var result = ValitRules.Create() 26 | .Ensure(m => m.Value, _ => _ 27 | .IsNegative() 28 | .WithMessage("1")) 29 | .Ensure(m => m.NullValue, _ => _ 30 | .Required() 31 | .WithMessage("2")) 32 | .For(_model) 33 | .Validate(); 34 | 35 | result.ErrorMessages.Length.ShouldBe(2); 36 | result.ErrorMessages.ShouldContain("1"); 37 | result.ErrorMessages.ShouldContain("2"); 38 | } 39 | 40 | public Property_WithDefaultMessage_Tests() 41 | { 42 | _model = new Model(); 43 | } 44 | 45 | private readonly Model _model; 46 | 47 | class Model 48 | { 49 | public int Value => 12; 50 | public object NullValue => null; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /tests/Valit.Tests/SByte/SByte_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.SByte 5 | { 6 | public class SByte_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void SByte_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void SByte_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void SByte_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void SByte_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void SByte_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public SByte_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public sbyte Value => 10; 87 | public sbyte ZeroValue => 0; 88 | public sbyte? NullableValue => 10; 89 | public sbyte? NullableZeroValue => 0; 90 | public sbyte? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/SByte/SByte_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.SByte 5 | { 6 | public class SByte_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void SByte_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void SByte_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public SByte_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public sbyte Value => 10; 47 | public sbyte ZeroValue => 0; 48 | public sbyte? NullableValue => 10; 49 | public sbyte? NullableZeroValue => 0; 50 | public sbyte? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Strategies/Complete.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using Xunit; 7 | 8 | namespace Valit.Tests.Strategies 9 | { 10 | public class Complete 11 | { 12 | [Fact] 13 | public void Complete_Strategy_Checks_All_Ensure() 14 | { 15 | var result = ValitRules.Create() 16 | .WithStrategy(_ => _.Complete) 17 | .Ensure(m => m.Age, _ => _ 18 | .IsPositive() 19 | .WithMessage(M1)) 20 | .Ensure(m => m.FirstName, _ => _ 21 | .Required() 22 | .WithMessage(M2) 23 | .MinLength(3) 24 | .WithMessage(M3)) 25 | .Ensure(m => m.LastName, _ => _ 26 | .Required() 27 | .WithMessage(M4) 28 | .MinLength(5) 29 | .WithMessage(M5)) 30 | .Ensure(m => m.Email, _ => _ 31 | .Required() 32 | .WithMessage(M6) 33 | .Email() 34 | .WithMessage(M7)) 35 | .For(_model) 36 | .Validate(); 37 | 38 | result.Succeeded.ShouldBe(false); 39 | result.ErrorMessages.Count().ShouldBe(5); 40 | result.ErrorMessages.ShouldContain(M1); 41 | result.ErrorMessages.ShouldContain(M3); 42 | result.ErrorMessages.ShouldContain(M4); 43 | result.ErrorMessages.ShouldContain(M5); 44 | result.ErrorMessages.ShouldContain(M7); 45 | } 46 | 47 | #region ARRANGE 48 | 49 | const string M1 = "Our framework doesn't support future born babies"; 50 | const string M2 = "Name is required"; 51 | const string M3 = "Name shorter than 3 are not supported"; 52 | const string M4 = "Lastname is required"; 53 | const string M5 = "Lastname shorter than 3 are not supported"; 54 | const string M6 = "Email is required"; 55 | const string M7 = "Invalid email"; 56 | 57 | Model _model => new Model(); 58 | 59 | class Model 60 | { 61 | public int Age => -1; 62 | public string FirstName => ""; 63 | public string LastName => null; 64 | public string Email => "a@a"; 65 | } 66 | #endregion 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Strategies/FailFast.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using Xunit; 7 | 8 | namespace Valit.Tests.Strategies 9 | { 10 | public class FailFast 11 | { 12 | [Fact] 13 | public void FailFast_Strategy_Checks_Until_First_Error() 14 | { 15 | var result = ValitRules.Create() 16 | .WithStrategy(_ => _.FailFast) 17 | .Ensure(m => m.Age, _ => _ 18 | .IsPositive() 19 | .WithMessage(M1)) 20 | .Ensure(m => m.FirstName, _ => _ 21 | .Required() 22 | .WithMessage(M2) 23 | .MinLength(3) 24 | .WithMessage(M3)) 25 | .Ensure(m => m.LastName, _ => _ 26 | .Required() 27 | .WithMessage(M4) 28 | .MinLength(5) 29 | .WithMessage(M5)) 30 | .Ensure(m => m.Email, _ => _ 31 | .Required() 32 | .WithMessage(M6) 33 | .Email() 34 | .WithMessage(M7)) 35 | .For(_model) 36 | .Validate(); 37 | 38 | result.Succeeded.ShouldBe(false); 39 | result.ErrorMessages.Count().ShouldBe(1); 40 | result.ErrorMessages.ShouldContain(M1); 41 | } 42 | 43 | [Fact] 44 | public void FailFast_Strategy_Checks_Until_First_Error_While_Error_Is_Not_First() 45 | { 46 | var result = ValitRules.Create() 47 | .WithStrategy(_ => _.FailFast) 48 | .Ensure(m => m.Age, _ => _ 49 | .IsLessThan(1000) 50 | .WithMessage(M8)) 51 | .Ensure(m => m.FirstName, _ => _ 52 | .Required() 53 | .WithMessage(M2) 54 | .MinLength(3) 55 | .WithMessage(M3)) 56 | .Ensure(m => m.LastName, _ => _ 57 | .Required() 58 | .WithMessage(M4) 59 | .MinLength(5) 60 | .WithMessage(M5)) 61 | .Ensure(m => m.Email, _ => _ 62 | .Required() 63 | .WithMessage(M6) 64 | .Email() 65 | .WithMessage(M7)) 66 | .For(_model) 67 | .Validate(); 68 | 69 | result.Succeeded.ShouldBe(false); 70 | result.ErrorMessages.Count().ShouldBe(1); 71 | result.ErrorMessages.ShouldContain(M3); 72 | } 73 | 74 | #region ARRANGE 75 | 76 | const string M1 = "Our framework doesn't support future born babies"; 77 | const string M2 = "Name is required"; 78 | const string M3 = "Name shorter than 3 are not supported"; 79 | const string M4 = "Lastname is required"; 80 | const string M5 = "Lastname shorter than 3 are not supported"; 81 | const string M6 = "Email is required"; 82 | const string M7 = "Invalid email"; 83 | const string M8 = "Old people are not supported"; 84 | 85 | Model _model => new Model(); 86 | 87 | class Model 88 | { 89 | public int Age => -1; 90 | public string FirstName => ""; 91 | public string LastName => null; 92 | public string Email => "a@a"; 93 | } 94 | #endregion 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_Email_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_Email_Tests 7 | { 8 | [Fact] 9 | public void String_Email_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .Email(); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Theory] 20 | [InlineData("email@domain.com")] 21 | [InlineData("firstname.lastname@domain.com")] 22 | [InlineData("email@subdomain.domain.com")] 23 | [InlineData("firstname+lastname@domain.com")] 24 | [InlineData("email@123.123.123.123")] 25 | [InlineData("1234567890@domain.com")] 26 | [InlineData("email@domain-one.com")] 27 | [InlineData("_______@domain.com")] 28 | [InlineData("email@domain.name")] 29 | [InlineData("email@domain.co.jp")] 30 | [InlineData("firstname-lastname@domain.com")] 31 | public void String_Email_Succeeds_For_Valid_Email(string value) 32 | { 33 | IValitResult result = ValitRules 34 | .Create() 35 | .Ensure(m => value, _ => _ 36 | .Email()) 37 | .For(_model) 38 | .Validate(); 39 | 40 | result.Succeeded.ShouldBe(true, value); 41 | } 42 | 43 | [Theory] 44 | [InlineData("plainaddress")] 45 | [InlineData("#@%^%#$@#$@#.com")] 46 | [InlineData("@domain.com")] 47 | [InlineData("Joe Smith ")] 48 | [InlineData("email.domain.com")] 49 | [InlineData("email@domain@domain.com")] 50 | [InlineData(".email@domain.com")] 51 | [InlineData("email.@domain.com")] 52 | [InlineData("email..email@domain.com")] 53 | [InlineData("あいうえお@domain.com")] 54 | [InlineData("email@domain.com (Joe Smith)")] 55 | [InlineData("email@domain")] 56 | [InlineData("email@-domain.com")] 57 | [InlineData("email@domain..com")] 58 | [InlineData("")] 59 | [InlineData(null)] 60 | public void String_Email_Fails_For_Invalid_Email(string value) 61 | { 62 | IValitResult result = ValitRules 63 | .Create() 64 | .Ensure(m => value, _ => _ 65 | .Email()) 66 | .For(_model) 67 | .Validate(); 68 | 69 | result.Succeeded.ShouldBe(false, value); 70 | } 71 | 72 | #region ARRANGE 73 | public String_Email_Tests() 74 | { 75 | _model = new Model(); 76 | } 77 | 78 | private readonly Model _model; 79 | 80 | class Model 81 | { 82 | } 83 | #endregion 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_IsEqualTo_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_IsEqualTo_Tests 7 | { 8 | [Fact] 9 | public void String_IsEqualTo_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .IsEqualTo("text"); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Theory] 20 | [InlineData("text", true)] 21 | [InlineData("other", false)] 22 | [InlineData("", false)] 23 | [InlineData(null, false)] 24 | public void String_IsEqualTo_Returns_Proper_Result_For_Left_Value(string value, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => m.Value, _ => _ 29 | .IsEqualTo(value)) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | [Theory] 37 | [InlineData("text", false)] 38 | [InlineData("other", false)] 39 | [InlineData("", true)] 40 | [InlineData(null, false)] 41 | public void String_IsEqualTo_Returns_Proper_Result_For_Left_Empty_Value(string value, bool expected) 42 | { 43 | IValitResult result = ValitRules 44 | .Create() 45 | .Ensure(m => m.EmptyValue, _ => _ 46 | .IsEqualTo(value)) 47 | .For(_model) 48 | .Validate(); 49 | 50 | result.Succeeded.ShouldBe(expected); 51 | } 52 | 53 | [Theory] 54 | [InlineData("text", false)] 55 | [InlineData("other", false)] 56 | [InlineData("", false)] 57 | [InlineData(null, false)] 58 | public void String_IsEqualTo_Returns_Proper_Result_For_Left_Null_Value(string value, bool expected) 59 | { 60 | IValitResult result = ValitRules 61 | .Create() 62 | .Ensure(m => m.NullValue, _ => _ 63 | .IsEqualTo(value)) 64 | .For(_model) 65 | .Validate(); 66 | 67 | result.Succeeded.ShouldBe(expected); 68 | } 69 | 70 | #region ARRANGE 71 | public String_IsEqualTo_Tests() 72 | { 73 | _model = new Model(); 74 | } 75 | 76 | private readonly Model _model; 77 | 78 | class Model 79 | { 80 | public string EmptyValue => string.Empty; 81 | public string Value => "text"; 82 | public string NullValue => null; 83 | } 84 | #endregion 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_Matches_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_Matches_Tests 7 | { 8 | [Fact] 9 | public void String_Matches_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .Matches(@"\d+"); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Theory] 20 | [InlineData(@"\w", true)] 21 | [InlineData(@"\d", false)] 22 | [InlineData("", false)] 23 | [InlineData(null, false)] 24 | public void String_Matches_Returns_Proper_Result_For_Left_Value(string value, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => m.Value, _ => _ 29 | .Matches(value)) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | [Theory] 37 | [InlineData(@"\w", false)] 38 | [InlineData(@"\d", false)] 39 | [InlineData("", false)] 40 | [InlineData(null, false)] 41 | public void String_Matches_Returns_Proper_Result_For_Left_Empty_Value(string value, bool expected) 42 | { 43 | IValitResult result = ValitRules 44 | .Create() 45 | .Ensure(m => m.EmptyValue, _ => _ 46 | .Matches(value)) 47 | .For(_model) 48 | .Validate(); 49 | 50 | result.Succeeded.ShouldBe(expected); 51 | } 52 | 53 | [Theory] 54 | [InlineData(@"\w", false)] 55 | [InlineData(@"\d", false)] 56 | [InlineData("", false)] 57 | [InlineData(null, false)] 58 | public void String_Matches_Returns_Proper_Result_For_Left_Null_Value(string value, bool expected) 59 | { 60 | IValitResult result = ValitRules 61 | .Create() 62 | .Ensure(m => m.NullValue, _ => _ 63 | .Matches(value)) 64 | .For(_model) 65 | .Validate(); 66 | 67 | result.Succeeded.ShouldBe(expected); 68 | } 69 | 70 | #region ARRANGE 71 | public String_Matches_Tests() 72 | { 73 | _model = new Model(); 74 | } 75 | 76 | private readonly Model _model; 77 | 78 | class Model 79 | { 80 | public string EmptyValue => string.Empty; 81 | public string Value => "text"; 82 | public string NullValue => null; 83 | } 84 | #endregion 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_MaxLength_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_MaxLength_Tests 7 | { 8 | [Fact] 9 | public void String_MaxLength_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .MaxLength(0); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Theory] 20 | [InlineData(0, false)] 21 | [InlineData(4, true)] 22 | [InlineData(8, true)] 23 | public void String_MaxLength_Returns_Proper_Result_For_Left_Value(int value, bool expected) 24 | { 25 | IValitResult result = ValitRules 26 | .Create() 27 | .Ensure(m => m.Value, _ => _ 28 | .MaxLength(value)) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBe(expected); 33 | } 34 | 35 | [Theory] 36 | [InlineData(0, true)] 37 | [InlineData(4, true)] 38 | [InlineData(8, true)] 39 | public void String_MaxLength_Returns_Proper_Result_For_Left_Empty_Value(int value, bool expected) 40 | { 41 | IValitResult result = ValitRules 42 | .Create() 43 | .Ensure(m => m.EmptyValue, _ => _ 44 | .MaxLength(value)) 45 | .For(_model) 46 | .Validate(); 47 | 48 | result.Succeeded.ShouldBe(expected); 49 | } 50 | 51 | [Theory] 52 | [InlineData(0, false)] 53 | [InlineData(4, false)] 54 | [InlineData(8, false)] 55 | public void String_MaxLength_Returns_Proper_Result_For_Left_Null_Value(int value, bool expected) 56 | { 57 | IValitResult result = ValitRules 58 | .Create() 59 | .Ensure(m => m.NullValue, _ => _ 60 | .MaxLength(value)) 61 | .For(_model) 62 | .Validate(); 63 | 64 | result.Succeeded.ShouldBe(expected); 65 | } 66 | 67 | #region ARRANGE 68 | public String_MaxLength_Tests() 69 | { 70 | _model = new Model(); 71 | } 72 | 73 | private readonly Model _model; 74 | 75 | class Model 76 | { 77 | public string EmptyValue => string.Empty; 78 | public string Value => "text"; 79 | public string NullValue => null; 80 | } 81 | #endregion 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_MinLength_Tests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Shouldly; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_MinLength_Tests 7 | { 8 | [Fact] 9 | public void String_MinLength_For_Nullable_Values_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => { 12 | ((IValitRule)null) 13 | .MinLength(0); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Theory] 20 | [InlineData(0, true)] 21 | [InlineData(4, true)] 22 | [InlineData(8, false)] 23 | public void String_MinLength_Returns_Proper_Result_For_Left_Value(int value, bool expected) 24 | { 25 | IValitResult result = ValitRules 26 | .Create() 27 | .Ensure(m => m.Value, _ => _ 28 | .MinLength(value)) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBe(expected); 33 | } 34 | 35 | [Theory] 36 | [InlineData(0, true)] 37 | [InlineData(4, false)] 38 | [InlineData(8, false)] 39 | public void String_MinLength_Returns_Proper_Result_For_Left_Empty_Value(int value, bool expected) 40 | { 41 | IValitResult result = ValitRules 42 | .Create() 43 | .Ensure(m => m.EmptyValue, _ => _ 44 | .MinLength(value)) 45 | .For(_model) 46 | .Validate(); 47 | 48 | result.Succeeded.ShouldBe(expected); 49 | } 50 | 51 | [Theory] 52 | [InlineData(0, false)] 53 | [InlineData(4, false)] 54 | [InlineData(8, false)] 55 | public void String_MinLength_Returns_Proper_Result_For_Left_Null_Value(int value, bool expected) 56 | { 57 | IValitResult result = ValitRules 58 | .Create() 59 | .Ensure(m => m.NullValue, _ => _ 60 | .MinLength(value)) 61 | .For(_model) 62 | .Validate(); 63 | 64 | result.Succeeded.ShouldBe(expected); 65 | } 66 | 67 | #region ARRANGE 68 | public String_MinLength_Tests() 69 | { 70 | _model = new Model(); 71 | } 72 | 73 | private readonly Model _model; 74 | 75 | class Model 76 | { 77 | public string EmptyValue => string.Empty; 78 | public string Value => "text"; 79 | public string NullValue => null; 80 | } 81 | #endregion 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Valit.Tests/String/String_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.String 5 | { 6 | public class String_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void String_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => 13 | { 14 | ((IValitRule)null) 15 | .Required(); 16 | }); 17 | 18 | exception.ShouldBeOfType(typeof(ValitException)); 19 | } 20 | 21 | 22 | [Fact] 23 | public void String_Required_Fails_For_Null_Value() 24 | { 25 | IValitResult result = ValitRules 26 | .Create() 27 | .Ensure(m => m.NullValue, _ => _ 28 | .Required()) 29 | .For(_model) 30 | .Validate(); 31 | 32 | result.Succeeded.ShouldBeFalse(); 33 | } 34 | 35 | [Fact] 36 | public void String_Required_Succeeds_For_Empty_Value() 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => m.EmptyValue, _ => _ 41 | .Required()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBeTrue(); 46 | } 47 | 48 | [Fact] 49 | public void String_Required_Succeeds_For_Not_Empty_Value() 50 | { 51 | IValitResult result = ValitRules 52 | .Create() 53 | .Ensure(m => m.Value, _ => _ 54 | .Required()) 55 | .For(_model) 56 | .Validate(); 57 | 58 | result.Succeeded.ShouldBeTrue(); 59 | } 60 | 61 | #region ARRANGE 62 | public String_Required_Tests() 63 | { 64 | _model = new Model(); 65 | } 66 | 67 | private readonly Model _model; 68 | 69 | class Model 70 | { 71 | public string EmptyValue => string.Empty; 72 | public string Value => "text"; 73 | public string NullValue => null; 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Valit.Tests/TimeSpan_/TimeSpan_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.TimeSpan_ 6 | { 7 | public class TimeSpan_IsNonZero_Tests 8 | { 9 | [Fact] 10 | public void TimeSpan_IsNonZero_For_Not_Nullable_Values_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void TimeSpan_IsNonZero_For_Nullable_Value_And_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => { 24 | ((IValitRule)null) 25 | .IsNonZero(); 26 | }); 27 | 28 | exception.ShouldBeOfType(typeof(ValitException)); 29 | } 30 | 31 | [Fact] 32 | public void TimeSpan_IsNonZero_Succeeds_For_Value() 33 | { 34 | var result = ValitRules 35 | .Create() 36 | .Ensure(m => m.Value, _ => _ 37 | .IsNonZero()) 38 | .For(_model) 39 | .Validate(); 40 | 41 | result.Succeeded.ShouldBe(true); 42 | } 43 | 44 | [Fact] 45 | public void TimeSpan_IsNonZero_Fails_For_Zero_Value() 46 | { 47 | var result = ValitRules 48 | .Create() 49 | .Ensure(m => m.Zero, _ => _ 50 | .IsNonZero()) 51 | .For(_model) 52 | .Validate(); 53 | 54 | result.Succeeded.ShouldBe(false); 55 | } 56 | 57 | [Fact] 58 | public void TimeSpan_IsNonZero_Succeeds_For_Nullable_Value() 59 | { 60 | var result = ValitRules 61 | .Create() 62 | .Ensure(m => m.Value, _ => _ 63 | .IsNonZero()) 64 | .For(_model) 65 | .Validate(); 66 | 67 | result.Succeeded.ShouldBe(true); 68 | } 69 | 70 | [Fact] 71 | public void TimeSpan_IsNonZero_Fails_For_Nullable_Zero_Value() 72 | { 73 | var result = ValitRules 74 | .Create() 75 | .Ensure(m => m.Zero, _ => _ 76 | .IsNonZero()) 77 | .For(_model) 78 | .Validate(); 79 | 80 | result.Succeeded.ShouldBe(false); 81 | } 82 | 83 | [Fact] 84 | public void TimeSpan_IsNonZero_Fails_For_Nullable_Null() 85 | { 86 | var result = ValitRules 87 | .Create() 88 | .Ensure(m => m.NullValue, _ => _ 89 | .IsNonZero()) 90 | .For(_model) 91 | .Validate(); 92 | 93 | result.Succeeded.ShouldBe(false); 94 | } 95 | 96 | #region ARRANGE 97 | public TimeSpan_IsNonZero_Tests() 98 | { 99 | _model = new Model(); 100 | } 101 | 102 | private readonly Model _model; 103 | 104 | class Model 105 | { 106 | public TimeSpan Value => new TimeSpan(1, 0, 0); 107 | public TimeSpan Zero => TimeSpan.Zero; 108 | public TimeSpan? NullableValue => new TimeSpan(1, 0, 0); 109 | public TimeSpan? NullableZero => TimeSpan.Zero; 110 | public TimeSpan? NullValue => null; 111 | } 112 | #endregion 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tests/Valit.Tests/TimeSpan_/TimeSpan_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.TimeSpan_ 6 | { 7 | public class TimeSpan_Required_Tests 8 | { 9 | [Fact] 10 | public void TimeSpan_Required_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void TimeSpan_Required_Succeeds_For_Nullable_Value() 22 | { 23 | var result = ValitRules 24 | .Create() 25 | .Ensure(m => m.NullableValue, _ => _ 26 | .Required()) 27 | .For(_model) 28 | .Validate(); 29 | 30 | result.Succeeded.ShouldBe(true); 31 | } 32 | 33 | [Fact] 34 | public void TimeSpan_Required_Succeeds_For_Nullable_Zero_Value() 35 | { 36 | var result = ValitRules 37 | .Create() 38 | .Ensure(m => m.NullableZero, _ => _ 39 | .Required()) 40 | .For(_model) 41 | .Validate(); 42 | 43 | result.Succeeded.ShouldBe(true); 44 | } 45 | 46 | [Fact] 47 | public void TimeSpan_Required_Fails_For_Nullable_Null() 48 | { 49 | var result = ValitRules 50 | .Create() 51 | .Ensure(m => m.NullValue, _ => _ 52 | .Required()) 53 | .For(_model) 54 | .Validate(); 55 | 56 | result.Succeeded.ShouldBe(false); 57 | } 58 | 59 | #region ARRANGE 60 | public TimeSpan_Required_Tests() 61 | { 62 | _model = new Model(); 63 | } 64 | 65 | private readonly Model _model; 66 | 67 | class Model 68 | { 69 | public TimeSpan Value => new TimeSpan(1, 0, 0); 70 | public TimeSpan Zero => TimeSpan.Zero; 71 | public TimeSpan? NullableValue => new TimeSpan(1, 0, 0); 72 | public TimeSpan? NullableZero => TimeSpan.Zero; 73 | public TimeSpan? NullValue => null; 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt16/UInt16_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt16 5 | { 6 | public class UInt16_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void UInt16_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void UInt16_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void UInt16_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void UInt16_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void UInt16_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public UInt16_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public ushort Value => 10; 87 | public ushort ZeroValue => 0; 88 | public ushort? NullableValue => 10; 89 | public ushort? NullableZeroValue => 0; 90 | public ushort? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt16/UInt16_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt16 5 | { 6 | public class UInt16_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void UInt16_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void UInt16_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public UInt16_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public ushort Value => 10; 47 | public ushort ZeroValue => 0; 48 | public ushort? NullableValue => 10; 49 | public ushort? NullableZeroValue => 0; 50 | public ushort? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt32/UInt32_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt32 5 | { 6 | public class UInt32_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void UInt32_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void UInt32_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void UInt32_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void UInt32_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void UInt32_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public UInt32_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public uint Value => 10; 87 | public uint ZeroValue => 0; 88 | public uint? NullableValue => 10; 89 | public uint? NullableZeroValue => 0; 90 | public uint? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt32/UInt32_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt32 5 | { 6 | public class UInt32_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void UInt32_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void UInt32_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public UInt32_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public uint Value => 10; 47 | public uint ZeroValue => 0; 48 | public uint? NullableValue => 10; 49 | public uint? NullableZeroValue => 0; 50 | public uint? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt64/UInt64_IsNonZero_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt64 5 | { 6 | public class UInt64_IsNonZero_Tests 7 | { 8 | [Fact] 9 | public void UInt64_IsNonZero_For_Not_Nullable_Value_Throws_When_Null_Rule_Is_Given() 10 | { 11 | var exception = Record.Exception(() => 12 | { 13 | ((IValitRule)null) 14 | .IsNonZero(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | [Fact] 21 | public void UInt64_IsNonZero_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 22 | { 23 | var exception = Record.Exception(() => 24 | { 25 | ((IValitRule)null) 26 | .IsNonZero(); 27 | }); 28 | 29 | exception.ShouldBeOfType(typeof(ValitException)); 30 | } 31 | 32 | 33 | [Theory] 34 | [InlineData(false, true)] 35 | [InlineData(true, false)] 36 | public void UInt64_IsNonZero_Returns_Proper_Results_For_Not_Nullable_Value(bool useZeroValue, bool expected) 37 | { 38 | IValitResult result = ValitRules 39 | .Create() 40 | .Ensure(m => useZeroValue ? m.ZeroValue : m.Value, _ => _ 41 | .IsNonZero()) 42 | .For(_model) 43 | .Validate(); 44 | 45 | result.Succeeded.ShouldBe(expected); 46 | } 47 | 48 | [Theory] 49 | [InlineData(false, true)] 50 | [InlineData(true, false)] 51 | public void UInt64_IsNonZero_Returns_Proper_Results_For_Nullable_Value(bool useZeroValue, bool expected) 52 | { 53 | IValitResult result = ValitRules 54 | .Create() 55 | .Ensure(m => useZeroValue ? m.NullableZeroValue : m.NullableValue, _ => _ 56 | .IsNonZero()) 57 | .For(_model) 58 | .Validate(); 59 | 60 | result.Succeeded.ShouldBe(expected); 61 | } 62 | 63 | [Fact] 64 | public void UInt64_IsNonZero_Fails_For_Null_Value() 65 | { 66 | IValitResult result = ValitRules 67 | .Create() 68 | .Ensure(m => m.NullValue, _ => _ 69 | .IsNonZero()) 70 | .For(_model) 71 | .Validate(); 72 | 73 | result.Succeeded.ShouldBeFalse(); 74 | } 75 | 76 | #region ARRANGE 77 | public UInt64_IsNonZero_Tests() 78 | { 79 | _model = new Model(); 80 | } 81 | 82 | private readonly Model _model; 83 | 84 | class Model 85 | { 86 | public ulong Value => 10; 87 | public ulong ZeroValue => 0; 88 | public ulong? NullableValue => 10; 89 | public ulong? NullableZeroValue => 0; 90 | public ulong? NullValue => null; 91 | } 92 | #endregion 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/Valit.Tests/UInt64/UInt64_Required_Tests.cs: -------------------------------------------------------------------------------- 1 | using Shouldly; 2 | using Xunit; 3 | 4 | namespace Valit.Tests.UInt64 5 | { 6 | public class UInt64_Required_Tests 7 | { 8 | 9 | [Fact] 10 | public void UInt64_Required_For_Nullable_Value_Throws_When_Null_Rule_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | ((IValitRule)null) 14 | .Required(); 15 | }); 16 | 17 | exception.ShouldBeOfType(typeof(ValitException)); 18 | } 19 | 20 | 21 | [Theory] 22 | [InlineData(false, true)] 23 | [InlineData(true, false)] 24 | public void UInt64_Required_Returns_Proper_Results_For_Nullable_Value(bool useNullValue, bool expected) 25 | { 26 | IValitResult result = ValitRules 27 | .Create() 28 | .Ensure(m => useNullValue? m.NullValue : m.NullableValue, _=>_ 29 | .Required()) 30 | .For(_model) 31 | .Validate(); 32 | 33 | result.Succeeded.ShouldBe(expected); 34 | } 35 | 36 | #region ARRANGE 37 | public UInt64_Required_Tests() 38 | { 39 | _model = new Model(); 40 | } 41 | 42 | private readonly Model _model; 43 | 44 | class Model 45 | { 46 | public ulong Value => 10; 47 | public ulong ZeroValue => 0; 48 | public ulong? NullableValue => 10; 49 | public ulong? NullableZeroValue => 0; 50 | public ulong? NullValue => null; 51 | } 52 | #endregion 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Valit.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Valitator/Valitator_MessageProvider_Tests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Valitator 6 | { 7 | public class Valitator_MessageProvider_Tests 8 | { 9 | [Fact] 10 | public void Created_Valitator_Properly_Handles_Complete_Strategy() 11 | { 12 | var valitator = new ModelRulesProvider().GetRules().CreateValitator(); 13 | var result = valitator.Validate(_model); 14 | 15 | result.Succeeded.ShouldBeFalse(); 16 | result.ErrorMessages.ShouldContain("One"); 17 | result.ErrorMessages.ShouldNotContain("Two"); 18 | result.ErrorMessages.ShouldContain("Three"); 19 | } 20 | 21 | [Fact] 22 | public void Created_Valitator_Properly_Handles_FailFast_Strategy() 23 | { 24 | var valitator = new ModelRulesProvider().GetRules().CreateValitator(); 25 | var result = valitator.Validate(_model, new FailFastValitStrategy()); 26 | 27 | result.Succeeded.ShouldBeFalse(); 28 | result.ErrorMessages.ShouldContain("One"); 29 | result.ErrorMessages.ShouldNotContain("Two"); 30 | result.ErrorMessages.ShouldNotContain("Three"); 31 | } 32 | 33 | 34 | #region ARRANGE 35 | 36 | class Model 37 | { 38 | public ushort NumericValue { get; set; } 39 | public string StringValue { get; set; } 40 | } 41 | 42 | class ModelRulesProvider 43 | { 44 | public IValitRules GetRules() 45 | => ValitRules 46 | .Create() 47 | .Ensure(m => m.NumericValue, _ => _ 48 | .IsGreaterThan(10) 49 | .WithMessage("One")) 50 | .Ensure(m => m.StringValue, _ => _ 51 | .Required() 52 | .WithMessage("Two") 53 | .Email() 54 | .WithMessage("Three")); 55 | } 56 | 57 | private readonly Model _model; 58 | 59 | public Valitator_MessageProvider_Tests() 60 | { 61 | _model = new Model 62 | { 63 | NumericValue = 3, 64 | StringValue = "Text" 65 | }; 66 | } 67 | } 68 | #endregion 69 | 70 | } 71 | -------------------------------------------------------------------------------- /tests/Valit.Tests/Valitator/Valitator_ValitRules_Tests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace Valit.Tests.Valitator 6 | { 7 | public class Valitator_ValitRules_Tests 8 | { 9 | [Fact] 10 | public void CreateValitator_Throws_When_Null_ValitRulesProvider_Is_Given() 11 | { 12 | var exception = Record.Exception(() => { 13 | var valitator = ((IValitRules)null).CreateValitator(); 14 | }); 15 | 16 | exception.ShouldBeOfType(typeof(ValitException)); 17 | } 18 | 19 | [Fact] 20 | public void Created_Valitator_Properly_Handles_Complete_Strategy() 21 | { 22 | var valitator = _valitRules.CreateValitator(); 23 | var result = valitator.Validate(_model); 24 | 25 | result.Succeeded.ShouldBeFalse(); 26 | result.ErrorMessages.ShouldContain("One"); 27 | result.ErrorMessages.ShouldNotContain("Two"); 28 | result.ErrorMessages.ShouldContain("Three"); 29 | } 30 | 31 | [Fact] 32 | public void Created_Valitator_Properly_Handles_FailFast_Strategy() 33 | { 34 | var valitator = _valitRules.CreateValitator(); 35 | var result = valitator.Validate(_model, new FailFastValitStrategy()); 36 | 37 | result.Succeeded.ShouldBeFalse(); 38 | result.ErrorMessages.ShouldContain("One"); 39 | result.ErrorMessages.ShouldNotContain("Two"); 40 | result.ErrorMessages.ShouldNotContain("Three"); 41 | } 42 | 43 | 44 | #region ARRANGE 45 | 46 | class Model 47 | { 48 | public ushort NumericValue { get; set; } 49 | public string StringValue { get; set; } 50 | } 51 | 52 | private readonly Model _model; 53 | private readonly IValitRules _valitRules; 54 | 55 | public Valitator_ValitRules_Tests() 56 | { 57 | _model = new Model 58 | { 59 | NumericValue = 3, 60 | StringValue = "Text" 61 | }; 62 | 63 | _valitRules = ValitRules 64 | .Create() 65 | .Ensure(m => m.NumericValue, _=>_ 66 | .IsGreaterThan(10) 67 | .WithMessage("One")) 68 | .Ensure(m => m.StringValue, _=>_ 69 | .Required() 70 | .WithMessage("Two") 71 | .Email() 72 | .WithMessage("Three")); 73 | } 74 | } 75 | #endregion 76 | 77 | } 78 | -------------------------------------------------------------------------------- /tools/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------