Esempio n. 1
0
        public void TestDynamic2()
        {
            var x = ObservableValue <int> .From(3);

            var xreader = x as IValueReader <int>;
            var xwriter = x as IValueWriter <int>;

            var y = ComputedValue <int> .From(() => xreader.Value *xreader.Value);

            Assert.Equal(9, y.Value);

            var values = new List <int>();

            var diposable = y.Observe(change =>
            {
                values.Add(change.NewValue);
            });

            xwriter.Value = 5;

            Assert.Equal(25, y.Value);

            Assert.Single(values);
            Assert.Equal(25, values[0]);
        }
        public void TestActionModificationPickup3()
        {
            var a = ObservableValue <int> .From(1);

            var b = 0;

            var doubler = ComputedValue <int> .From(() => a.Value * 2);

            doubler.Observe(change =>
            {
                b = doubler.Value;
            }, true);

            Assert.Equal(2, b);

            var action = Actions.CreateAction("action", () =>
            {
                a.Value = a.Value + 1; // ha, no loop!
            });

            action();

            Assert.Equal(4, b);

            action();

            Assert.Equal(6, b);
        }
Esempio n. 3
0
        public void TestDynamic()
        {
            var x = ObservableValue <int> .From(3);

            var xreader = x as IValueReader <int>;
            var xwriter = x as IValueWriter <int>;

            var y = ComputedValue <int> .From(() => xreader.Value);

            var values = new List <int>();

            var diposable = y.Observe(change =>
            {
                values.Add(change.NewValue);
            }, true);

            Assert.Equal(3, y.Value);

            xwriter.Value = 5;

            Assert.Equal(5, y.Value);

            Assert.Equal(2, values.Count);

            Assert.Equal(3, values[0]);
            Assert.Equal(5, values[1]);
        }
        private void PreCompute()
        {
            _Path = ComputedValue <string> .From(() =>
            {
                if (Parent == null)
                {
                    return("");
                }

                return($"{Parent.Path}/{Subpath.EscapeJsonPath()}");
            });

            _Value = ComputedValue <object> .From(() =>
            {
                if (!IsAlive)
                {
                    return(null);
                }
                return(Type.GetValue(this));
            });

            _Snapshot = ComputedValue <object> .From(() =>
            {
                if (!IsAlive)
                {
                    return(null);
                }
                return(Type.GetSnapshot(this, false));
            });
        }
Esempio n. 5
0
            public Order()
            {
                Vat = ObservableValue <double> .From(0.2);

                Price = ObservableValue <double> .From(10);

                PriceWithVat = ComputedValue <double> .From(() => (Price as IValueReader <double>).Value *(1 + (Vat as IValueReader <double>).Value));
            }
        public void TestAllowModificationInComputed()
        {
            var a = ObservableValue <int> .From(2);

            var d = Reactions.Autorun(() => { var x = a.Value; });

            IComputedValue <int> c2 = null;

            var action = Actions.CreateAction("action", () =>
            {
                Actions.AllowStateChangesInsideComputed(() =>
                {
                    a.Value = 3;

                    //// a second level computed should throw
                    Assert.Throws <CaughtException>(() =>
                    {
                        // /Computed values are not allowed to cause side effects by changing observables that are already being observed/

                        var x = c2.Value;
                    });
                });

                Assert.Equal(3, a.Value);

                Assert.Throws <Exception>(() =>
                {
                    // /Computed values are not allowed to cause side effects by changing observables that are already being observed/

                    a.Value = 4;
                });
            });

            var c = ComputedValue <int> .From(() =>
            {
                action();
                return(a.Value);
            });


            c2 = ComputedValue <int> .From(() => {
                a.Value = 6;
                return(a.Value);
            });


            var _ = c.Value;

            d.Dispose();
        }
        public void TestAutorun2()
        {
            var list = ObservableList <int> .From(new[] { 4, 2, 3 });

            List <int> sorted = null;

            var sortedX = ComputedValue <List <int> > .From(() =>
            {
                var splice = list.ToList();
                splice.Sort();
                return(splice);
            });

            Reactions.Autorun((r) =>
            {
                sorted = sortedX.Value;
            });

            Assert.Equal(4, list[0]);
            Assert.Equal(2, list[1]);
            Assert.Equal(3, list[2]);

            Assert.Equal(2, sorted[0]);
            Assert.Equal(3, sorted[1]);
            Assert.Equal(4, sorted[2]);

            list.Add(1);

            Assert.Equal(4, list[0]);
            Assert.Equal(2, list[1]);
            Assert.Equal(3, list[2]);
            Assert.Equal(1, list[3]);

            Assert.Equal(1, sorted[0]);
            Assert.Equal(2, sorted[1]);
            Assert.Equal(3, sorted[2]);
            Assert.Equal(4, sorted[3]);

            list.Shift();

            Assert.Equal(2, list[0]);
            Assert.Equal(3, list[1]);
            Assert.Equal(1, list[2]);

            Assert.Equal(1, sorted[0]);
            Assert.Equal(2, sorted[1]);
            Assert.Equal(3, sorted[2]);
        }
