Beispiel #1
0
        public void TestNodeMatcher()
        {
            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();
            EditPatch    patch       = new EditPatch(UrlBuilder.CreateConfig("abc/def", new ConfigNode()), nodeMatcher, Substitute.For <IPassSpecifier>());

            Assert.Same(nodeMatcher, patch.NodeMatcher);
        }
Beispiel #2
0
        private void AssertNodeMatcher(INodeMatcher matcher)
        {
            Assert.True(matcher.IsMatch(new TestConfigNode("NODE")
            {
                { "name", "foo" },
                { "bar", "baz" },
            }));

            Assert.False(matcher.IsMatch(new TestConfigNode("NODE")
            {
                { "name", "foo" },
            }));

            Assert.False(matcher.IsMatch(new TestConfigNode("NODE")
            {
                { "name", "boo" },
                { "bar", "baz" },
            }));

            Assert.False(matcher.IsMatch(new ConfigNode("NODE")));

            Assert.False(matcher.IsMatch(new TestConfigNode("NADE")
            {
                { "name", "foo" },
                { "bar", "baz" },
            }));

            Assert.False(matcher.IsMatch(new TestConfigNode("NODE")
            {
                { "name", "boo" },
                { "bar", "baz" },
            }));
        }
Beispiel #3
0
        public EditPatch(UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier)
        {
            UrlConfig     = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig));
            NodeMatcher   = nodeMatcher ?? throw new ArgumentNullException(nameof(nodeMatcher));
            PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier));

            loop = urlConfig.config.HasNode("MM_PATCH_LOOP");
        }
Beispiel #4
0
        /// <summary>
        /// Returns a verbose selector that will select this node.
        /// </summary>
        public INodeMatcher GenerateCssSelector(bool includeNthChild)
        {
            AndSelector selector = new AndSelector();

            // name
            if (this.Name != null)
            {
                selector.Selectors.Add(new NameSelector(this.Name));
            }

            // attributes
            foreach (string s in this.AttributeNames)
            {
                string[] parts = this[s].Split(' ');
                if (parts.Length == 1)
                {
                    // 'class' is the only attribute I know of that allows mix and match, everything else should be exact match
                    var op = (s != "class")
                                                        ? AttributeSelector.EqualToOp       // exact match
                                                        : AttributeSelector.ContainsWordOp; // mix and match - also allows string to have .class for single classed elements
                    selector.Selectors.Add(new AttributeSelector(s, op, parts[0]));
                }
                else
                {
                    foreach (string part in parts)
                    {
                        selector.Selectors.Add(new AttributeSelector(s, AttributeSelector.ContainsWordOp, part));
                    }
                }
            }

            if (this.SiblingCount > 1 && includeNthChild)
            {
                selector.Selectors.Add(new SiblingSelector(0, this.SiblingIndex + 1));
            }


            // : selectors
            var candidates = new INodeMatcher[] {
//				 new ColonSelector(":first-child")
//				,new ColonSelector(":last-child")
//				,new ColonSelector(":empty")
//				,new ColonSelector(":parent")
            };

            foreach (var c in candidates)
            {
                if (c.IsMatch(this))
                {
                    selector.Selectors.Add(c);
                }
            }

            return(selector);
        }
