Code Monkey home page Code Monkey logo

ensure.that's People

Contributors

danielwertheim avatar dinispeixoto avatar jameskyburz avatar jeffhandley avatar loedeman avatar ndrwrbgs avatar nevaldas avatar pbouillon avatar rbanks54 avatar tagc avatar vakadavr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ensure.that's Issues

Add more Resharper Annotations

Not all current [NotNull]'s are annotated, we should fill in any existing gaps. Also of particular use to users would be usage of the [InvokerParameterName] which helps with auto-completion of the paramName arguments.

I'd be happy to contribute this just opening an issue for tracking

Suggestion: add WithException

Please add an extension method WithException(...) to define a custom exception to be thrown. It can be done today with Throws => Throws(x => x.Custom( ....)) but seems a little lengthy and not as fluent.

Thank you.

Consider [Conditional] instead of/in addition to On/Off

[DebuggerStepThrough]
[Conditional("notsatisfied")]
public static void AnyConditional<T>(this Param<IList<T>> param, Func<T, bool> predicate)

Results in
conditional

and benchmark confirms that even the That is not run
benchmark

This change would prevent the overhead (though minimal) of checking IsActive ever, but would make Active/Inactive toggleable at the binary level only rather than dynamically at runtime (is dynamic a user requirement? I'm not sure of the uses cases for it)

Benchmark code:

private IList<string> strings;

public ArgumentValidation()
{
    this.strings = new List<string>(10);
    for (int i = 0; i < 9; i++)
    {
        this.strings.Add(string.Empty);
    }
    this.strings.Add(null);
}

[Benchmark]
public void AnyNoThrow()
{
    try
    {
        Ensure.That(this.strings).Any(s => null == (s));
    }
    catch { }
}

[Benchmark]
public void AnyConditional()
{
    Ensure.That(this.strings).AnyConditional(s => !string.IsNullOrEmpty(s));
}

[Benchmark]
public void BCLNoThrow()
{
    var len = this.strings.Count;
    for (int i = 0; i < len; i++)
    {
        if (null == (this.strings[i]))
        {
            return;
        }
    }
    try {
    throw new Exception();
    }
    catch { }
}

[Benchmark]
public void Baseline()
{
    Ensure.That(this.strings);
}

Add support for IEnumerable<T>

The library appears to support IList, ICollection, and arrays, but IEnumerable should cover all of those bases, shouldn't it? Most of the collections I deal with are IEnumerable.

Great library!

Custom messages

One thing that would be nice is support for custom messages anywhere, maybe inside Param. Sometimes I may want the null check but may want to give a more informative, friendly exception message. Assuming there is nothing there for this currently best I can tell. Any ideas on this topic?

Should there be a T ContainsKey (not just IDictionary)?

Many of the other methods like SizeIs, HasAny, etc in the CollectionArg class expose a type-preserving API (e.g. where T : ICollection<TOther>). Should ContainsKey have the same for parity?

Also, other IDictionary methods in this class contain an overload for IReadOnlyDictionary explicitly; should this method?

The type or namespace name 'Resources' does not exist in the namespace 'EnsureThat'

Installed from NuGet:
package id="Ensure.That.Source" version="0.8.1" targetFramework="net40"

Most all code files generated the following error on compile:

The type or namespace name 'Resources' does not exist in the namespace 'EnsureThat' (are you missing an assembly reference?)

ExceptionMessages.resx is there now unlike the previous version but there is no designer code generated file. I was able to fix this manually via changing the properties of the resx project item:

  1. Set custom tool to:
    ResXFileCodeGenerator

  2. Set custom tool namespace to:
    EnsureThat.Resources

Ensure.That().Value?

Was .Value removed due to some .NET standard limitation? Any plans to bring it back (i.e. net std 2.0)?

It's a bummer this doesn't appear to work anymore as it was handy:

_logger = Ensure.That(logger, nameof(logger)).IsNotNull().Value;

Couldn't find file or assembly

Hi!
I am getting the following error: "Could not load file or assembly 'EnsureThat, Version=2.0.0.39118, Culture=neutral, PublicKeyToken=xxxxxxx' or one of its dependencies. The system cannot find the file specified" when calling to the constructor of MyCouch's MyCouchUriBuilder constructor.

Also I want to comment that in order to sign our project's installer, we sign MyCouch package with the package StrongNaming https://www.nuget.org/packages/Nivot.StrongNaming/

Resharper warning "Possible multiple enumeration of IEnumerable" when using EnsureArg.*

I've been using Pommalabs.Thrower as my guard clause library of choice for a while, but I've recently started using R# and I get quite a lot of warnings about possible enumeration of my IEnumerable method parameters when using Raise.ArgumentNullException.IfIsNull.

I considered switching to using Ensure.That as I saw from your release notes that you handle this situation with Ensure.That(enumerable).IsNotNull(). Unfortunately, this doesn't seem to have been implemented with the lighter-weight simple static methods that you've introduced in v5.0.0.

Having a brief look through your code base, I think that this could be resolved by creating a file EnsureArg.Enumerables.cs:

using System;
using System.Diagnostics;
using JetBrains.Annotations;

namespace EnsureThat
{
    public static partial class EnsureArg
    {
        [DebuggerStepThrough]
        public static void IsNotNull<T>([NoEnumeration] IEnumerable<T> value, string paramName = Param.DefaultName)
        {
            if (!Ensure.IsActive)
                return;

            if (value == null)
                throw new ArgumentNullException(paramName, ExceptionMessages.Common_IsNotNull_Failed);
        }
    }
}

Design: Why does SizeIs accept a long count since collection.Count is an int?

Was it a some performance concern to keep just int?

Though here's a sample that would require a long, via Enumerable.LongCount perhaps, but I imagine it is only applicable in contrived scenarios and not applicable on ICollection which exposes an int Count property, nor on IList which exposes an int this[] accessor.

var myBigEnumerable = Enumerable.Range(0, int.MaxValue)
  .Concat(Enumerable.Range(0, 10));
Ensure.Collection.SizeIs(
  myBigEnumerable,
  2147483657,
  "paramName");

Add exception xmldoc elements

Some plugins like Exceptional utilize the <exception> xmldoc element to provide a type of checked-exceptions experience similar to java. Documenting the methods that can throw with the <exception> element would enable those scenarios.

String.IsNotNullOrWhitespace Returning ArgumentNullExceptions for Whitespace Values

I have tons of unit tests in the same project verifying the arguments are valid throughout the project using Ensure.String.IsNotNullOrWhiteSpace(). They all expect an ArgumentNullException for null string values and an ArgumentException for empty or whitespace strings.

However, the empty/whitespace exceptions switch from ArgumentExceptions to ArgumentNullExceptions and back for no apparent reason. And when they switch, they are consistent within a class but not w/in the project. So 2 classes can use the exact same Ensure.String.IsNotNullOrWhitespace method for the exact same argument, but one class throws ArgumentExceptions and the other throws ArgumentNullExceptions.

In looking at the source code, this seems totally impossible; however, I can see the issue happening repeatedly. I haven't figured out how to intentionally cause the problem; however, that's to be expected b/c the behavior is clearly governed by something outside of my project b/c it switches w/out any changes to the project.

This is just a pain b/c a large number of unit tests start failing intermittently.

Validation proposals

Paths

make sure work here includes thoughts about how to handle the case where Directory method is called but a File exists at the path

  • DirectoryExists
  • DirectoryDoesNotExist
  • FileExists
  • FileDoesNotExist

Object

  • IsNull (though Is(null) probably suffices)
  • Implements/Extends
  • IsAnyOf (analogous to Is)
  • IsNotAnyOf

Number

  • IsApproximately(accuracy/within)
  • IsPositive
  • IsNegative
  • IsNotNegative

Collection

  • SizeIsGt/Lt/Gte/Lte
  • SizeIsNot
  • Contains
  • DoesNotContain
  • ^variation of above | HasNoNull
  • ContainsExactly(2, [optional] where: item => item == "foo")
  • IsEmpty (.SizeIs(0))
  • IsInAscendingOrder (IComparable only)
  • IsInDescendingOrder (IComparable only)

Dictionary

  • DoesNotContainKey
  • ContainsValue
  • DoesNotContainsValue

String

  • StartsWith #97
  • EndsWith
  • Contains
  • DoesNotContain
  • IsNullOrWhiteSpace
  • IsNullOrEmpty
  • IsEmpty
  • SizeIsGt/Lt/Gte/Lte
  • SizeIsNot
  • DoesNotMatch

Suggestion : add IsNotDefault()

I suggest that you add a new extension method IsNotDefault() that check the value is not the default one for the current type, especially for primitive types. it would simplify the check.

For instance, with a "int input", it would be
Ensure.That(input, "input").IsNotDefault();
Instead of :
Ensure.That(input, "input").IsNot(default(int));

Or maybe you already have something to handle that, but I couldn't find it.

Thanks !

Consider using struct for Param<T>

I believe the motivating factor for deprecating the Ensure.That syntax was the object allocation. A quick test with struct seems that it may be as performant as the new static methods, and maintain the Ensure.That syntax this library derives it's name from. I believe that the usage of Param<T> will work within the constraints introduced by struct also.

I can isolate the test change I did for a PR to send as proof of concept and include BenchmarkDotNet results for various scenarios. This issue is to track that work.

Dictionary.ContainsKey

Add feature for: Ensure.That(dictionary).ContainsKey()

[DebuggerStepThrough]
public static Param<IDictionary<TKey, TValue>> ContainsKey<TKey, TValue>(this Param<IDictionary<TKey, TValue>> param, TKey key)
{
    if (!param.Value.ContainsKey(key))
        throw ExceptionFactory.CreateForParamValidation(param, $"Could not find key {key} in dictionary.");

    return param;
}

Allow for choosing exception type

"Ensuring that..." (i.e. the concept) applies to more than just arguments. I'm thinking specifically about state. For instance, I'd like to ensure that HttpContext.Current is not null, but I don't want to throw an argument exception if it is. I'd want to throw an InvalidOperationException. I'd suggest

public static class CustomExceptionExtensions
    {
        public static Param<T> WithExceptionOf<T>(this Param<T> param, Func<T> exceptionFn)
        {
            param.ExceptionFn = messageFn;
            return param;
        }
    }

either that or add .State after Ensure.That() or something to cue the library to throw InvalidOperationException.

Saving code lines

Hey,

rather than write your own extensions for each type, it would be more convenient if you put the constraints on the generic so that it goes on all numeric types.

like:

public static Param <TKey> IsLt<TKey> (Param param <TKey>, TKey limit) where TKey: struct, IComparable, IComparable <TKey>
{
if (param.Value> = limit) {
throw ExceptionFactory.CreateForParamValidation (param, ExceptionMessages.EnsureExtensions_IsNotLt.Inject (param.Value, limit));
}

return param;
}

So you have to deal with only the Nullable version for the following types. (date, float, double, byte, char, int16, int32, int64 + all unsigned versions)

public static Param <Nullable <TKey>> IsLt<TKey> (Param <Nullable <TKey>> param, TKey limit) where TKey: struct, IComparable, IComparable <TKey>
{
if (!param.Value.HasValue || param.Value.Value > = limit) {
throw ExceptionFactory.CreateForParamValidation (param, ExceptionMessages.EnsureExtensions_IsNotLt.Inject (param.Value, limit));
}

return param;
}

greets sam

Referenced assembly System.Linq.Expressions cannot resolve in dnx46

Trying to include Ensure.That in a ASP.NET 5 / dnx46 project and receiving the following error about a missing assembly reference:

Error CS0012 The type 'Expression<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Linq.Expressions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

I am added the System.Linq.Expressions nugget package for the most recent (beta) version as well as the 4.0.10.0 version but that doesn't resolve the build error.

Resources throws exception

Is there something I need to do after installing the package? As soon as a guard "assertion" fails I get the below.

<System.Resources.MissingManifestResourceException> (Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "EnsureThat.Resources.ExceptionMessages.resources" was correctly embedded or linked into assembly "TestAssembly" at compile time, or that all the satellite assemblies required are loadable and fully signed.)

at System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(String fileName)
at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)

