public void TestNestedExpressions() { var term1 = new ReactiveVar <int>(1); var term2 = new ReactiveVar <int>(2); var subexpression = new ReactiveExpression <int>(() => term1.Value + term2.Value); ChangedCalled subexpressionChangedCalled = EnsureChangedCalled(subexpression); var term3 = new ReactiveVar <int>(3); var expression = new ReactiveExpression <int>(() => subexpression.Value + term3.Value); ChangedCalled expressionChangeCalled = EnsureChangedCalled(expression); Transaction.Start(); term3.Set(5); CompleteTransactionAndAssertChangedCalled(expressionChangeCalled); Assert.AreEqual(8, expression.Value); expressionChangeCalled.Reset(); Transaction.Start(); term1.Set(10); CompleteTransactionAndAssertChangedCalled(expressionChangeCalled); subexpressionChangedCalled.AssertCalled(); Assert.AreEqual(17, expression.Value); }
public void TestList2() { var sourcesList = new ClassWithList(); var property = new ReactiveExpression <int>(() => sourcesList.Sources.Count); property.Evaluate(); var counter = 0; var expectation = 1; property.Subscribe(s => ReactiveManagerTest.Const(s, () => counter++)); Assert.AreEqual(expectation, counter); var source1 = new Source(); sourcesList.Sources.Add(source1); Assert.AreEqual(++expectation, counter); Assert.AreEqual(1, property.Evaluate()); var source2 = new Source(); sourcesList.Sources.Add(source2); Assert.AreEqual(++expectation, counter); source1.Woop = true; Assert.AreEqual(expectation, counter); }
public void TestDisenabler() { var source = new object(); var expression = new ReactiveExpression <bool>(() => { ReactiveManager.WasRead(source); return(true); }); int notifications = 0; int expectation = 1; using (new ReactiveDisenabler()) { expression.Subscribe(getValue => Const(getValue, () => notifications++)); } expression.Evaluate(); ReactiveManager.WasChanged(source); Assert.AreEqual(++expectation, notifications); using (new ReactiveDisenabler()) { ReactiveManager.WasChanged(source); Assert.AreEqual(expectation, notifications); using (new ReactiveDisenabler(true)) { ReactiveManager.WasChanged(source); Assert.AreEqual(++expectation, notifications); } ReactiveManager.WasChanged(source); Assert.AreEqual(expectation, notifications); } ReactiveManager.WasChanged(source); Assert.AreEqual(++expectation, notifications); }
public void TestRecoveryMode() { var expectation = 1; var source1 = new DebugReactiveVariable <int>(0, "source1"); var source2 = new DebugReactiveVariable <int>(0, "source2"); var selectedSource = source1; source1.Value = 0; var function = new ReactiveExpression <int>(() => selectedSource.Value); var counter = 0; function.Subscribe(getValue => Const(getValue, () => counter++)); source1.Value++; expectation++; Assert.AreEqual(expectation, counter); selectedSource = source2; Assert.AreEqual(expectation, counter); function.Evaluate(); source2.Value++; if (RecoversAfterMissedChange) { expectation++; } Assert.AreEqual(expectation, counter); }
public void ComplexExpression() { var first = new Source(); var second = new Source(); var rx = new ReactiveExpression <string>(() => first.Woop ? "foo" : (second.Woop ? "bar" : "zoo"), "rx"); var counter = 0; var expectation = 1; Assert.AreEqual("zoo", rx.Evaluate()); rx.Subscribe(s => counter++); second.Woop = true; Assert.AreEqual(++expectation, counter); Assert.AreEqual("bar", rx.Evaluate()); first.Woop = true; Assert.AreEqual("foo", rx.Evaluate()); Assert.AreEqual(++expectation, counter); second.Woop = false; Assert.AreEqual("foo", rx.Evaluate()); Assert.AreEqual(expectation, counter); second.Woop = true; Assert.AreEqual("foo", rx.Evaluate()); Assert.AreEqual(expectation, counter); first.Woop = false; Assert.AreEqual("bar", rx.Evaluate()); Assert.AreEqual(++expectation, counter); second.Woop = false; Assert.AreEqual("zoo", rx.Evaluate()); Assert.AreEqual(++expectation, counter); }
public void Test() { var multiplication = new ReactiveExpression <int>(() => UsingABackingField * UsingAnAttributeAndPostSharp); multiplication.Subscribe(getMultiplication => Console.WriteLine("multiplication = " + getMultiplication())); UsingAnAttributeAndPostSharp = 2; UsingABackingField = 2; }
public void Square() { var input = new ReactiveVariable <int>(1); var inputSquared = new ReactiveExpression <int>(() => input.Value * input.Value); inputSquared.Subscribe(getSquare => Console.WriteLine("square = " + getSquare())); input.Value = 2; input.Value = 3; }
static void AddDependents(ReactiveVariable <int> dependency, bool weak) { int sum = 0; foreach (var obj in Enumerable.Range(0, 10000)) { var expression = new ReactiveExpression <int>(() => dependency.Value, weak); sum += expression.Evaluate(); } }
public void Composition() { var input = new ReactiveVariable <int>(); var timesTwo = new ReactiveExpression <int>(() => input.Value * 2); var timesThree = new ReactiveExpression <int>(() => input.Value * 3); var sumOfBoth = new ReactiveExpression <int>(() => timesTwo.Evaluate() + timesThree.Evaluate()); sumOfBoth.Subscribe(getValue => Console.WriteLine("sumOfBoth = " + getValue())); //Prints 'sumOfBoth = 0' input.Value = 1; //Prints 'sumOfBoth = 5' input.Value = 2; //Prints 'sumOfBoth = 10' }
public void TestReactiveVariable() { var woop = new HasReactiveVariableAttribute(); var expression = new ReactiveExpression <bool>(() => woop.Woop); int counter = 0; var expectation = 1; expression.Subscribe(get => ReactiveManagerTest.Const(get, () => counter++)); woop.Woop = !woop.Woop; Assert.AreEqual(++expectation, counter); }
public void Precise() { var left = new ReactiveVariable <bool>(); var right = new ReactiveVariable <bool>(); var leftOrRight = new ReactiveExpression <bool>(() => left.Value || right.Value); leftOrRight.Subscribe(getValue => Console.WriteLine("leftOrRight = " + getValue())); // Prints 'leftOrRight = False' right.Value = true; // Prints 'leftOrRight = True' left.Value = true; // Prints 'leftOrRight = True' right.Value = false; // Prints nothing }
public void MultipleDependence() { var source = new Source(); var sink = new ReactiveExpression <bool>(() => source.Woop && source.Woop); var counter = 0; var expectation = 1; sink.Subscribe(getValue => ReactiveManagerTest.Const(getValue, () => counter++)); Assert.AreEqual(source.Woop, sink.Evaluate()); Assert.AreEqual(expectation, counter); source.FlipWoop(); Assert.AreEqual(++expectation, counter); }
public void ReactiveVariable() { var test = new Source(); var rx = new ReactiveExpression <string>(() => test.Woop ? "foo" : "bar"); var counter = 0; var expectation = 1; rx.Subscribe(s => ReactiveManagerTest.Const(s, () => counter++)); test.Woop = true; Assert.AreEqual(++expectation, counter); test.Woop = true; Assert.AreEqual(expectation += NotificationWhenSourceChangesToSameValue, counter); test.Woop = false; Assert.AreEqual(++expectation, counter); }
public void TestIndirectDiamondSituation2() { var input = new ReactiveVariable <int>(); var timesTwo = new ReactiveExpression <int>(() => input.Value * 2, "timesTwo"); var plusOne = new ReactiveExpression <int>(() => input.Value + 1, "plusOne"); var sumOfBoth = new ReactiveExpression <int>(() => timesTwo.Evaluate() + plusOne.Evaluate(), "sumOfBoth"); var counter = 0; sumOfBoth.Subscribe(getValue => Const(getValue, () => counter++)); Assert.AreEqual(1, counter); input.Value = 1; Assert.AreEqual(2, counter); input.Value = 2; Assert.AreEqual(3, counter); }
public void TestIndirectDiamondSituation() { var source = new DebugReactiveVariable <bool>(false, "source"); source.Value = true; var mid1 = new ReactiveExpression <bool>(() => source.Value, "mid1"); var mid2 = new ReactiveExpression <bool>(() => source.Value, "mid2"); var sink = new ReactiveExpression <bool>(() => mid1.Evaluate() && mid2.Evaluate(), "sink"); var counter = 0; sink.Subscribe(getSink => Const(getSink, () => counter++)); Assert.AreEqual(1, counter); source.Value = false; Assert.AreEqual(2, counter); }
static WeakReference CreateWeakReactive(Source source) { var weakReactiveVariable = new ReactiveExpression <bool>(() => source.Woop); weakReactiveVariable.Evaluate(); int counter = 0; weakReactiveVariable.Subscribe(_ => counter++); Assert.AreEqual(1, counter); source.Woop = !source.Woop; Assert.AreEqual(2, counter); var result = new WeakReference(weakReactiveVariable); Assert.AreEqual(true, result.IsAlive); return(result); }
public void DependentListMultiThreadingTrap() { var list = new DependentList(); var counter = 0; var victimWaiter = new Waiter(); var attackerWaiter = new Waiter(); var observableExpression = new ReactiveExpression <int>(() => list.DependentCount, "DependentCountObserver"); observableExpression.Evaluate(); var victim = new Thread(() => { observableExpression.Skip(1).Subscribe(s => { s(); counter++; attackerWaiter.Release(); victimWaiter.Wait(); }); list.Sources.Add(new Source()); Assert.AreEqual(1, counter); }); var attackerList = new DependentList(); var attacker = new Thread(() => { attackerWaiter.Wait(); attackerList.Sources.Add(new Source()); victimWaiter.Release(); }); Assert.AreEqual(0, attackerList.DependentCount); victim.Start(); attacker.Start(); victim.Join(); attacker.Join(); Assert.AreEqual(1, counter); }
public void TestBasics() { var collection = new ObservableCollection <int>(); collection.Add(1); collection.Add(2); collection.Add(3); Func <ObservableCollection <int> > getCollection = () => ReactiveManagerWithList.Evaluate(() => collection); var secondElement = new ReactiveExpression <int>(() => getCollection()[1]); var counter = 0; var expectation = 0; secondElement.Subscribe(getValue => ReactiveManagerTest.Const(getValue, () => counter++)); Assert.AreEqual(++expectation, counter); collection.RemoveAt(2); Assert.AreEqual(++expectation, counter); collection.Add(0); Assert.AreEqual(++expectation, counter); }
public void MultiThreading() { var fakeSource = new Source(); var actualSource = new Source(); var waitEvaluateSource1 = new Waiter(); var waitEvaluateSource2 = new Waiter(); ReactiveExpression <bool> sink = null; var thread1 = new Thread(() => { sink = new ReactiveExpression <bool>(() => { waitEvaluateSource1.Release(); waitEvaluateSource2.Wait(); return(actualSource.Woop); }); sink.Evaluate(); }); var thread2 = new Thread(() => { waitEvaluateSource1.Wait(); Assert.AreEqual(fakeSource.Woop, fakeSource.Woop); waitEvaluateSource2.Release(); }); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); var counter = 0; sink.Subscribe(_ => counter++); Assert.AreEqual(1, counter); fakeSource.FlipWoop(); Assert.AreEqual(1, counter); actualSource.FlipWoop(); Assert.AreEqual(2, counter); }
public void NestedMultipleDependence() { var source1 = new Source(); var source2 = new Source(); var mid = new ReactiveExpression <bool>(() => source1.Woop ^ source2.Woop, "mid"); var top = new ReactiveExpression <bool>(() => mid.Evaluate() & source1.Woop, "top"); var topCounter = 0; var midCounter = 0; var topExpectation = 1; var midExpectation = 1; top.Subscribe(getValue => ReactiveManagerTest.Const(getValue, () => topCounter++)); mid.Subscribe(getValue => ReactiveManagerTest.Const(getValue, () => midCounter++)); Assert.AreEqual(topExpectation, topCounter); Assert.AreEqual(midExpectation, midCounter); source1.FlipWoop(); Assert.AreEqual(++topExpectation, topCounter); Assert.AreEqual(++midExpectation, midCounter); source2.FlipWoop(); Assert.AreEqual(++topExpectation, topCounter); Assert.AreEqual(++midExpectation, midCounter); }
public void TestSimpleExpression() { var term1 = new ReactiveVar <int>(1); var term2 = new ReactiveVar <int>(2); var expression = new ReactiveExpression <int>(() => term1.Value + term2.Value); Assert.AreEqual(3, expression.Value); ChangedCalled changedCalled = EnsureChangedCalled(expression); Transaction.Start(); term1.Set(3); term2.Set(4); CompleteTransactionAndAssertChangedCalled(changedCalled); Assert.AreEqual(7, expression.Value); changedCalled = EnsureChangedCalled(expression); Transaction.Start(); term1.Set(5); CompleteTransactionAndAssertChangedCalled(changedCalled); Assert.AreEqual(9, expression.Value); }
public void TestSourceEquality() { var source1 = new EqualityBasedOnId(1); var source2 = new EqualityBasedOnId(2); var source3 = new EqualityBasedOnId(1); var function = new ReactiveExpression <bool>(() => { ReactiveManager.WasRead(source1); return(true); }); var counter = 0; var expectation = 1; function.Subscribe(getValue => Const(getValue, () => counter++)); ReactiveManager.WasChanged(source1); Assert.AreEqual(++expectation, counter); ReactiveManager.WasChanged(source2); Assert.AreEqual(expectation, counter); ReactiveManager.WasChanged(source3); Assert.AreEqual(expectation, counter); }
public void TestList() { var source1 = new Source(); var source2 = new Source(); var source3 = new Source(); var sourcesList = new ClassWithList(); sourcesList.Sources.Add(source1); sourcesList.Sources.Add(source2); var counter = 0; var expectation = 1; var property = new ReactiveExpression <bool>(() => sourcesList.Sources[1].Woop); property.Evaluate(); property.Subscribe(s => ReactiveManagerTest.Const(s, () => counter++)); source1.Woop = true; Assert.AreEqual(expectation, counter); source2.Woop = true; Assert.AreEqual(true, property.Evaluate()); Assert.AreEqual(++expectation, counter); source1.Woop = false; sourcesList.Sources.Insert(0, source3); Assert.AreEqual(false, property.Evaluate()); Assert.AreEqual(++expectation, counter); source2.Woop = false; source3.Woop = true; Assert.AreEqual(expectation, counter); source1.Woop = true; Assert.AreEqual(true, property.Evaluate()); Assert.AreEqual(++expectation, counter); }
public SinkChain() { innerSink = new ReactiveExpression <bool>(() => !Source); outerSink = new ReactiveExpression <bool>(() => !InnerSink); }
public ComplexSink(Source source, Source source2) { this.source.Value = source; Source2 = source2; complex = new ReactiveExpression <string>(() => Source.Woop ? "foo" : (Source2.Woop ? "bar" : "zoo")); }
public SimpleSink(Source source) { Source = source; BoopReactive = new ReactiveExpression <bool>(() => Source.Woop); }
public Tree(IList <Tree> children = null, bool successful = false) { this.children.Value = children ?? new List <Tree>(); Successful = successful; hasSuccessfulBloodReactive = new ReactiveExpression <bool>(() => Successful || Children.Any(child => child.HasSuccessfulBlood)); }