Skip to content

Commit

Permalink
Add Option.MapOrElse (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
nightruby-isa authored Aug 20, 2023
1 parent e8d6b49 commit 38ff5fa
Show file tree
Hide file tree
Showing 5 changed files with 487 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
using System.Threading.Tasks;
using NUnit.Framework;
using static Galaxus.Functional.Tests.Option.Async.OptionFactory;

namespace Galaxus.Functional.Tests.Option.Async;

[TestFixture]
internal class MapOrElseAsyncTest
{
public sealed class AsyncOption_BothSyncArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSomeTask("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return 2.ToOption();
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await CreateNoneTask().MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return 42.ToOption();
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class AsyncOption_AsyncMapArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSomeTask("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return 2.ToOption();
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await CreateNoneTask().MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return 42.ToOption();
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class AsyncOption_AsyncFallbackArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSomeTask("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(2.ToOption());
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await CreateNoneTask().MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(42.ToOption());
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class AsyncOption_BothAsyncArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSomeTask("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(2.ToOption());
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await CreateNoneTask().MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(42.ToOption());
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class SyncOption_AsyncMapArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSome("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return 2.ToOption();
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await Option<string>.None.MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return 42.ToOption();
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class SyncOption_AsyncFallbackArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSome("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(2.ToOption());
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await Option<string>.None.MapOrElseAsync(
s =>
{
mapInvoked = true;
return s.Length.ToOption();
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(42.ToOption());
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}

public sealed class SyncOption_BothAsyncArguments : MapOrElseAsyncTest
{
[Test]
public async Task CallsMap_WhenSelfIsSome()
{
var mapInvoked = false;
var fallbackInvoked = false;

var value = await CreateSome("value").MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(2.ToOption());
});

Assert.AreEqual(5.ToOption(), value);
Assert.IsTrue(mapInvoked);
Assert.IsFalse(fallbackInvoked);
}

[Test]
public async Task CallsFallback_WhenSelfIsNone()
{
var mapInvoked = false;
var fallbackInvoked = false;

Assert.AreEqual(42.ToOption(), await Option<string>.None.MapOrElseAsync(
s =>
{
mapInvoked = true;
return Task.FromResult(s.Length.ToOption());
},
() =>
{
fallbackInvoked = true;
return Task.FromResult(42.ToOption());
}));

Assert.IsFalse(mapInvoked);
Assert.IsTrue(fallbackInvoked);
}
}
}
35 changes: 35 additions & 0 deletions Galaxus.Functional.Tests/Option/OptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,41 @@ public void Option_MapOr()
Assert.AreEqual(42.ToOption(), none.MapOr(s => s.Length.ToOption(), 42.ToOption()));
}

[Test]
public void Option_MapOrElse()
{
var some = "hello".ToOption();
var none = Option<string>.None;

{
var invoked = false;

Assert.AreEqual(5.ToOption(), some.MapOrElse(
s => s.Length.ToOption(),
() =>
{
invoked = true;
return 2.ToOption();
}));

Assert.IsFalse(invoked);
}

{
var invoked = false;

Assert.AreEqual(42.ToOption(), none.MapOrElse(
s => s.Length.ToOption(),
() =>
{
invoked = true;
return 42.ToOption();
}));

Assert.IsTrue(invoked);
}
}

[Test]
public void Option_ToObject()
{
Expand Down
Loading

0 comments on commit 38ff5fa

Please sign in to comment.