Esempio n. 8
0
        public void TestBatch()
        {
            var a = ObservableValue <int> .From(2);

            var b = ObservableValue <int> .From(3);

            var areader = a as IValueReader <int>;
            var awriter = a as IValueWriter <int>;

            var breader = b as IValueReader <int>;
            var bwriter = b as IValueWriter <int>;

            var c = ComputedValue <int> .From(() => areader.Value *breader.Value);

            var d = ComputedValue <int> .From(() => c.Value *breader.Value);

            var values    = new List <int>();
            var diposable = d.Observe(change =>
            {
                values.Add(change.NewValue);
            });

            awriter.Value = 4;
            bwriter.Value = 5;

            // Note, 60 should not happen! (that is d beign computed before c after update of b)
            Assert.Equal(2, values.Count);
            Assert.Equal(36, values[0]);
            Assert.Equal(100, values[1]);

            var x = Reactions.Transaction <int>(() =>
            {
                awriter.Value = 2;
                bwriter.Value = 3;
                awriter.Value = 6;

                Assert.Equal(54, d.Value);

                return(2);
            });

            Assert.Equal(2, x);
            Assert.Equal(3, values.Count);
            Assert.Equal(36, values[0]);
            Assert.Equal(100, values[1]);
            Assert.Equal(54, values[2]);
        }
Esempio n. 9
0
        public void TestComputed()
        {
            var box = ObservableValue <int> .From(3);

            var reader = box as IValueReader <int>;
            var writer = box as IValueWriter <int>;

            var x = ComputedValue <int> .From(() => reader.Value * 2);

            var y = ComputedValue <int> .From(() => reader.Value * 3);

            Assert.Equal(6, x.Value);
            Assert.Equal(9, y.Value);

            writer.Value = 5;

            Assert.Equal(10, x.Value);
            Assert.Equal(15, y.Value);
        }
Esempio n. 10
0
        internal StoredReference(StoreType type, object value, IType targetType)
        {
            Type = type;

            Value = value;

            TargetType = targetType;

            if (Type == StoreType.Object)
            {
                if (!value.IsStateTreeNode())
                {
                    throw new ArgumentException($"Can only store references to tree nodes, got: '{value}'");
                }

                var node = value.GetStateTreeNode();

                if (string.IsNullOrWhiteSpace(node.IdentifierAttribute))
                {
                    throw new ArgumentException("Can only store references with a defined identifier attribute.");
                }
            }

            _resolvedValue = ComputedValue <object> .From(() =>
            {
                var identifier = Value?.ToString();

                if (string.IsNullOrWhiteSpace(identifier))
                {
                    return(null);
                }

                // reference was initialized with the identifier of the target
                var target = Node.Root.IdentifierCache?.Resolve(TargetType, identifier);

                if (target == null)
                {
                    throw new Exception($"Failed to resolve reference '{identifier}' to type '{TargetType.Name}' (from node: {Node.Path})");
                }

                return(target?.Value);
            });
        }
Esempio n. 11
0
        private void PreCompute()
        {
            _Value = ComputedValue <object> .From(() =>
            {
                if (!IsAlive)
                {
                    return(null);
                }
                return(Type.GetValue(this));
            });

            _Snapshot = ComputedValue <object> .From(() =>
            {
                if (!IsAlive)
                {
                    return(null);
                }
                return(Type.GetSnapshot(this, false));
            });
        }
