public ResultOrErrorDetails <TDestination> Map <TDestination>(Func <T, TDestination> mapper) { if (mapper == null) { throw new ArgumentNullException(nameof(mapper)); } if (!_result.IsDefined) { if (typeof(T) == typeof(TDestination)) { //@ return this; } return(ResultOrErrorDetails <TDestination> .FromError(_error.Value)); } var newResult = mapper(_result.Value); if (newResult == null) { throw new ArgumentException($"The provided {nameof(mapper)} returned null, which is not valid"); } if ((typeof(T) == typeof(TDestination)) && newResult.Equals(_result.Value)) { //@ return this; } return(new ResultOrErrorDetails <TDestination>(newResult, _error)); }
private static void EqualsTests() { QUnit.Module("Equals(..)"); QUnit.Test("An instance of NonBlankTrimmedString is found to be equal to itself", assert => { var x = new NonBlankTrimmedString("xyz"); AssertEqualsViaNonBlankTrimmedStringEqualsCall(assert, x, x, shouldBeEqual: true); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are found to be equal when compared as NonBlankTrimmedString", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new NonBlankTrimmedString("xyz"); AssertEqualsViaNonBlankTrimmedStringEqualsCall(assert, x, y, shouldBeEqual: true); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are found to be equal when compared as generic type param of NonBlankTrimmedString", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new NonBlankTrimmedString("xyz"); AssertEqualsViaSharedGenericTypeEqualsCall(assert, x, y, shouldBeEqual: true); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are found to be equal when compared as Object", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new NonBlankTrimmedString("xyz"); AssertEqualsViaObjectEqualsCall(assert, x, y, shouldBeEqual: true); }); // There was a hack in ProductiveRage.Immutable to help Optional<T>'s Equals implementation work when T is an [ObjectLiteral] but that isn't required with the hacks in this library // (so, once I'm happy with this all, I'll remove them from ProductiveRage.Immutable, so 3.2.0 will have the hacks removed that were introduced in 3.1.0 - for now, the tests here // are referencing the 3.0.0 NuGet package, which doesn't have the hacks in it) QUnit.Test("Two instances of Optional<NonBlankTrimmedString> with the same value are found to be equal when compared as NonBlankTrimmedString", assert => { var x = Optional.For(new NonBlankTrimmedString("xyz")); var y = Optional.For(new NonBlankTrimmedString("xyz")); AssertEqualsViaOptionalNonBlankTrimmedStringEqualsCall(assert, x, y, shouldBeEqual: true); }); QUnit.Test("Two instances of Optional<NonBlankTrimmedString> with the same value are found to be equal when compared as generic type param of NonBlankTrimmedString", assert => { var x = Optional.For(new NonBlankTrimmedString("xyz")); var y = Optional.For(new NonBlankTrimmedString("xyz")); AssertEqualsViaSharedGenericTypeEqualsCall(assert, x, y, shouldBeEqual: true); }); QUnit.Test("Two instances of Optional<NonBlankTrimmedString> with the same value are found to be equal when compared as Object", assert => { var x = Optional.For(new NonBlankTrimmedString("xyz")); var y = Optional.For(new NonBlankTrimmedString("xyz")); AssertEqualsViaObjectEqualsCall(assert, x, y, shouldBeEqual: true); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are NOT equal if they are of different types when compared as NonBlankTrimmedString", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new ClassName("xyz"); AssertEqualsViaNonBlankTrimmedStringEqualsCall(assert, x, y, shouldBeEqual: false); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are NOT equal if they are of different types when compared as generic type param of NonBlankTrimmedString", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new ClassName("xyz"); AssertEqualsViaSharedGenericTypeEqualsCall(assert, x, y, shouldBeEqual: false); }); QUnit.Test("Two instances of NonBlankTrimmedString with the same value are NOT equal if they are of different types when compared as Object", assert => { var x = new NonBlankTrimmedString("xyz"); var y = new ClassName("xyz"); AssertEqualsViaObjectEqualsCall(assert, x, y, shouldBeEqual: false); }); // This tests a few issues that have been encountered after using [ObjectLiteral] in more places - the FixObjectLiteralEqualsHack approach means that the implicit operator will // not reliably be called when comparing an Optional<T> to T (the fix for that is in 4.1.0 of ProductiveRage.Immutable) and FixObjectLiteralEqualsHack now supports "falling // through" equality checks if false is returned (so is comparing a NonBlankTrimmedString, which is an [ObjectLiteral], to an Optional<NonBlankTrimmedString> then the Equals // check made against the NonBlankTrimmedString's Equals method will return false as it is unaware of Optional's implicit casting support and so other Equals methods need to // be give opportunity to run) and it tests a bug with FixObjectLiteralEqualsHack relating to different generic types where the cached Equals lookup for an [ObjectLiteral] // generic class would result in type checks against the generic type parameters being incorrect. QUnit.Test("Integration tests around NonBlankTrimmedString / Optional / another [ObjectLiteral]", assert => { var stringValue = new NonBlankTrimmedString("test"); var optionalOfString = Optional.For(stringValue); var resultOrErrorOfString = ResultOrErrorDetails.FromResult(stringValue); assert.NotOk(Equals(optionalOfString, resultOrErrorOfString)); assert.Ok(Equals(optionalOfString, stringValue)); assert.Ok(Equals(stringValue, optionalOfString)); assert.Ok(Equals(ResultOrErrorDetails.FromResult("abc"), ResultOrErrorDetails.FromResult("abc"))); assert.Ok(Equals(ResultOrErrorDetails.FromResult(new NonBlankTrimmedString("abc")), ResultOrErrorDetails.FromResult(new NonBlankTrimmedString("abc")))); assert.NotOk(Equals(ResultOrErrorDetails.FromResult(new NonBlankTrimmedString("abc")), ResultOrErrorDetails.FromResult("abc"))); }); }