Skip to content

Commit

Permalink
Fix language-ext Properties & add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danslapman committed Nov 19, 2023
1 parent aee56d0 commit 841eed5
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
33 changes: 33 additions & 0 deletions src/LeviySoft.Visor.LanguageExt.Tests/PropertyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,37 @@ public void AtIndexTest()
sut.Update(i => i * 2)(seq).ShouldBe(Seq<int?>(1, 4, 3));
sut.Update(i => i * 2)(Seq<int?>()).ShouldBe(Seq<int?>());
}

[Fact]
public void FirstTest()
{
var seq = Seq<string?>("a", "bb", "ccc");
var sut = Property.First<string?>(s => (s?.Length % 2) == 0);

sut.MaybeGet(seq).ShouldBe("bb");
sut.MaybeGet(Seq<string?>()).ShouldBeNull();

sut.Update(s => s + s?.Length)(seq).ShouldBe(Seq<string?>("a", "bb2", "ccc"));
sut.Update(s => s + s?.Length)(Seq<string?>()).ShouldBe(Seq<string?>());
}

[Fact]
public void AtKeyTest()
{
var map = Map(("a", 1), ("b", 2));
var sut = Property.AtKey<string, int>("b");
var sut2 = Property.AtKey("b", 42);

sut.MaybeGet(map).ShouldBe(2);
sut.MaybeGet(Map<string, int>()).ShouldBe(0);

sut2.MaybeGet(map).ShouldBe(2);
sut2.MaybeGet(Map<string, int>()).ShouldBe(42);

sut.Update(v => v * 2)(map)["b"].ShouldBe(4);
sut.Update(v => v * 2)(Map<string, int>()).ShouldBe(Map<string, int>());

sut2.Update(v => v * 2)(map)["b"].ShouldBe(4);
sut2.Update(v => v * 2)(Map<string, int>())["b"].ShouldBe(84);
}
}
22 changes: 22 additions & 0 deletions src/LeviySoft.Visor.LanguageExt/Internal/Utils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using LanguageExt;
using System;

namespace LeviySoft.Visor.LanguageExt.Internal;

internal static class Utils
{
public static int FindIndex<T>(this Seq<T> source, Func<T, bool> predicate)
{
int index = 0;
foreach (T elem in source)
{
if (predicate(elem))
{
return index;
}
++index;
}

return -1;
}
}
20 changes: 12 additions & 8 deletions src/LeviySoft.Visor.LanguageExt/Property.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using LanguageExt;
using System;
using LeviySoft.Visor.LanguageExt.Internal;

namespace LeviySoft.Visor.LanguageExt;

Expand All @@ -13,21 +14,24 @@ public static IProperty<Seq<T>, T> AtIndex<T>(int index) =>

public static IProperty<Seq<T>, T> First<T>() where T : class? => AtIndex<T>(0);

public static IProperty<Seq<T>, T> First<T>(Func<T, bool> predicate) where T : class? =>
Property<Seq<T>, T>.New(
seq => seq.FirstOrDefault(predicate),
upd => seq => {
var index = seq.FindIndex(predicate);
return Seq.map(seq, (i, v) => i == index ? upd(v) : v);
}
);

public static IProperty<Map<K, V>, V> AtKey<K, V>(K key) =>
Property<Map<K, V>, V>.New(
map => map[key] ?? default,
map => map.ContainsKey(key) ? map[key] : default,
upd => map => Map.map(map, (k, v) => Equals(k, key) ? upd(v) : v)
);

public static IProperty<Map<K, V>, V> AtKey<K, V>(K key, V defaultVal) =>
Property<Map<K, V>, V>.New(
map => map[key] ?? default,
map => map.ContainsKey(key) ? map[key] : defaultVal,
upd => map => map.AddOrUpdate(key, upd, upd(defaultVal))
);

public static IProperty<Seq<T>, T> First<T>(Func<T, bool> predicate) where T : class? =>
Property<Seq<T>, T>.New(
seq => seq.First(predicate),
upd => seq => Seq.map(seq, (_, v) => predicate(v) ? upd(v) : v)
);
}

0 comments on commit 841eed5

Please sign in to comment.