Beispiel #5
0
        public void TestApply()
        {
            ConfigNode config1 = new ConfigNode("NODE");
            ConfigNode config2 = new ConfigNode("NODE");
            ConfigNode config3 = new ConfigNode("NODE");
            ConfigNode config4 = new ConfigNode("NODE");

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(config1).Returns(false);
            nodeMatcher.IsMatch(config2).Returns(true);
            nodeMatcher.IsMatch(config3).Returns(false);
            nodeMatcher.IsMatch(config4).Returns(true);

            DeletePatch patch = new DeletePatch(UrlBuilder.CreateConfig("ghi/jkl", new ConfigNode("!NODE")), nodeMatcher, Substitute.For <IPassSpecifier>());

            IProtoUrlConfig urlConfig1 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig2 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig3 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig4 = Substitute.For <IProtoUrlConfig>();

            urlConfig1.Node.Returns(config1);
            urlConfig2.Node.Returns(config2);
            urlConfig3.Node.Returns(config3);
            urlConfig4.Node.Returns(config4);

            LinkedList <IProtoUrlConfig> configs = new LinkedList <IProtoUrlConfig>();

            configs.AddLast(urlConfig1);
            configs.AddLast(urlConfig2);
            configs.AddLast(urlConfig3);
            configs.AddLast(urlConfig4);

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(configs, progress, logger);

            Assert.Equal(new[] { urlConfig1, urlConfig3 }, configs);

            Received.InOrder(delegate
            {
                progress.ApplyingDelete(urlConfig2, patch.UrlConfig);
                progress.ApplyingDelete(urlConfig4, patch.UrlConfig);
            });

            progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
Beispiel #6
0
        internal void AddParent(INodeMatcher parentSelector)
        {
            AndSelector a = this.Selector as AndSelector;

            if (a == null)
            {
                this.Selector = a = new AndSelector(this.Selector);
            }

            // add at begining so it .ToString()s in the correct place
            a.Selectors.Insert(0, new HasParentSelector(parentSelector));
        }
Beispiel #7
0
        internal void AddSibling(INodeMatcher sibSelector, bool any)
        {
            AndSelector a = this.Selector as AndSelector;

            if (a == null)
            {
                this.Selector = a = new AndSelector(this.Selector);
            }

            // add at begining so it .ToString()s in the correct place
            a.Selectors.Insert(0, new HasPreviousSiblingSelector(sibSelector, any));
        }
Beispiel #8
0
        /// <summary>
        /// used for when a parent node must have a specific child
        /// </summary>
        internal void AddChild(INodeMatcher childSelector)
        {
            AndSelector a = this.Selector as AndSelector;

            if (a == null)
            {
                this.Selector = a = new AndSelector(this.Selector);
            }

            // add at begining so it .ToString()s in the correct place
            a.Selectors.Insert(0, new HasChildSelector(childSelector));
            this.HasChildSelector = true;
        }
Beispiel #9
0
        public void TestApply__NameChanged()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            UrlDir.UrlConfig urlConfig = UrlBuilder.CreateConfig(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            }, file);

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(urlConfig.config).Returns(true);

            CopyPatch patch = new CopyPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE")
            {
                { "@name", "001" },
                { "@foo", "baz" },
                { "pqr", "stw" },
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(file, progress, logger);

            Assert.Equal(2, file.configs.Count);

            Assert.Same(urlConfig, file.configs[0]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            }, file.configs[0].config);

            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "001" },
                { "foo", "baz" },
                { "pqr", "stw" },
            }, file.configs[1].config);

            progress.Received().ApplyingCopy(urlConfig, patch.UrlConfig);

            progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
        public void TestApply__NameNotChanged()
        {
            ConfigNode config = new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            };

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(config).Returns(true);

            CopyPatch patch = new CopyPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("+NODE")
            {
                { "@foo", "baz" },
                { "pqr", "stw" },
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IProtoUrlConfig protoConfig = Substitute.For <IProtoUrlConfig>();

            protoConfig.Node.Returns(config);
            protoConfig.FullUrl.Returns("abc/def.cfg/NODE");

            LinkedList <IProtoUrlConfig> configs = new LinkedList <IProtoUrlConfig>();

            configs.AddLast(protoConfig);

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(configs, progress, logger);

            Assert.Single(configs);

            Assert.Same(protoConfig, configs.First.Value);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            }, configs.First.Value.Node);

            progress.Received().Error(patch.UrlConfig, "Error - when applying copy ghi/jkl/+NODE to abc/def.cfg/NODE - the copy needs to have a different name than the parent (use @name = xxx)");

            progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
        public void TestApply()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            UrlDir.UrlConfig urlConfig1 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);
            UrlDir.UrlConfig urlConfig2 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);
            UrlDir.UrlConfig urlConfig3 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);
            UrlDir.UrlConfig urlConfig4 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(urlConfig1.config).Returns(false);
            nodeMatcher.IsMatch(urlConfig2.config).Returns(true);
            nodeMatcher.IsMatch(urlConfig3.config).Returns(false);
            nodeMatcher.IsMatch(urlConfig4.config).Returns(true);

            DeletePatch patch = new DeletePatch(UrlBuilder.CreateConfig("ghi/jkl", new ConfigNode("!NODE")), nodeMatcher, Substitute.For <IPassSpecifier>());

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(file, progress, logger);

            Assert.Equal(new[] { urlConfig1, urlConfig3 }, file.configs);

            Received.InOrder(delegate
            {
                progress.ApplyingDelete(urlConfig2, patch.UrlConfig);
                progress.ApplyingDelete(urlConfig4, patch.UrlConfig);
            });

            progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
