├── icon_1280.png
├── media
├── 144.png
├── 256.png
├── 512.png
├── 72.png
├── 96.png
├── fav16.ico
├── favicon.ico
├── logotype 1024.eps
├── logotype 1024.pdf
├── logotype 1024.png
├── 48.svg
├── 72.svg
├── 96.svg
├── 144.svg
├── 256.svg
├── 512.svg
└── logotype 1024.svg
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
├── stale.yaml
└── workflows
│ ├── codeql-analysis.yml
│ ├── publish.yml
│ └── build.yml
├── src
└── GuardClauses
│ ├── icon.png
│ ├── ValidatedNotNullAttribute.cs
│ ├── Guard.cs
│ ├── GuardAgainstExpressionExtensions.cs
│ ├── Exceptions
│ └── NotFoundException.cs
│ ├── GuardClauses.csproj
│ ├── GuardAgainstInvalidFormatExtensions.cs
│ ├── GuardAgainstNotFoundExtensions.cs
│ ├── GuardAgainstZeroExtensions.cs
│ └── GuardAgainstOutOfRangeExtensions.cs
├── test
└── GuardClauses.UnitTests
│ ├── GlobalUsings.cs
│ ├── NamespaceSeparate
│ └── ExtendingGuard.cs
│ ├── GuardAgainstFooExtension.cs
│ ├── GuardClauses.UnitTests.csproj
│ ├── GuardAgainstNotFound.cs
│ ├── GuardAgainstInvalidFormatTests.cs
│ ├── GuardAgainstOutOfRangeForInt.cs
│ ├── GuardAgainstOutOfRangeForUint.cs
│ ├── GuardAgainstOutOfRangeForShort.cs
│ ├── GuardAgainstExpression.cs
│ ├── GuardAgainstOutOfRangeForFloat.cs
│ ├── GuardAgainstOutOfRangeForDouble.cs
│ ├── GuardAgainstOutOfRangeForDecimal.cs
│ ├── GuardAgainstNull.cs
│ ├── GuardAgainstOutOfRangeForIComparable.cs
│ ├── GuardAgainstOutOfRangeForDateTime.cs
│ ├── GuardAgainstDefault.cs
│ ├── GuardAgainstNullOrInvalidInput.cs
│ ├── GuardAgainstOutOfRangeForInvalidInput.cs
│ ├── GuardAgainstOutOfSQLDateRange.cs
│ ├── GuardAgainstNullOrWhiteSpace.cs
│ ├── GuardAgainstOutOfRangeForTimeSpan.cs
│ ├── GuardAgainstOutOfRangeForEnumerableInt.cs
│ ├── GuardAgainstOutOfRangeForEnumerableShort.cs
│ ├── GuardAgainstOutOfRangeForEnumerableLong.cs
│ ├── GuardAgainstOutOfRangeForEnum.cs
│ ├── GuardAgainstOutOfRangeForEnumerableFloat.cs
│ ├── GuardAgainstOutOfRangeForEnumerableDecimal.cs
│ ├── GuardAgainstOutOfRangeForEnumerableDouble.cs
│ ├── GuardAgainstOutOfRangeForEnumerableTimeSpan.cs
│ └── GuardAgainstNullOrEmpty.cs
├── Directory.Build.props
├── nuget.txt
├── LICENSE
├── GuardClauses.sln
├── CONTRIBUTING.md
├── azure-pipelines.yml.bak
├── README.md
├── .gitignore
└── .editorconfig
/icon_1280.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/icon_1280.png
--------------------------------------------------------------------------------
/media/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/144.png
--------------------------------------------------------------------------------
/media/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/256.png
--------------------------------------------------------------------------------
/media/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/512.png
--------------------------------------------------------------------------------
/media/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/72.png
--------------------------------------------------------------------------------
/media/96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/96.png
--------------------------------------------------------------------------------
/media/fav16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/fav16.ico
--------------------------------------------------------------------------------
/media/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/favicon.ico
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ardalis
4 |
--------------------------------------------------------------------------------
/media/logotype 1024.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/logotype 1024.eps
--------------------------------------------------------------------------------
/media/logotype 1024.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/logotype 1024.pdf
--------------------------------------------------------------------------------
/media/logotype 1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/media/logotype 1024.png
--------------------------------------------------------------------------------
/src/GuardClauses/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/GuardClauses/HEAD/src/GuardClauses/icon.png
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 |
2 | blank_issues_enabled: false
3 | contact_links:
4 | - name: Question
5 | url: https://github.com/ardalis/GuardClauses/discussions/categories/q-a
6 | about: Please ask and answer questions in the Discussions Q&A tab.
7 |
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | ---
5 |
6 |
7 |
8 | - .NET SDK Version:
9 |
10 | Steps to Reproduce:
11 |
12 | 1.
13 | 2.
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/GuardClauses/ValidatedNotNullAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Ardalis.GuardClauses
4 | {
5 | ///
6 | /// Add to methods that check input for null and throw if the input is null.
7 | ///
8 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
9 | public sealed class ValidatedNotNullAttribute : Attribute { }
10 | }
11 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using System;
2 | global using System.Collections;
3 | global using System.Collections.Generic;
4 | global using System.ComponentModel;
5 | global using System.Data.SqlTypes;
6 | global using System.Linq;
7 | global using System.Runtime.CompilerServices;
8 | global using Ardalis.GuardClauses;
9 | global using Microsoft.VisualBasic;
10 | global using Xunit;
11 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 8
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | # default location of `.github/workflows`
5 | directory: "/"
6 | open-pull-requests-limit: 10
7 | schedule:
8 | interval: "weekly"
9 |
10 | - package-ecosystem: nuget
11 | directory: "/"
12 | schedule:
13 | interval: daily
14 | open-pull-requests-limit: 10
15 | ignore:
16 | - dependency-name: altcover
17 | versions:
18 | - 8.1.819
--------------------------------------------------------------------------------
/nuget.txt:
--------------------------------------------------------------------------------
1 | Checklist:
2 | https://ardalis.com/nuget-publication-checklist
3 |
4 | -- Don't forget to update the .csproj file with version and release notes!
5 |
6 | dotnet pack -c release /p:Version=1.0.0
7 |
8 | -- from /bin/release folder
9 | dotnet nuget push -s https://www.nuget.org/api/v2/package -k Ardalis.GuardClauses.1.0.1.nupkg
10 |
11 | -- can also just add a release in github.com UI
12 | git tag -a v1.2.4 -m "Published 1.2.4 to nuget.org"
13 |
14 | git push --follow-tags
15 |
--------------------------------------------------------------------------------
/.github/stale.yaml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 60
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: false
18 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/NamespaceSeparate/ExtendingGuard.cs:
--------------------------------------------------------------------------------
1 | // By using the same namespace, the required using for Ardalis.GuardClauses will include custom guards regardless of location.
2 | namespace Ardalis.GuardClauses;
3 |
4 | ///
5 | /// An example Guard extension method. Throws if input is "foo".
6 | ///
7 | public static class FooGuard
8 | {
9 | #if NETSTANDARD || NETFRAMEWORK
10 | public static void Foo(this IGuardClause guardClause, string input, string parameterName)
11 | #else
12 | public static void Foo(this IGuardClause guardClause, string input, [CallerArgumentExpression("input")] string? parameterName = null)
13 | #endif
14 | {
15 | if (input?.ToLower() == "foo")
16 | throw new ArgumentException("Should not have been foo!", parameterName);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: CodeQL Analysis
2 |
3 | on:
4 | # push:
5 | # pull_request:
6 | # 1st of the month only
7 | schedule:
8 | - cron: '0 8 1 * *'
9 |
10 | jobs:
11 | analyze:
12 | name: CodeQL Analysis
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout repository
16 | id: checkout_repo
17 | uses: actions/checkout@v2
18 |
19 | - name: Initialize CodeQL
20 | id: init_codeql
21 | uses: github/codeql-action/init@v2
22 | with:
23 | queries: security-and-quality
24 |
25 | - name: Autobuild
26 | uses: github/codeql-action/autobuild@v2
27 |
28 | - name: Perform CodeQL Analysis
29 | id: analyze_codeql
30 | uses: github/codeql-action/analyze@v2
31 |
32 | # Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
33 |
--------------------------------------------------------------------------------
/src/GuardClauses/Guard.cs:
--------------------------------------------------------------------------------
1 | using JetBrainsNotNullAttribute = JetBrains.Annotations.NotNullAttribute;
2 |
3 | namespace Ardalis.GuardClauses
4 | {
5 | ///
6 | /// Simple interface to provide a generic mechanism to build guard clause extension methods from.
7 | ///
8 | public interface IGuardClause
9 | {
10 | }
11 |
12 | ///
13 | /// An entry point to a set of Guard Clauses defined as extension methods on IGuardClause.
14 | ///
15 | /// See http://www.weeklydevtips.com/004 on Guard Clauses
16 | public class Guard : IGuardClause
17 | {
18 | ///
19 | /// An entry point to a set of Guard Clauses.
20 | ///
21 | [JetBrainsNotNull] public static IGuardClause Against { get; } = new Guard();
22 |
23 | private Guard() { }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstFooExtension.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstFooExtension
4 | {
5 | [Fact]
6 | public void ThrowsGivenFoo()
7 | {
8 | Assert.Throws(() => Guard.Against.Foo("foo", "aParameterName"));
9 | }
10 |
11 | [Fact]
12 | public void DoesNothingGivenAnythingElse()
13 | {
14 | Guard.Against.Foo("anythingElse", "aParameterName");
15 | //Guard.Against.Foo(null, "aParameterName");
16 | }
17 |
18 | [Fact]
19 | public void ErrorMessageMatchesExpectedWhenNameNotExplicitlyProvided()
20 | {
21 | string? xyz = "foo";
22 |
23 | var exception = Assert.Throws(() => Guard.Against.Foo(xyz));
24 |
25 | Assert.NotNull(exception);
26 | Assert.NotNull(exception.Message);
27 | Assert.Contains($"Should not have been foo! (Parameter '{nameof(xyz)}')", exception.Message);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Steve Smith
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/GuardClauses/GuardAgainstExpressionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using JetBrainsNotNullAttribute = JetBrains.Annotations.NotNullAttribute;
3 |
4 | namespace Ardalis.GuardClauses
5 | {
6 | public static partial class GuardClauseExtensions
7 | {
8 | ///
9 | /// Throws an if evaluates to false for given
10 | ///
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | /// if the evaluates to true
17 | ///
18 | public static T AgainstExpression([JetBrainsNotNull] this IGuardClause guardClause, [JetBrainsNotNull] Func func, T input, string message) where T : struct
19 | {
20 | if (!func(input))
21 | {
22 | throw new ArgumentException(message);
23 | }
24 |
25 | return input;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | 10
7 |
8 |
9 |
10 |
11 |
12 | runtime; build; native; contentfiles; analyzers
13 | all
14 |
15 |
16 | runtime; build; native; contentfiles; analyzers; buildtransitive
17 | all
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: publish Ardalis.GuardClauses to nuget
2 | on:
3 | push:
4 | branches:
5 | - main # Your default release branch
6 | paths:
7 | - 'src/GuardClauses/**'
8 | jobs:
9 | publish:
10 | name: list Ardalis.GuardClauses on nuget.org
11 | runs-on: windows-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | # Required for a specific dotnet version that doesn't come with ubuntu-latest / windows-latest
16 | # Visit bit.ly/2synnZl to see the list of SDKs that are pre-installed with ubuntu-latest / windows-latest
17 | - name: Setup dotnet
18 | uses: actions/setup-dotnet@v1
19 | with:
20 | dotnet-version: 6.0.x
21 |
22 | # Publish
23 | - name: publish on version change
24 | uses: rohith/publish-nuget@v2
25 | with:
26 | PROJECT_FILE_PATH: src/GuardClauses/GuardClauses.csproj # Relative to repository root
27 | # VERSION_FILE_PATH: Directory.Build.props # Filepath with version info, relative to repository root. Defaults to project file
28 | VERSION_REGEX: (.*)<\/Version> # Regex pattern to extract version info in a capturing group
29 | TAG_COMMIT: true # Flag to enable / disable git tagging
30 | TAG_FORMAT: GuardClauses-v* # Format of the git tag, [*] gets replaced with version
31 | NUGET_KEY: ${{secrets.NUGET_API_KEY}} # nuget.org API key
32 |
--------------------------------------------------------------------------------
/src/GuardClauses/Exceptions/NotFoundException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Ardalis.GuardClauses
4 | {
5 | ///
6 | /// Represents error that occurs if a queried object by a particular key is null (not found).
7 | ///
8 | public class NotFoundException : Exception
9 | {
10 | ///
11 | /// Initializes a new instance of the NotFoundException class with a specified name of the queried object and its key.
12 | ///
13 | /// Name of the queried object.
14 | /// The value by which the object is queried.
15 | public NotFoundException(string key, string objectName)
16 | : base($"Queried object {objectName} was not found, Key: {key}")
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the NotFoundException class with a specified name of the queried object, its key,
22 | /// and the exception that is the cause of this exception.
23 | ///
24 | /// Name of the queried object.
25 | /// The value by which the object is queried.
26 | /// The exception that is the cause of the current exception.
27 | public NotFoundException(string key, string objectName, Exception innerException)
28 | : base($"Queried object {objectName} was not found, Key: {key}", innerException)
29 | {
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: .NET Core
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches: [ main ]
7 | pull_request:
8 | branches: [ main ]
9 |
10 | jobs:
11 | build:
12 |
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Setup .NET Core
18 | uses: actions/setup-dotnet@v1
19 | with:
20 | dotnet-version: '6.0.x'
21 | - name: Install dependencies
22 | run: dotnet restore
23 | - name: Build
24 | run: dotnet build --configuration Release --no-restore
25 |
26 | # See https://josh-ops.com/posts/github-code-coverage/
27 | # Add coverlet.collector nuget package to test project - 'dotnet add package coverlet
28 | - name: Test
29 | run: dotnet test --no-restore --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
30 |
31 | - name: Copy Coverage To Predictable Location
32 | run: cp coverage/*/coverage.cobertura.xml coverage/coverage.cobertura.xml
33 |
34 | - name: Code Coverage Summary Report
35 | uses: irongut/CodeCoverageSummary@v1.2.0
36 | # uses: joshjohanning/CodeCoverageSummary@v1.0.2
37 | with:
38 | filename: coverage/coverage.cobertura.xml
39 | badge: true
40 | format: 'markdown'
41 | output: 'both'
42 |
43 | - name: Add Coverage PR Comment
44 | uses: marocchino/sticky-pull-request-comment@v2
45 | if: github.event_name == 'pull_request'
46 | with:
47 | recreate: true
48 | path: code-coverage-results.md
49 |
--------------------------------------------------------------------------------
/GuardClauses.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.32112.339
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuardClauses", "src\GuardClauses\GuardClauses.csproj", "{2A1AA760-8929-433C-BC27-5513F0289842}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D0831547-3E6D-4E0E-8CB0-F7DA27F4E8EA}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | Directory.Build.props = Directory.Build.props
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuardClauses.UnitTests", "test\GuardClauses.UnitTests\GuardClauses.UnitTests.csproj", "{B84F450E-7778-48C8-A9DB-CCD5EE80E92E}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {2A1AA760-8929-433C-BC27-5513F0289842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {2A1AA760-8929-433C-BC27-5513F0289842}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {2A1AA760-8929-433C-BC27-5513F0289842}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {2A1AA760-8929-433C-BC27-5513F0289842}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {B84F450E-7778-48C8-A9DB-CCD5EE80E92E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {B84F450E-7778-48C8-A9DB-CCD5EE80E92E}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {B84F450E-7778-48C8-A9DB-CCD5EE80E92E}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {B84F450E-7778-48C8-A9DB-CCD5EE80E92E}.Release|Any CPU.Build.0 = Release|Any CPU
31 | EndGlobalSection
32 | GlobalSection(SolutionProperties) = preSolution
33 | HideSolutionNode = FALSE
34 | EndGlobalSection
35 | GlobalSection(ExtensibilityGlobals) = postSolution
36 | SolutionGuid = {46896DE3-41B8-442F-A6FB-6AC9F11CCBCE}
37 | EndGlobalSection
38 | EndGlobal
39 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Ardalis.GuardClauses
2 |
3 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
4 |
5 | - Reporting a bug
6 | - Discussing the current state of the code
7 | - Submitting a fix
8 | - Proposing new features
9 |
10 | ## We Develop with GitHub
11 |
12 | Obviously...
13 |
14 | ## We Use Pull Requests
15 |
16 | Mostly. But pretty much exclusively for non-maintainers. You'll need to fork the repo in order to submit a pull request. Here are the basic steps:
17 |
18 | 1. Fork the repo and create your branch from `main`.
19 | 2. If you've added code that should be tested, add tests.
20 | 3. If you've changed APIs, update the documentation.
21 | 4. Ensure the test suite passes.
22 | 5. Make sure your code lints.
23 | 6. Issue that pull request!
24 |
25 | - [Pull Request Check List](https://ardalis.com/github-pull-request-checklist/)
26 | - [Resync your fork with this upstream repo](https://ardalis.com/syncing-a-fork-of-a-github-repository-with-upstream/)
27 |
28 | ## Ask before adding a pull request
29 |
30 | You can just add a pull request out of the blue if you want, but it's much better etitquette (and more likely to be accepted) if you open a new issue or comment in an existing issue stating you'd like to make a pull request.
31 |
32 | ## Getting Started
33 |
34 | Look for [issues marked with 'help wanted'](https://github.com/ardalis/guardclauses/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) to find good places to start contributing.
35 |
36 | ## Any contributions you make will be under the MIT Software License
37 |
38 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers this project.
39 |
40 | ## Report bugs using Github's [issues](https://github.com/ardalis/guardclauses/issues)
41 |
42 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/ardalis/GuardClauses/issues/new/choose); it's that easy!
43 |
44 | ## Sponsor us
45 |
46 | If you don't have the time or expertise to contribute code, you can still support us by [sponsoring](https://github.com/sponsors/ardalis).
47 |
--------------------------------------------------------------------------------
/src/GuardClauses/GuardClauses.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | LICENSE
4 |
5 |
6 |
7 |
8 |
9 | netstandard2.0;net451;net60
10 | Ardalis.GuardClauses
11 | Ardalis.GuardClauses
12 | true
13 | Steve Smith (@ardalis)
14 | Ardalis.com
15 | https://github.com/ardalis/guardclauses
16 | A simple package by @ardalis and @nimblepros with guard clause helper methods. See docs for how to extend using your own extension methods defined in your project.
17 | A simple package with guard clause helper methods. See docs for how to extend using your own extension methods.
18 | https://github.com/ardalis/guardclauses
19 | guard clause clauses assert assertion
20 |
21 | Add more support for CallerArgumentExpression.
22 |
23 | 4.0.1
24 | Ardalis.GuardClauses
25 | icon.png
26 | true
27 | true
28 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
29 |
30 |
31 | bin\$(Configuration)\Ardalis.GuardClauses.xml
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/media/48.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/media/72.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/media/96.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/media/144.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/media/256.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstNotFound.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstNotFound
4 | {
5 | [Fact]
6 | public void DoesNothingGivenNonNullValue()
7 | {
8 | Guard.Against.NotFound("mykey", "", "string");
9 | Guard.Against.NotFound(1, 1, "int");
10 | Guard.Against.NotFound(1, Guid.Empty, "guid");
11 | Guard.Against.NotFound(Guid.Empty, DateTime.Now, "datetime");
12 | Guard.Against.NotFound(1, new Object(), "object");
13 | }
14 |
15 | [Fact]
16 | public void ThrowsGivenNullValue()
17 | {
18 | object obj = null!;
19 | Assert.Throws(() => Guard.Against.NotFound(1, obj, "null"));
20 | }
21 |
22 | [Fact]
23 | public void ReturnsExpectedValueWhenGivenNonNullValue()
24 | {
25 | Assert.Equal("", Guard.Against.NotFound("mykey", "", "string"));
26 | Assert.Equal(1, Guard.Against.NotFound(1, 1, "int"));
27 |
28 | var guid = Guid.Empty;
29 | Assert.Equal(guid, Guard.Against.NotFound(1, guid, "guid"));
30 |
31 | var now = DateTime.Now;
32 | Assert.Equal(now, Guard.Against.NotFound(1, now, "datetime"));
33 |
34 | var obj = new Object();
35 | Assert.Equal(obj, Guard.Against.NotFound(1, obj, "object"));
36 | }
37 |
38 | [Fact]
39 | public void ErrorMessageMatchesExpectedWhenNameNotExplicitlyProvidedGivenStringValue()
40 | {
41 | string? xyz = null;
42 | var key = "mykey";
43 |
44 | var exception = Assert.Throws(() => Guard.Against.NotFound(key, xyz));
45 |
46 | Assert.NotNull(exception);
47 | Assert.NotNull(exception.Message);
48 | Assert.Contains($"Queried object {nameof(xyz)} was not found, Key: {key}", exception.Message);
49 |
50 | //Assert.Equal("", Guard.Against.NotFound("mykey", "", "string"));
51 | //Assert.Equal(1, Guard.Against.NotFound(1, 1, "int"));
52 |
53 | //var guid = Guid.Empty;
54 | //Assert.Equal(guid, Guard.Against.NotFound(1, guid, "guid"));
55 |
56 | //var now = DateTime.Now;
57 | //Assert.Equal(now, Guard.Against.NotFound(1, now, "datetime"));
58 |
59 | //var obj = new Object();
60 | //Assert.Equal(obj, Guard.Against.NotFound(1, obj, "object"));
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstInvalidFormatTests.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstInvalidFormatTests
4 | {
5 | [Theory]
6 | [InlineData("12345",@"\d{1,6}")]
7 | [InlineData("50FA", @"[0-9a-fA-F]{1,6}")]
8 | [InlineData("abfACD", @"[a-fA-F]{1,8}")]
9 | [InlineData("DHSTRY",@"[A-Z]+")]
10 | [InlineData("3498792", @"\d+")]
11 | public void ReturnsExpectedValueGivenCorrectFormat(string input,string regexPattern)
12 | {
13 | var result = Guard.Against.InvalidFormat(input, nameof(input), regexPattern);
14 | Assert.Equal(input, result);
15 | }
16 |
17 | [Theory]
18 | [InlineData("aaa", @"\d{1,6}")]
19 | [InlineData("50XA", @"[0-9a-fA-F]{1,6}")]
20 | [InlineData("2GudhUtG", @"[a-fA-F]+")]
21 | [InlineData("sDHSTRY", @"[A-Z]+")]
22 | [InlineData("3F498792", @"\d+")]
23 | [InlineData("", @"\d+")]
24 | public void ThrowsGivenGivenIncorrectFormat(string input, string regexPattern)
25 | {
26 | Assert.Throws(() => Guard.Against.InvalidFormat(input, nameof(input), regexPattern));
27 | }
28 |
29 | [Theory]
30 | [InlineData(null, "Input parameterName was not in required format (Parameter 'parameterName')")]
31 | [InlineData("Please provide value in a correct format", "Please provide value in a correct format (Parameter 'parameterName')")]
32 | public void ErrorMessageMatchesExpected(string customMessage, string expectedMessage)
33 | {
34 | var exception = Assert.Throws(() => Guard.Against.InvalidFormat("aaa", "parameterName", "^b", customMessage));
35 | Assert.NotNull(exception);
36 | Assert.NotNull(exception.Message);
37 | Assert.Equal(expectedMessage, exception.Message);
38 | }
39 |
40 | [Theory]
41 | [InlineData(null, null)]
42 | [InlineData(null, "Please provide correct value")]
43 | [InlineData("SomeParameter", null)]
44 | [InlineData("SomeOtherParameter", "Value must be correct")]
45 | public void ExceptionParamNameMatchesExpected(string expectedParamName, string customMessage)
46 | {
47 | var exception = Assert.Throws(() => Guard.Against.InvalidFormat("aaa", expectedParamName, "^b", customMessage));
48 | Assert.NotNull(exception);
49 | Assert.Equal(expectedParamName, exception.ParamName);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/media/512.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/azure-pipelines.yml.bak:
--------------------------------------------------------------------------------
1 | trigger:
2 | branches:
3 | include:
4 | - master
5 | - refs/tags/*
6 | pr:
7 | - master
8 |
9 | pool:
10 | vmImage: 'windows-2019'
11 |
12 | variables:
13 | buildConfiguration: 'Release'
14 | buildPlatform: 'Any CPU'
15 | solution: '**/*.sln'
16 |
17 | steps:
18 |
19 | # Prepare
20 | - task: DotNetCoreCLI@2
21 | displayName: 'dotnet info'
22 | inputs:
23 | command: custom
24 | custom: '--info'
25 |
26 | - task: DotNetCoreCLI@2
27 | displayName: 'dotnet version'
28 | inputs:
29 | command: custom
30 | custom: '--version'
31 |
32 | - task: NuGetToolInstaller@0
33 | displayName: 'Use NuGet 4.9.3'
34 | inputs:
35 | versionSpec: 4.9.3
36 |
37 | - task: NuGetCommand@2
38 | inputs:
39 | restoreSolution: '$(solution)'
40 |
41 | # Build
42 | - task: VSBuild@1
43 | inputs:
44 | solution: '$(solution)'
45 | platform: '$(buildPlatform)'
46 | configuration: '$(buildConfiguration)'
47 | arguments: '--output $(Build.ArtifactStagingDirectory)'
48 |
49 | # Run tests and create coverage report
50 | - task: DotNetCoreCLI@2
51 | displayName: Test
52 | inputs:
53 | command: test
54 | # projects: '$(Parameters.TestProjects)'
55 | projects: '**/*[Tt]ests/*.csproj'
56 | arguments: '--configuration $(BuildConfiguration) --no-build /p:AltCover=true /p:AltCoverForce=true /p:AltCoverCallContext=[Fact] /p:AltCoverXmlReport=..\target\reports\coverage\coverage.opencover.xml --collect "Code Coverage"'
57 |
58 | - task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4
59 | displayName: ReportGenerator
60 | inputs:
61 | reports: 'src\target\reports\coverage\coverage.opencover.xml'
62 | targetdir: 'src\target\reports\coverage'
63 | reporttypes: 'HtmlInline_AzurePipelines;Cobertura;Badges'
64 | assemblyfilters: '-xunit*'
65 |
66 | - task: PublishCodeCoverageResults@1
67 | displayName: 'Publish code coverage results'
68 | inputs:
69 | codeCoverageTool: Cobertura
70 | summaryFileLocation: '$(build.sourcesdirectory)\src\target\reports\coverage\Cobertura.xml'
71 | reportDirectory: '$(build.sourcesdirectory)\src\target\reports\coverage'
72 |
73 | - task: CopyFiles@2
74 | displayName: 'Copy *.nupkg Files'
75 | inputs:
76 | SourceFolder: '$(Build.SourcesDirectory)'
77 | Contents: '**\*.nupkg'
78 | TargetFolder: '$(Build.ArtifactStagingDirectory)\Package'
79 | flattenFolders: true
80 | condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
81 |
82 | # Publish
83 | - task: PublishBuildArtifacts@1
84 | displayName: 'Publish Artifact'
85 | inputs:
86 | PathtoPublish: '$(Build.ArtifactStagingDirectory)\Package'
87 | condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
88 |
89 |
--------------------------------------------------------------------------------
/src/GuardClauses/GuardAgainstInvalidFormatExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 | using JetBrainsInvokerParameterNameAttribute = JetBrains.Annotations.InvokerParameterNameAttribute;
4 | using JetBrainsNotNullAttribute = JetBrains.Annotations.NotNullAttribute;
5 | using JetBrainsRegexPattern = JetBrains.Annotations.RegexPatternAttribute;
6 |
7 | namespace Ardalis.GuardClauses
8 | {
9 | public static partial class GuardClauseExtensions
10 | {
11 | ///
12 | /// Throws an if doesn't match the .
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | /// Optional. Custom error message
19 | ///
20 | ///
21 | public static string InvalidFormat([JetBrainsNotNull] this IGuardClause guardClause,
22 | [JetBrainsNotNull] string input,
23 | [JetBrainsNotNull][JetBrainsInvokerParameterName] string parameterName,
24 | [JetBrainsNotNull][JetBrainsRegexPattern] string regexPattern,
25 | string? message = null)
26 | {
27 | var m = Regex.Match(input, regexPattern);
28 | if (!m.Success || input != m.Value)
29 | {
30 | throw new ArgumentException(message ?? $"Input {parameterName} was not in required format", parameterName);
31 | }
32 |
33 | return input;
34 | }
35 |
36 | ///
37 | /// Throws an if doesn't satisfy the function.
38 | ///
39 | ///
40 | ///
41 | ///
42 | ///
43 | /// Optional. Custom error message
44 | ///
45 | ///
46 | ///
47 | public static T InvalidInput([JetBrainsNotNull] this IGuardClause guardClause, [JetBrainsNotNull] T input, [JetBrainsNotNull][JetBrainsInvokerParameterName] string parameterName, Func predicate, string? message = null)
48 | {
49 | if (!predicate(input))
50 | {
51 | throw new ArgumentException(message ?? $"Input {parameterName} did not satisfy the options", parameterName);
52 | }
53 |
54 | return input;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForInt.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstOutOfRangeForInt
4 | {
5 | [Theory]
6 | [InlineData(1, 1, 1)]
7 | [InlineData(1, 1, 3)]
8 | [InlineData(2, 1, 3)]
9 | [InlineData(3, 1, 3)]
10 | public void DoesNothingGivenInRangeValue(int input, int rangeFrom, int rangeTo)
11 | {
12 | Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo);
13 | }
14 |
15 | [Theory]
16 | [InlineData(-1, 1, 3)]
17 | [InlineData(0, 1, 3)]
18 | [InlineData(4, 1, 3)]
19 | public void ThrowsGivenOutOfRangeValue(int input, int rangeFrom, int rangeTo)
20 | {
21 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
22 | }
23 |
24 | [Theory]
25 | [InlineData(-1, 3, 1)]
26 | [InlineData(0, 3, 1)]
27 | [InlineData(4, 3, 1)]
28 | public void ThrowsGivenInvalidArgumentValue(int input, int rangeFrom, int rangeTo)
29 | {
30 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
31 | }
32 |
33 | [Theory]
34 | [InlineData(1, 1, 1, 1)]
35 | [InlineData(1, 1, 3, 1)]
36 | [InlineData(2, 1, 3, 2)]
37 | [InlineData(3, 1, 3, 3)]
38 | public void ReturnsExpectedValueGivenInRangeValue(int input, int rangeFrom, int rangeTo, int expected)
39 | {
40 | Assert.Equal(expected, Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
41 | }
42 |
43 | [Theory]
44 | [InlineData(null, "Input parameterName was out of range (Parameter 'parameterName')")]
45 | [InlineData("Int range", "Int range (Parameter 'parameterName')")]
46 | public void ErrorMessageMatchesExpected(string customMessage, string expectedMessage)
47 | {
48 | var exception = Assert.Throws(() => Guard.Against.OutOfRange(3, "parameterName", 0, 1, customMessage));
49 | Assert.NotNull(exception);
50 | Assert.NotNull(exception.Message);
51 | Assert.Equal(expectedMessage, exception.Message);
52 | }
53 |
54 | [Theory]
55 | [InlineData(null, null)]
56 | [InlineData(null, "Please provide correct value")]
57 | [InlineData("SomeParameter", null)]
58 | [InlineData("SomeOtherParameter", "Value must be correct")]
59 | public void ExceptionParamNameMatchesExpected(string expectedParamName, string customMessage)
60 | {
61 | var exception = Assert.Throws(() => Guard.Against.OutOfRange(3, expectedParamName, 0, 1, customMessage));
62 | Assert.NotNull(exception);
63 | Assert.Equal(expectedParamName, exception.ParamName);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForUint.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstOutOfRangeForUint
4 | {
5 | [Theory]
6 | [InlineData(1, 1, 1)]
7 | [InlineData(1, 1, 3)]
8 | [InlineData(2, 1, 3)]
9 | [InlineData(3, 1, 3)]
10 | public void DoesNothingGivenInRangeValue(uint input, uint rangeFrom, uint rangeTo)
11 | {
12 | Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo);
13 | }
14 |
15 | [Theory]
16 | [InlineData(0, 1, 3)]
17 | [InlineData(4, 1, 3)]
18 | public void ThrowsGivenOutOfRangeValue(uint input, uint rangeFrom, uint rangeTo)
19 | {
20 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
21 | }
22 |
23 | [Theory]
24 | [InlineData(0, 3, 1)]
25 | [InlineData(1, 3, 1)]
26 | [InlineData(4, 3, 1)]
27 | public void ThrowsGivenInvalidArgumentValue(uint input, uint rangeFrom, uint rangeTo)
28 | {
29 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
30 | }
31 |
32 | [Theory]
33 | [InlineData(1, 1, 1, 1)]
34 | [InlineData(1, 1, 3, 1)]
35 | [InlineData(2, 1, 3, 2)]
36 | [InlineData(3, 1, 3, 3)]
37 | public void ReturnsExpectedValueGivenInRangeValue(uint input, uint rangeFrom, uint rangeTo, uint expected)
38 | {
39 | Assert.Equal(expected, Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
40 | }
41 |
42 | [Theory]
43 | [InlineData(null, "Input parameterName was out of range (Parameter 'parameterName')")]
44 | [InlineData("Uint range", "Uint range (Parameter 'parameterName')")]
45 | public void ErrorMessageMatchesExpected(string customMessage, string expectedMessage)
46 | {
47 | var exception = Assert.Throws(() => Guard.Against.OutOfRange((uint)3.0d, "parameterName", (uint)0.0d, (uint)1.0d, customMessage));
48 | Assert.NotNull(exception);
49 | Assert.NotNull(exception.Message);
50 | Assert.Equal(expectedMessage, exception.Message);
51 | }
52 |
53 | [Theory]
54 | [InlineData(null, null)]
55 | [InlineData(null, "Please provide correct value")]
56 | [InlineData("SomeParameter", null)]
57 | [InlineData("SomeOtherParameter", "Value must be correct")]
58 | public void ExceptionParamNameMatchesExpected(string expectedParamName, string customMessage)
59 | {
60 | var exception = Assert.Throws(() => Guard.Against.OutOfRange((uint)3.0d, expectedParamName, (uint)0.0d, (uint)1.0d, customMessage));
61 | Assert.NotNull(exception);
62 | Assert.Equal(expectedParamName, exception.ParamName);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForShort.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstOutOfRangeForShort
4 | {
5 | [Theory]
6 | [InlineData(1, 1, 1)]
7 | [InlineData(1, 1, 3)]
8 | [InlineData(2, 1, 3)]
9 | [InlineData(3, 1, 3)]
10 | public void DoesNothingGivenInRangeValue(short input, short rangeFrom, short rangeTo)
11 | {
12 | Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo);
13 | }
14 |
15 | [Theory]
16 | [InlineData(-1, 1, 3)]
17 | [InlineData(0, 1, 3)]
18 | [InlineData(4, 1, 3)]
19 | public void ThrowsGivenOutOfRangeValue(short input, short rangeFrom, short rangeTo)
20 | {
21 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
22 | }
23 |
24 | [Theory]
25 | [InlineData(-1, 3, 1)]
26 | [InlineData(0, 3, 1)]
27 | [InlineData(4, 3, 1)]
28 | public void ThrowsGivenInvalidArgumentValue(short input, short rangeFrom, short rangeTo)
29 | {
30 | Assert.Throws(() => Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
31 | }
32 |
33 | [Theory]
34 | [InlineData(1, 1, 1, 1)]
35 | [InlineData(1, 1, 3, 1)]
36 | [InlineData(2, 1, 3, 2)]
37 | [InlineData(3, 1, 3, 3)]
38 | public void ReturnsExpectedValueGivenInRangeValue(short input, short rangeFrom, short rangeTo, short expected)
39 | {
40 | Assert.Equal(expected, Guard.Against.OutOfRange(input, "index", rangeFrom, rangeTo));
41 | }
42 |
43 | [Theory]
44 | [InlineData(null, "Input parameterName was out of range (Parameter 'parameterName')")]
45 | [InlineData("Short range", "Short range (Parameter 'parameterName')")]
46 | public void ErrorMessageMatchesExpected(string customMessage, string expectedMessage)
47 | {
48 | var exception = Assert.Throws(() => Guard.Against.OutOfRange((short) 3, "parameterName", (short) 0, (short) 1, customMessage));
49 | Assert.NotNull(exception);
50 | Assert.NotNull(exception.Message);
51 | Assert.Equal(expectedMessage, exception.Message);
52 | }
53 |
54 | [Theory]
55 | [InlineData(null, null)]
56 | [InlineData(null, "Please provide correct value")]
57 | [InlineData("SomeParameter", null)]
58 | [InlineData("SomeOtherParameter", "Value must be correct")]
59 | public void ExceptionParamNameMatchesExpected(string expectedParamName, string customMessage)
60 | {
61 | var exception = Assert.Throws(() => Guard.Against.OutOfRange((short)3, expectedParamName, (short)0, (short)1, customMessage));
62 | Assert.NotNull(exception);
63 | Assert.Equal(expectedParamName, exception.ParamName);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/GuardClauses.UnitTests/GuardAgainstExpression.cs:
--------------------------------------------------------------------------------
1 | namespace GuardClauses.UnitTests
2 | {
3 | public class GuardAgainstExpression
4 | {
5 | public struct CustomStruct
6 | {
7 | public string FieldName { get; set; }
8 | }
9 |
10 | private static IEnumerable