...

Allow IsOfType to accept subclasses of the specified type

Currently, IsOfType throws an exception when type of the passed object is different from the specified type.

However, it is often desired to see if an object is a subclass of a certain type. So, it could be useful if we can make IsOfType optionally accept any subclass of the specified type rather than an instance that exactly matches it.

Lambda performance improvements

Hello @danielwertheim
First of all thank you for your library - it is really great.
Second one πŸ˜„
I spent some time on the performance improvements for lambda expressions and I want to share my results.
Compiling is slow operation for func, so I decided to replace it with the ExpressionVisitor and I got:

Name                                    Milliseconds        Percent                       
Ensure.That.Direct                      7                   916.9%                        
Ensure.That.Expression                  489                 59670.4%                      
Ensure.That.ThatAlternative1            36896               4500270%                      
Ensure.That.ThatAlternative2            37472               4570483.5%                    
Simple null check                       0                   100%                          

As you can see

Ensure.That(TestObject, "TestObject").IsNotNull()

is faster then

Ensure.That(() => TestObject).IsNotNull()

in ~70 times, but it is not so nice and clear 😸

So we can change code in the main package, or I can create an extension and publish it to the nuget for the people, who want to have expressions in the Ensure.That?

Benchmark code (it uses https://github.com/bodyloss/BenchmarkIt) :

public class SimpleBenchmark
{
    public TestObject TestObject { get; set; }

    public SimpleBenchmark()
    {
        TestObject = new TestObject();
    }

    [Fact]
    public void MyMethod()
    {
        Benchmark
            .This("Ensure.That.Direct", () => Ensure.That(TestObject, "TestObject").IsNotNull())
            .Against
            .This("Ensure.That.Expression", () => Ensure.That(() => TestObject).IsNotNull())
            .Against
            .This("Ensure.That.ThatAlternative1", () => Extensions.ThatAlternative1(() => TestObject).IsNotNull())
            .Against
            .This("Ensure.That.ThatAlternative2", () => Extensions.ThatAlternative2(() => TestObject).IsNotNull())
            .Against
            .This("Simple null check", () =>
            {
                if (TestObject == null)
                {
                    throw new ArgumentNullException("TestObject");
                }
            })
            .WithWarmup(1000)
            .For(100000)
            .Iterations()
            .PrintComparison();

    }
}

English typo

cannot instead of can not
public static string Common_IsNotNull_Failed { get; private set; } = "Value can not be null.";

.NET Core framework update needed.

Hi,

My app uses a recently released .NET Core 1.0 and it cannot compile with Ensure.That because of the different framework name:

The dependency Ensure.That 4.0.0 does not support framework .NETCoreApp,Version=v1.0.

Could you please add netcoreapp1.0 to the list of supported frameworks?

do not allow us to be an idiot

would be good if you don't let us to do the following
Ensure
.That(myString, nameof(myString))
.IsNotNullOrWhiteSpace()
.WithExtraMessageOf(p => "Some more details");

Consider an Ensure.Dictionary type-specific class

Problem: Intellisense shows the IDictionary methods when I do Ensure.Collection, which are not valid on an ICollection. Could we introduce a new DictionaryArg class as a subclass of CollectionArg?

Custom exception error with EnsureArgs

Dear,

I am trying to use your library but I see that Ensure.That is going to be deprecated.
So I was curious on how I can do the following:
EnsureArg.IsFalse(true);

And have my own exception stating something like "value should be not true".
Hope you can help me out because I could not find it in the docs.

Consider replacing string.Empty.Equals(value)

I notice new changes in the library around performance (specifically, the migration away from Ensure.That to static methods and EnsureArg). Given performance is important -- let's replace string.Empty.Equals(value) with value != null && string.IsNullOrEmpty(value)

BenchmarkDotNet micro benchmark showed this to be ~3x faster (intuitively makes sense as it doesn't have to deal with the overhead of equality just to see if it's empty - which I think the BCL uses .Length to test)

EnsureArg

Introduce as a more effective and simpler API but keep the old as well.

Can not use EnsureArg from the existing as those might have decorations of e.g. WithException. Dual track with duplicate tests?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.