Beispiel #12
0
 /// <summary>
 /// Sets the strategy for selecting nodes to compare.
 /// </summary>
 /// <remarks>
 ///   <para>
 /// Example with org.xmlunit.diff.DefaultNodeMatcher:
 /// <pre>
 /// .WithNodeMatcher(new DefaultNodeMatcher(ElementSelectors.ByNameAndText))
 /// </pre>
 ///   </para>
 /// </remarks>
 /* @see org.xmlunit.diff.DifferenceEngine#setNodeMatcher(NodeMatcher) */
 public DiffBuilder WithNodeMatcher(INodeMatcher nodeMatcher)
 {
     this.nodeMatcher = nodeMatcher;
     return(this);
 }
Beispiel #13
0
 public DeepStepSelector(INodeMatcher selector) : base(selector)
 {
 }
 /// <param name="sibSelector"></param>
 /// <param name="any">true=>any sibling can match, false=>only immediate sibling can match</param>
 public HasPreviousSiblingSelector(INodeMatcher sibSelector, bool any)
 {
     this._sibSelector = sibSelector;
     this._any         = any;
 }
Beispiel #15
0
        public void TestApply()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            UrlDir.UrlConfig urlConfig1 = UrlBuilder.CreateConfig(new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            }, file);

            UrlDir.UrlConfig urlConfig2 = UrlBuilder.CreateConfig(new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            }, file);

            UrlDir.UrlConfig urlConfig3 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);
            UrlDir.UrlConfig urlConfig4 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file);

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(urlConfig1.config).Returns(false);
            nodeMatcher.IsMatch(urlConfig2.config).Returns(true);
            nodeMatcher.IsMatch(urlConfig3.config).Returns(false);
            nodeMatcher.IsMatch(urlConfig4.config).Returns(true);

            EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE")
            {
                { "@foo", "baz" },
                { "pqr", "stw" },
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(file, progress, logger);

            Assert.Equal(4, file.configs.Count);

            Assert.Same(urlConfig1, file.configs[0]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            }, file.configs[0].config);

            Assert.NotSame(urlConfig2, file.configs[1]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "foo", "baz" },
                { "pqr", "stw" },
            }, file.configs[1].config);

            Assert.Same(urlConfig3, file.configs[2]);
            AssertNodesEqual(new ConfigNode("NODE"), file.configs[2].config);

            Assert.NotSame(urlConfig4, file.configs[3]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "pqr", "stw" },
            }, file.configs[3].config);

            Received.InOrder(delegate
            {
                progress.ApplyingUpdate(urlConfig2, patch.UrlConfig);
                progress.ApplyingUpdate(urlConfig4, patch.UrlConfig);
            });

            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