Esempio n. 12
0
        public void TestTransaction()
        {
            var x1 = ObservableValue <int> .From(3);

            var x2 = ObservableValue <int> .From(5);

            var x1reader = x1 as IValueReader <int>;
            var x1writer = x1 as IValueWriter <int>;

            var x2reader = x2 as IValueReader <int>;
            var x2writer = x2 as IValueWriter <int>;

            var y = ComputedValue <int> .From(() => x1reader.Value + x2reader.Value);

            var values = new List <int>();

            var diposable = y.Observe(change =>
            {
                values.Add(change.NewValue);
            }, true);

            Assert.Equal(8, y.Value);

            x1writer.Value = 4;

            Assert.Equal(9, y.Value);

            Reactions.Transaction(() =>
            {
                x1writer.Value = 5;
                x2writer.Value = 6;
            });

            Assert.Equal(11, y.Value);
            Assert.Equal(3, values.Count);

            Assert.Equal(8, values[0]);
            Assert.Equal(9, values[1]);
            Assert.Equal(11, values[2]);
        }
        public void TestAutorunInActionDoesNotKeepComputedAlive()
        {
            var calls    = 0;
            var computed = ComputedValue <int> .From(() => calls ++);

            Action callComputedTwice = () =>
            {
                var x = computed.Value;
                var y = computed.Value;
            };

            Action <Action> runWithMemoizing = (fun) =>
            {
                Reactions.Autorun(fun).Dispose();
            };

            callComputedTwice();
            Assert.Equal(2, calls);

            runWithMemoizing(callComputedTwice);
            Assert.Equal(3, calls);

            callComputedTwice();
            Assert.Equal(5, calls);

            runWithMemoizing(() =>
            {
                Actions.RunInAction <int>("x", () =>
                {
                    callComputedTwice();
                    return(0);
                });
            });
            Assert.Equal(6, calls);

            callComputedTwice();
            Assert.Equal(8, calls);
        }
        public void TestModificationInComputed()
        {
            var a = ObservableValue <int> .From(2);

            var action = Actions.CreateAction("action", () =>
            {
                a.Value = 3;
            });

            var c = ComputedValue <object> .From(() =>
            {
                action();
                return(null);
            });

            var d = Reactions.Autorun(() =>
            {
                // expect not to throws
                var x = c.Value;
            });


            d.Dispose();
        }
        public void TestModificationErrorInComputed()
        {
            var a = ObservableValue <int> .From(2);

            var d = Reactions.Autorun(() => { var x = a.Value; });

            var action = Actions.CreateAction("action", () =>
            {
                a.Value = 3;
            });

            var c = ComputedValue <int> .From(() =>
            {
                action();
                return(a.Value);
            });

            Assert.Throws <Exception>(() =>
            {
                var x = c.Value;
            });

            d.Dispose();
        }
Esempio n. 16
0
        public void TestComputedAutorun()
        {
            var box = ObservableValue <int> .From(3);

            var reader = box as IValueReader <int>;
            var writer = box as IValueWriter <int>;

            var x = ComputedValue <int> .From(() => reader.Value * 2);

            var values = new List <int>();

            Reactions.Autorun((reaction) =>
            {
                values.Add(x.Value);
            });

            writer.Value = 5;
            writer.Value = 10;

            Assert.Equal(3, values.Count);
            Assert.Equal(6, values[0]);
            Assert.Equal(10, values[1]);
            Assert.Equal(20, values[2]);
        }
