public void Compute_cells_fire_callbacks() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var callback1 = A.Fake <EventHandler <int> >(); output.Changed += callback1; input.Value = 3; A.CallTo(() => callback1.Invoke(A <object> ._, 4)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback1); }
public void Compute_cells_can_depend_on_other_compute_cells() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var timesTwo = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] * 2); var timesThirty = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] * 30); var output = sut.CreateComputeCell(new[] { timesTwo, timesThirty }, inputs => inputs[0] + inputs[1]); Assert.Equal(32, output.Value); input.Value = 3; Assert.Equal(96, output.Value); }
public void Compute_cells_can_have_callbacks() { var reactor = new Reactor(); var inputCell1 = reactor.CreateInputCell(1); var computeCell1 = reactor.CreateComputeCell(new[] { inputCell1 }, (values) => values[0] + 1); var observed = new List <int>(); computeCell1.Changed += (sender, value) => observed.Add(value); Assert.That(observed, Is.Empty); inputCell1.Value = 2; Assert.That(observed, Is.EquivalentTo(new[] { 3 })); }
public void Callback_cells_only_fire_on_change() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] < 3 ? 111 : 222); var callback1 = A.Fake <EventHandler <int> >(); output.Changed += callback1; input.Value = 2; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); input.Value = 4; A.CallTo(() => callback1.Invoke(A <object> ._, 222)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback1); }
public void Callbacks_should_only_be_called_once_even_if_multiple_dependencies_change() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var minusOne1 = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1); var minusOne2 = sut.CreateComputeCell(new[] { minusOne1 }, inputs => inputs[0] - 1); var output = sut.CreateComputeCell(new[] { plusOne, minusOne2 }, inputs => inputs[0] * inputs[1]); var callback1 = A.Fake <EventHandler <int> >(); output.Changed += callback1; input.Value = 4; A.CallTo(() => callback1.Invoke(A <object> ._, 10)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback1); }
public void Callbacks_only_trigger_on_change() { var reactor = new Reactor(); var inputCell1 = reactor.CreateInputCell(1); var computecell1 = reactor.CreateComputeCell(new[] { inputCell1 }, (values) => values[0] > 2 ? values[0] + 1 : 2); var observerCalled = 0; computecell1.Changed += (sender, value) => observerCalled++; inputCell1.Value = 1; Assert.That(observerCalled, Is.EqualTo(0)); inputCell1.Value = 2; Assert.That(observerCalled, Is.EqualTo(0)); inputCell1.Value = 3; Assert.That(observerCalled, Is.EqualTo(1)); }
public void Callbacks_should_only_be_called_once_even_if_multiple_dependencies_have_changed() { var reactor = new Reactor(); var inputCell1 = reactor.CreateInputCell(1); var computeCell1 = reactor.CreateComputeCell(new[] { inputCell1 }, (values) => values[0] + 1); var computeCell2 = reactor.CreateComputeCell(new[] { inputCell1 }, (values) => values[0] - 1); var computeCell3 = reactor.CreateComputeCell(new[] { computeCell2 }, (values) => values[0] - 1); var computeCell4 = reactor.CreateComputeCell(new[] { computeCell1, computeCell3 }, (values) => values[0] * values[1]); var changed4 = 0; computeCell4.Changed += (sender, value) => changed4++; inputCell1.Value = 3; Assert.That(changed4, Is.EqualTo(1)); }
public void Removing_a_callback_multiple_times_doesnt_interfere_with_other_callbacks() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var callback1 = A.Fake <EventHandler <int> >(); output.Changed += callback1; var callback2 = A.Fake <EventHandler <int> >(); output.Changed += callback2; output.Changed -= callback1; output.Changed -= callback1; output.Changed -= callback1; input.Value = 2; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); }
public void Callbacks_can_fire_from_multiple_cells() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var minusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1); var callback1 = A.Fake <EventHandler <int> >(); plusOne.Changed += callback1; var callback2 = A.Fake <EventHandler <int> >(); minusOne.Changed += callback2; input.Value = 10; A.CallTo(() => callback1.Invoke(A <object> ._, 11)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback1); A.CallTo(() => callback2.Invoke(A <object> ._, 9)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback2); }
public void Callbacks_should_not_be_called_if_dependencies_change_but_output_value_doesnt_change() { var sut = new Reactor(); var input = sut.CreateInputCell(1); var plusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var minusOne = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] - 1); var alwaysTwo = sut.CreateComputeCell(new[] { plusOne, minusOne }, inputs => inputs[0] - inputs[1]); var callback1 = A.Fake <EventHandler <int> >(); alwaysTwo.Changed += callback1; input.Value = 2; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); input.Value = 3; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); input.Value = 4; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); input.Value = 5; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); }
public void Callbacks_can_be_added_and_removed() { var sut = new Reactor(); var input = sut.CreateInputCell(11); var output = sut.CreateComputeCell(new[] { input }, inputs => inputs[0] + 1); var callback1 = A.Fake <EventHandler <int> >(); output.Changed += callback1; var callback2 = A.Fake <EventHandler <int> >(); output.Changed += callback2; input.Value = 31; A.CallTo(() => callback1.Invoke(A <object> ._, 32)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback1); A.CallTo(() => callback2.Invoke(A <object> ._, 32)).MustHaveHappenedOnceExactly(); Fake.ClearRecordedCalls(callback2); output.Changed -= callback1; var callback3 = A.Fake <EventHandler <int> >(); output.Changed += callback3; input.Value = 41; A.CallTo(() => callback1.Invoke(A <object> ._, A <int> ._)).MustNotHaveHappened(); }
public void Callbacks_can_be_removed() { var reactor = new Reactor(); var inputCell1 = reactor.CreateInputCell(1); var computeCell1 = reactor.CreateComputeCell(new[] { inputCell1 }, (values) => values[0] + 1); var observed1 = new List <int>(); var observed2 = new List <int>(); ChangedEventHandler changedHandler1 = (object sender, int value) => observed1.Add(value); ChangedEventHandler changedHandler2 = (object sender, int value) => observed2.Add(value); computeCell1.Changed += changedHandler1; computeCell1.Changed += changedHandler2; inputCell1.Value = 2; Assert.That(observed1, Is.EquivalentTo(new[] { 3 })); Assert.That(observed2, Is.EquivalentTo(new[] { 3 })); computeCell1.Changed -= changedHandler1; inputCell1.Value = 3; Assert.That(observed1, Is.EquivalentTo(new[] { 3 })); Assert.That(observed2, Is.EquivalentTo(new[] { 3, 4 })); }