Beispiel #16
0
        public void TestApply__Loop()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            UrlDir.UrlConfig urlConfig = UrlBuilder.CreateConfig(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "aaa", "1" },
            }, file);

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(Arg.Is <ConfigNode>(node => int.Parse(node.GetValue("aaa")) < 10)).Returns(true);

            EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE")
            {
                { "@aaa *", "2" },
                { "bbb", "002" },
                new ConfigNode("MM_PATCH_LOOP"),
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            List <UrlDir.UrlConfig> modifiedUrlConfigs = new List <UrlDir.UrlConfig>();

            progress.ApplyingUpdate(Arg.Do <UrlDir.UrlConfig>(url => modifiedUrlConfigs.Add(url)), patch.UrlConfig);

            patch.Apply(file, progress, logger);

            Assert.Equal(1, file.configs.Count);
            Assert.NotSame(urlConfig, file.configs[0]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "aaa", "16" },
                { "bbb", "002" },
                { "bbb", "002" },
                { "bbb", "002" },
                { "bbb", "002" },
            }, file.configs[0].config);

            Assert.Same(urlConfig, modifiedUrlConfigs[0]);
            Assert.NotSame(urlConfig, modifiedUrlConfigs[1]);
            Assert.NotSame(urlConfig, modifiedUrlConfigs[2]);
            Assert.NotSame(urlConfig, modifiedUrlConfigs[3]);

            Received.InOrder(delegate
            {
                logger.Log(LogType.Log, "Looping on ghi/jkl/@NODE to abc/def/NODE");
                progress.ApplyingUpdate(urlConfig, patch.UrlConfig);
                progress.ApplyingUpdate(modifiedUrlConfigs[1], patch.UrlConfig);
                progress.ApplyingUpdate(modifiedUrlConfigs[2], patch.UrlConfig);
                progress.ApplyingUpdate(modifiedUrlConfigs[3], patch.UrlConfig);
            });

            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
Beispiel #17
0
 public CopyPatch(UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier)
 {
     UrlConfig     = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig));
     NodeMatcher   = nodeMatcher ?? throw new ArgumentNullException(nameof(nodeMatcher));
     PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier));
 }
Beispiel #18
0
 public HasParentSelector(INodeMatcher childSelector)
 {
     this._parentSelector = childSelector;
 }
Beispiel #19
0
        public void TestApply()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            ConfigNode config1 = new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            };

            ConfigNode config2 = new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            };

            ConfigNode config3 = new ConfigNode("NODE");
            ConfigNode config4 = new ConfigNode("NODE");

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(config1).Returns(false);
            nodeMatcher.IsMatch(config2).Returns(true);
            nodeMatcher.IsMatch(config3).Returns(false);
            nodeMatcher.IsMatch(config4).Returns(true);

            EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE")
            {
                { "@foo", "baz" },
                { "pqr", "stw" },
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IProtoUrlConfig urlConfig1 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig2 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig3 = Substitute.For <IProtoUrlConfig>();
            IProtoUrlConfig urlConfig4 = Substitute.For <IProtoUrlConfig>();

            urlConfig1.Node.Returns(config1);
            urlConfig2.Node.Returns(config2);
            urlConfig3.Node.Returns(config3);
            urlConfig4.Node.Returns(config4);

            urlConfig1.UrlFile.Returns(file);
            urlConfig2.UrlFile.Returns(file);
            urlConfig3.UrlFile.Returns(file);
            urlConfig4.UrlFile.Returns(file);

            LinkedList <IProtoUrlConfig> configs = new LinkedList <IProtoUrlConfig>();

            configs.AddLast(urlConfig1);
            configs.AddLast(urlConfig2);
            configs.AddLast(urlConfig3);
            configs.AddLast(urlConfig4);

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(configs, progress, logger);

            IProtoUrlConfig[] newConfigs = configs.ToArray();

            Assert.Equal(4, newConfigs.Length);

            Assert.Same(urlConfig1, newConfigs[0]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "foo", "bar" },
            }, newConfigs[0].Node);

            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "foo", "baz" },
                { "pqr", "stw" },
            }, newConfigs[1].Node);
            Assert.Same(file, newConfigs[1].UrlFile);

            Assert.Same(urlConfig3, newConfigs[2]);
            AssertNodesEqual(new ConfigNode("NODE"), newConfigs[2].Node);

            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "pqr", "stw" },
            }, newConfigs[3].Node);
            Assert.Same(file, newConfigs[3].UrlFile);

            Received.InOrder(delegate
            {
                progress.ApplyingUpdate(urlConfig2, patch.UrlConfig);
                progress.ApplyingUpdate(urlConfig4, patch.UrlConfig);
            });

            progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }
Beispiel #20
0
 public BaseStepSelector(INodeMatcher selector)
 {
     this.Selector = selector;
 }
Beispiel #21
0
 public HasChildSelector(INodeMatcher childSelector)
 {
     this._childSelector = childSelector;
 }
