Skip to content

Commit

Permalink
Convenience methods for unit tests.
Browse files Browse the repository at this point in the history
References #5.
  • Loading branch information
jspuij committed Nov 26, 2019
1 parent 0957bda commit ad385e1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 31 deletions.
23 changes: 23 additions & 0 deletions src/Cortex.Net/Api/SharedStateObservableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,28 @@ public static IDictionary<TKey, TValue> Dictionary<TKey, TValue>(this ISharedSta

return new ObservableDictionary<TKey, TValue>(sharedState, enhancer, initialValues, name);
}

/// <summary>
/// Creates a computed value.
/// </summary>
/// <typeparam name="T">The type of the elements.</typeparam>
/// <param name="sharedState">The shared state to operate on.</param>
/// <param name="getter">The getter function to use.</param>
/// <param name="name">The name of the observable collection.</param>
/// <returns>The computed value.</returns>
public static IComputedValue<T> Computed<T>(this ISharedState sharedState, Func<T> getter, string name = null)
{
if (sharedState is null)
{
throw new ArgumentNullException(nameof(sharedState));
}

if (string.IsNullOrEmpty(name))
{
name = $"{nameof(ComputedValue<T>)}@{sharedState.GetUniqueId()}";
}

return new ComputedValue<T>(sharedState, new ComputedValueOptions<T>(getter, name));
}
}
}
17 changes: 17 additions & 0 deletions src/Cortex.Net/Cortex.Net.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions src/Cortex.Net/IComputedValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ public interface IComputedValue<T> : IComputedValue, IValue<T>
/// Event that fires after the value has changed.
/// </summary>
event EventHandler<ValueChangedEventArgs<T>> Changed;

/// <summary>
/// Registers the secified event handler, and optionally fires it first.
/// </summary>
/// <param name="changedEventHandler">The event handler to register.</param>
/// <param name="fireImmediately">Whether to fire the event handler immediately.</param>
void Observe(EventHandler<ValueChangedEventArgs<T>> changedEventHandler, bool fireImmediately);
}

/// <summary>
Expand Down
61 changes: 30 additions & 31 deletions test/Cortex.Net.Test/Base/ActionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void ActionShouldWrapInTransaction()
{
var values = new List<int>();

var observable = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 0);
var observable = this.sharedState.Box(0);

this.sharedState.Autorun((r) => values.Add(observable.Value));

Expand All @@ -72,7 +72,7 @@ public void ActionShouldWrapInTransaction()
[Fact]
public void ActionModificationsShouldBePickedUp1()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 1);
var a = this.sharedState.Box(1);

var i = 3;
var b = 0;
Expand Down Expand Up @@ -104,7 +104,7 @@ public void ActionModificationsShouldBePickedUp1()
[Fact]
public void ActionModificationsShouldBePickedUp2()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 1);
var a = this.sharedState.Box(1);

var b = 0;

Expand Down Expand Up @@ -135,12 +135,11 @@ public void ActionModificationsShouldBePickedUp2()
[Fact]
public void ActionModificationsShouldBePickedUp3()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 1);
var a = this.sharedState.Box(1);

var b = 0;

var doubler = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
() => a.Value * 2, "doubler"));
var doubler = this.sharedState.Computed(() => a.Value * 2, "doubler");

doubler.Observe(
(s, e) =>
Expand Down Expand Up @@ -168,8 +167,8 @@ public void ActionModificationsShouldBePickedUp3()
[Fact]
public void ActionShouldBeUntracked()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 3);
var b = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 4);
var a = this.sharedState.Box(3);
var b = this.sharedState.Box(4);

var latest = 0;
var runs = 0;
Expand Down Expand Up @@ -222,7 +221,7 @@ public void ActionShouldBeUntracked()
[Fact]
public void ShouldBePossibleToCreateAutorunInAction()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 1);
var a = this.sharedState.Box(1);
var values = new List<int>();

var adder = this.CreateAction<int, IDisposable>(increment =>
Expand Down Expand Up @@ -251,19 +250,19 @@ public void ShouldBePossibleToCreateAutorunInAction()
[Fact]
public void ShouldBePossibleToChangeUnobservedStateInActionCalledFromComputed()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 2);
var a = this.sharedState.Box(2);

var testAction = this.sharedState.CreateAction(() =>
{
a.Value = 3;
});

