public void SetOrAddValue_Adds_value_to_created_inner_node()
        {
            // ARRANGE

            var childNode = new Mock <NodeType>();
            var startNode = new Mock <NodeType>();

            startNode
            .Setup(n => n.TryGetChildNode("a"))
            .Returns((false, null));

            startNode
            .Setup(n => n.AddChild(childNode.Object))
            .Returns(startNode.Object);

            var writer = new SetOrAddNodeValueWriter <string, int, NodeType>(id => childNode.Object);

            // ACT

            var result = writer.AddValue(startNode.Object, HierarchyPath.Create("a"), 1);

            // ASSERT

            startNode.Verify(n => n.AddChild(childNode.Object), Times.Once());
            startNode.VerifyAll();

            childNode.Verify(n => n.SetValue(1), Times.Once());
            childNode.VerifyAll();

            Assert.Same(startNode.Object, result);
        }
        public void SetOrAddValue_Set_value_overwrites_existing_value()
        {
            // ARRANGE

            int value     = 2;
            var childNode = new Mock <NodeType>();

            var childNodeObject = childNode.Object;

            var startNode = new Mock <NodeType>();

            startNode
            .Setup(n => n.TryGetChildNode("a"))
            .Returns((true, childNodeObject));
            startNode
            .Setup(n => n.ReplaceChild(childNodeObject, childNodeObject))
            .Returns(startNode.Object);

            var writer = new SetOrAddNodeValueWriter <string, int, NodeType>(id => null);

            // ACT

            var result = writer.SetValue(startNode.Object, HierarchyPath.Create("a"), 1);

            // ASSERT

            startNode.Verify(n => n.TryGetChildNode("a"), Times.Once());
            startNode.VerifyAll();

            childNode.Verify(n => n.TryGetValue(out value), Times.Never());
            childNode.Verify(n => n.SetValue(1), Times.Once());
            childNode.VerifyAll();

            Assert.Same(startNode.Object, result);
        }
Exemple #3
0
        /// <summary>
        /// Set the value of the specified node of the hierarchy.
        /// if the node doesn't exist, it is created.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public TValue this[HierarchyPath <TKey> path]
        {
            get
            {
                if (this.TryGetValue(path, out var value))
                {
                    return(value);
                }

                throw new KeyNotFoundException($"path '{path}' doesn't exist or has no value");
            }
            set
            {
                bool isLocked = false;
                try
                {
                    this.writeLock.Enter(ref isLocked);

                    var writer = new SetOrAddNodeValueWriter <TKey, TValue, ImmutableNode <TKey, TValue> >(createNode: key => new ImmutableNode <TKey, TValue>(key));

                    // if the root node has changed, it substitutes the existing root node.

                    this.rootNode = writer.SetValue(this.rootNode, path, value);
                }
                finally
                {
                    if (isLocked)
                    {
                        this.writeLock.Exit();
                    }
                }
            }
        }
        public void SetOrAddValue_Sets_value_at_start_node()
        {
            // ARRANGE
            int value     = 0;
            var startNode = new Mock <NodeType>();
            var writer    = new SetOrAddNodeValueWriter <string, int, NodeType>(id => null);

            // ACT

            var result = writer.SetValue(startNode.Object, HierarchyPath.Create <string>(), 1);

            // ASSERT

            startNode.Verify(n => n.TryGetValue(out value), Times.Never());
            startNode.Verify(n => n.SetValue(1), Times.Once());
            startNode.VerifyAll();

            Assert.Same(result, startNode.Object);
        }
Exemple #5
0
        /// <summary>
        /// Adds a value to the immutable hierarchy at the specified position.
        /// </summary>
        /// <param name="path">Specifies where to set the value</param>
        /// <param name="value">the value to keep</param>
        /// <returns>returns this</returns>
        public void Add(HierarchyPath <TKey> path, TValue value)
        {
            bool isLocked = false;

            try
            {
                this.writeLock.Enter(ref isLocked);

                var writer = new SetOrAddNodeValueWriter <TKey, TValue, ImmutableNode <TKey, TValue> >(createNode: key => new ImmutableNode <TKey, TValue>(key));

                // if the root node has changed, it substitutes the existing root node.

                this.rootNode = writer.AddValue(this.rootNode, path, value);
            }
            finally
            {
                if (isLocked)
                {
                    this.writeLock.Exit();
                }
            }
        }
        public void SetOrAddValue_Adds_value_fails_if_node_has_value()
        {
            // ARRANGE

            int value     = 2;
            var childNode = new Mock <NodeType>();

            childNode
            .Setup(n => n.TryGetValue(out value))
            .Returns(true);

            var childNodeObject = childNode.Object;

            var startNode = new Mock <NodeType>();

            startNode
            .Setup(n => n.TryGetChildNode("a"))
            .Returns((true, childNodeObject));

            var writer = new SetOrAddNodeValueWriter <string, int, NodeType>(id => null);

            // ACT

            var result = Assert.Throws <ArgumentException>(() => writer.AddValue(startNode.Object, HierarchyPath.Create("a"), 1));

            // ASSERT

            startNode.Verify(n => n.TryGetChildNode("a"), Times.Once());
            startNode.VerifyAll();

            childNode.Verify(n => n.TryGetValue(out value), Times.Once());
            childNode.Verify(n => n.SetValue(1), Times.Never());
            childNode.VerifyAll();

            Assert.True(result.Message.Contains("NodeType at 'a' already has a value"));
            Assert.Equal("path", result.ParamName);
        }