Beispiel #22
0
        // consumes steps and whitespace from token stream until EOS or ',' is reached
        CssPathSelector ConsumePath()
        {
            List <StepSelector> steps = new List <StepSelector>();

            bool         bContinue        = true;
            bool         isImmediateChild = false;
            string       siblingOp        = null;
            StepSelector last             = null;

            while (HasNext && bContinue)
            {
                var t = Peek;
                switch (t.Type)
                {
                case CssTokenType.Comma:
                    bContinue = false;

                    // TODO?? change the ',' to a terminator and consume it here instead of in the caller.

                    break;

                case CssTokenType.Whitespace:
                    ++_index;
                    break;

                case CssTokenType.Relationship:
                    if (last == null)
                    {
                        throw new Exception("Error starting selector path with relationship ( '>' '+' '~' ) operator.");
                    }
                    if (t.Text == ">")
                    {
                        isImmediateChild = true;                                 // set flag so next selector added, adds its self to parent as immediate
                    }
                    else
                    {
                        siblingOp = t.Text;                                 // set flag so when next node gets added, it can strip off the previous node and use as a sibling instead
                    }
                    ++_index;
                    break;

                default:
                    // add new step
                    INodeMatcher ns  = ConsumeStep();
                    var          cur = new StepSelector(ns);
                    steps.Add(cur);

                    // check last/cur have a relationship
                    if (isImmediateChild)
                    {
                        INodeMatcher pureParentSelector = last.Selector;     // grab this before it gets soiled.
                        last.AddChild(ns);                                   // this part helps pair down the tree faster
                        cur.AddParent(pureParentSelector);                   // this part is required to make it work
                        isImmediateChild = false;
                    }
                    if (siblingOp != null)
                    {
                        steps.Remove(last);                                   // remove last because it is not a parent
                        cur.AddSibling(last.Selector, siblingOp == "~");      // it is a sibling
                        siblingOp = null;
                    }

                    last = cur;
                    break;
                }
            }

            return(new CssPathSelector(steps));
        }
Beispiel #23
0
 /// <summary>
 /// Use the given <see cref="INodeMatcher"/> when comparing.
 /// </summary>
 /// <param name="nodeMatcher">INodeMatcher to use</param>
 public CompareConstraint WithNodeMatcher(INodeMatcher nodeMatcher)
 {
     diffBuilder.WithNodeMatcher(nodeMatcher);
     return(this);
 }
        public void TestApply__NameChanged()
        {
            UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg");

            ConfigNode config = new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            };

            INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>();

            nodeMatcher.IsMatch(config).Returns(true);

            CopyPatch patch = new CopyPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE")
            {
                { "@name", "001" },
                { "@foo", "baz" },
                { "pqr", "stw" },
            }), nodeMatcher, Substitute.For <IPassSpecifier>());

            IProtoUrlConfig protoConfig = Substitute.For <IProtoUrlConfig>();

            protoConfig.Node.Returns(config);
            protoConfig.UrlFile.Returns(file);

            LinkedList <IProtoUrlConfig> configs = new LinkedList <IProtoUrlConfig>();

            configs.AddLast(protoConfig);

            IPatchProgress progress = Substitute.For <IPatchProgress>();
            IBasicLogger   logger   = Substitute.For <IBasicLogger>();

            patch.Apply(configs, progress, logger);

            IProtoUrlConfig[] newConfigs = configs.ToArray();

            Assert.Equal(2, newConfigs.Length);

            Assert.Same(protoConfig, newConfigs[0]);
            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "000" },
                { "foo", "bar" },
            }, newConfigs[0].Node);

            AssertNodesEqual(new TestConfigNode("NODE")
            {
                { "name", "001" },
                { "foo", "baz" },
                { "pqr", "stw" },
            }, newConfigs[1].Node);
            Assert.Same(file, newConfigs[1].UrlFile);

            progress.Received().ApplyingCopy(protoConfig, patch.UrlConfig);

            progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null);
            progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null);

            progress.DidNotReceiveWithAnyArgs().Error(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null);
            progress.DidNotReceiveWithAnyArgs().Exception(null, null, null);
        }