var c = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
var c = this.sharedState.Computed(
() =>
{
testAction();
return 0;
}, "computed"));
}, "computed");

this.sharedState.Autorun(r =>
{
Expand All @@ -280,15 +279,15 @@ public void ShouldBePossibleToChangeUnobservedStateInActionCalledFromComputed()
[Fact]
public void ShouldBePossibleToChangeObservedStateInActionCalledFromComputedIfRunInsideAllowStateChange()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 2);
var a = this.sharedState.Box(2);

var d = this.sharedState.Autorun(r =>
{
int i = a.Value;
});

ComputedValue<int> c = null;
ComputedValue<int> c2 = null;
IComputedValue<int> c = null;
IComputedValue<int> c2 = null;

var testAction = this.sharedState.CreateAction(() =>
{
Expand All @@ -312,19 +311,19 @@ public void ShouldBePossibleToChangeObservedStateInActionCalledFromComputedIfRun
});
});

c = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
c = this.sharedState.Computed(
() =>
{
testAction();
return a.Value;
}, "computed"));
}, "computed");

c2 = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
c2 = this.sharedState.Computed(
() =>
{
a.Value = 6;
return a.Value;
}, "computed"));
}, "computed");

int j = c.Value;

Expand All @@ -337,7 +336,7 @@ public void ShouldBePossibleToChangeObservedStateInActionCalledFromComputedIfRun
[Fact]
public void ShouldNotBePossibleToChangeObservedStateInAnActionCalledFromComputed()
{
var a = new ObservableValue<int>(this.sharedState, "int", this.sharedState.ReferenceEnhancer(), 2);
var a = this.sharedState.Box(2);

var d = this.sharedState.Autorun(r =>
{
Expand All @@ -349,12 +348,12 @@ public void ShouldNotBePossibleToChangeObservedStateInAnActionCalledFromComputed
a.Value = 3;
});

var c = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
var c = this.sharedState.Computed(
() =>
{
testAction();
return a.Value;
}, "computed"));
}, "computed");

Assert.Throws<InvalidOperationException>(() =>
{
Expand All @@ -370,8 +369,8 @@ public void ShouldNotBePossibleToChangeObservedStateInAnActionCalledFromComputed
[Fact]
public void ActionInAutorunShouldBeUntracked()
{
var a = new ObservableValue<int>(this.sharedState, "a", this.sharedState.ReferenceEnhancer(), 2);
var b = new ObservableValue<int>(this.sharedState, "b", this.sharedState.ReferenceEnhancer(), 3);
var a = this.sharedState.Box(2);
var b = this.sharedState.Box(3);

var values = new List<int>();

Expand Down Expand Up @@ -400,7 +399,7 @@ public void ActionInAutorunShouldBeUntracked()
public void ExceptionsInActionsShouldNotAffectGlobalState()
{
int autoRunTimes = 0;
var count = new ObservableValue<int>(this.sharedState, "a", this.sharedState.ReferenceEnhancer(), 2);
var count = this.sharedState.Box(2);

var add = this.sharedState.CreateAction(() =>
{
Expand Down Expand Up @@ -450,7 +449,7 @@ public void RunInAction()
}
};

var observable = new ObservableValue<int>(this.sharedState, "a", this.sharedState.ReferenceEnhancer(), 0);
var observable = this.sharedState.Box(0);

var d = this.sharedState.Autorun(r =>
{
Expand Down Expand Up @@ -501,11 +500,11 @@ public void RunInAction()
public void ActionInAutoRunDoesNotKeepComputedValuesAlive()
{
var calls = 0;
var computed = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
var computed = this.sharedState.Computed(
() =>
{
return calls++;
}, "computed"));
}, "computed");

Action callComputedTwice = () =>
{
Expand Down Expand Up @@ -546,13 +545,13 @@ public void ComputedValuesAndActions()
{
var calls = 0;

var number = new ObservableValue<int>(this.sharedState, "a", this.sharedState.ReferenceEnhancer(), 1);
var squared = new ComputedValue<int>(this.sharedState, new ComputedValueOptions<int>(
var number = this.sharedState.Box(1);
var squared = this.sharedState.Computed(
() =>
{
calls++;
return number.Value * number.Value;
}, "squared"));
}, "squared");

var changeNumber10Times = this.sharedState.CreateAction(() =>
{
Expand Down

0 comments on commit ad385e1

Please sign in to comment.