Esempio n. 17
0
        public void TestTransactionInspection()
        {
            var a = ObservableValue <int> .From(2);

            var areader = a as IValueReader <int>;
            var awriter = a as IValueWriter <int>;

            var calcs = 0;
            var b     = ComputedValue <int> .From(() =>
            {
                calcs++;
                return(areader.Value * 2);
            });

            // if not inspected during transaction, postpone value to end
            Reactions.Transaction(() =>
            {
                awriter.Value = 3;
                Assert.Equal(6, b.Value);
                Assert.Equal(1, calcs);
            });

            Assert.Equal(6, b.Value);
            Assert.Equal(2, calcs);

            // if inspected, evaluate eagerly
            Reactions.Transaction(() =>
            {
                awriter.Value = 4;
                Assert.Equal(8, b.Value);
                Assert.Equal(3, calcs);
            });

            Assert.Equal(8, b.Value);
            Assert.Equal(4, calcs);
        }
        public void TestComputedValuesAndAction()
        {
            var calls = 0;

            var number = ObservableValue <int> .From(1);

            var squared = ComputedValue <int> .From(() =>
            {
                calls++;
                return(number.Value *number.Value);
            });

            var changeNumber10Times = Actions.CreateAction("changeNumber10Times", () =>
            {
                var x = squared.Value;
                var y = squared.Value;
                for (int i = 0; i < 10; i++)
                {
                    number.Value = number.Value + 1;
                }
            });

            changeNumber10Times();
            Assert.Equal(1, calls);

            Reactions.Autorun(r =>
            {
                changeNumber10Times();
                Assert.Equal(2, calls);
            });

            Assert.Equal(2, calls);

            changeNumber10Times();
            Assert.Equal(3, calls);
        }
        public void TestSetup()
        {
            var list = ObservableList <int> .From();

            Assert.Empty(list);

            list.Add(1);

            Assert.Single(list);
            Assert.Equal(1, list[0]);

            list[1] = 2;

            Assert.Equal(2, list.Length);
            Assert.Equal(1, list[0]);
            Assert.Equal(2, list[1]);

            var compute = ComputedValue <int> .From(() =>
            {
                return(-1 + list.Aggregate(1, (acc, curr) => acc + curr));
            });

            Assert.Equal(3, compute.Value);

            list[1] = 3;

            Assert.Equal(2, list.Length);
            Assert.Equal(1, list[0]);
            Assert.Equal(3, list[1]);
            Assert.Equal(4, compute.Value);

            list.Splice(1, 1, 4, 5);

            Assert.Equal(3, list.Length);
            Assert.Equal(1, list[0]);
            Assert.Equal(4, list[1]);
            Assert.Equal(5, list[2]);
            Assert.Equal(10, compute.Value);

            list.Replace(new[] { 2, 4 });

            Assert.Equal(2, list.Length);
            Assert.Equal(2, list[0]);
            Assert.Equal(4, list[1]);
            Assert.Equal(6, compute.Value);

            list.Splice(1, 1);

            Assert.Equal(1, list.Length);
            Assert.Equal(2, list[0]);
            Assert.Equal(2, compute.Value);

            list.Splice(0, 0, new[] { 4, 3 });

            Assert.Equal(3, list.Length);
            Assert.Equal(4, list[0]);
            Assert.Equal(3, list[1]);
            Assert.Equal(2, list[2]);
            Assert.Equal(9, compute.Value);

            list.Clear();

            Assert.Empty(list);
            Assert.Equal(0, compute.Value);

            list.Length = 4;

            Assert.Equal(4, list.Length);
            Assert.Equal(0, compute.Value);

            list.Replace(new[] { 1, 2, 2, 4 });

            Assert.Equal(4, list.Length);
            Assert.Equal(9, compute.Value);

            list.Length = 4;

            Assert.Equal(4, list.Length);
            Assert.Equal(9, compute.Value);

            list.Length = 2;

            Assert.Equal(2, list.Length);
            Assert.Equal(3, compute.Value);
            Assert.Equal(1, list[0]);
            Assert.Equal(2, list[1]);

            list.Unshift(3);

            Assert.Equal(3, list.Length);
            Assert.Equal(6, compute.Value);
            Assert.Equal(3, list[0]);
            Assert.Equal(1, list[1]);
            Assert.Equal(2, list[2]);

            list[2] = 4;

            Assert.Equal(3, list.Length);
            Assert.Equal(8, compute.Value);
            Assert.Equal(3, list[0]);
            Assert.Equal(1, list[1]);
            Assert.Equal(4, list[2]);
        }
Esempio n. 20
0
        public bool TryGetComputedValue(string calculationConfiguration, ValueRequirement valueRequirement, out ComputedValue result)
        {
            result = null;

            ViewCalculationResultModel model;

            if (!_configurationMap.TryGetValue(calculationConfiguration, out model))
            {
                return(false);
            }

            ISet <ComputedValue> values;

            if (!model.TryGetAllValues(valueRequirement.TargetSpecification, out values))
            {
                return(false);
            }

            var computedValues = values.Where(v => valueRequirement.IsSatisfiedBy(v.Specification));

            result = computedValues.FirstOrDefault();
            return(result != null);
        }
Esempio n. 21
0
 public ViewResultEntry(string calculationConfiguration, ComputedValue computedValue)
 {
     _calculationConfiguration = calculationConfiguration;
     _computedValue            = computedValue;
 }