Ejemplo n.º 1
0
        public void ConflictFirstElement()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod1List = new List <string>()
            {
                "X", "B", "C", "D", "E", "F"
            };
            var mod2List = new List <string>()
            {
                "Y", "B", "C", "D", "E", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(2, diff3.Count);

            // Conflict on base:"A", v1:"X", v2:"Y"
            Assert.AreEqual(Diff3ChangeType.Conflict, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            // First set is identical
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[1].ChangeType);
            Assert.AreEqual(new Span(1, 5), diff3[1].Base);
            Assert.AreEqual(new Span(1, 5), diff3[1].From1);
            Assert.AreEqual(new Span(1, 5), diff3[1].From2);
        }
Ejemplo n.º 2
0
        public void TestAllEquals()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(1, diff3.Count);

            // All elements are identical
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 5), diff3[0].Base);
            Assert.AreEqual(new Span(0, 5), diff3[0].From1);
            Assert.AreEqual(new Span(0, 5), diff3[0].From2);
        }
Ejemplo n.º 3
0
        public void MergeFirstElementFrom1And2()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "X", "B", "C", "D", "E", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(2, diff3.Count);

            // Merge from v1 "X" to base, v2
            Assert.AreEqual(Diff3ChangeType.MergeFrom1And2, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            // First set is identical
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[1].ChangeType);
            Assert.AreEqual(new Span(1, 5), diff3[1].Base);
            Assert.AreEqual(new Span(1, 5), diff3[1].From1);
            Assert.AreEqual(new Span(1, 5), diff3[1].From2);
        }
Ejemplo n.º 4
0
        public void CompareInsertsTest()
        {
            var original  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                }
            ".WrapWithMethod().Parse();
            var changed1  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                    total = i + total;
                }
            ".WrapWithMethod().Parse();
            var changed2  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                    total += i;
                }
            ".WrapWithMethod().Parse();
            var conflicts = Diff3.Compare(original, changed1, changed2);

            Assert.IsTrue(conflicts.Conflicts.Any());
            var strrep = conflicts.Conflicts.First().ToString();
        }
Ejemplo n.º 5
0
        public void CompareOverlapingTest()
        {
            var original  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                    total = i + total;
                }
            ".WrapWithMethod().Parse();
            var changed1  = @"
                var total = 0;
            ".WrapWithMethod().Parse(); //Minus 153 chars
            var changed2  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                    total += i;
                }
            ".WrapWithMethod().Parse();
            var conflicts = Diff3.Compare(original, changed1, changed2);

            var localDiff  = Diff.VisualDiff(conflicts.Local, conflicts.AncestorTree);
            var remoteDiff = Diff.VisualDiff(conflicts.Remote, conflicts.AncestorTree);

            conflicts.Conflicts = conflicts.Conflicts.ToList();

            Assert.IsTrue(conflicts.Conflicts.Any());
            var strrep = conflicts.Conflicts.First().ToString();
        }
Ejemplo n.º 6
0
        public void CompareNoConflictTest()
        {
            var original  = @"
                var total = 0;
                var n = 100;
                for (var i = n - 1; i >= 0; i--)
                {
                    total = i + total;
                }
            ".WrapWithMethod().Parse();
            var changed1  = @"
                var total = 0;
                var n = 100;
                for (var i = 0; i < n; i++)
                {
                    total = i + total;
                }
            ".WrapWithMethod().Parse();
            var changed2  = @"
                var total = 0;
                var n = 100;
                for (var i = n - 1; i >= 0; i--)
                {
                    total += i;
                }
            ".WrapWithMethod().Parse();
            var conflicts = Diff3.Compare(original, changed1, changed2);

            var localDiff  = Diff.VisualDiff(conflicts.Local, conflicts.AncestorTree);
            var remoteDiff = Diff.VisualDiff(conflicts.Remote, conflicts.AncestorTree);

            conflicts.Conflicts = conflicts.Conflicts.ToList();

            Assert.IsTrue(!conflicts.Conflicts.Any());
        }
Ejemplo n.º 7
0
        public void MergeRemoveFrom2Middle()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C", "D"
            };
            var mod1List = new List <string>()
            {
                "A", "B", "C", "D"
            };
            var mod2List = new List <string>()
            {
                "A", "D"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(3, diff3.Count);
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            Assert.AreEqual(Diff3ChangeType.MergeFrom2, diff3[1].ChangeType);
            Assert.AreEqual(new Span(1, 2), diff3[1].Base);
            Assert.AreEqual(new Span(1, 2), diff3[1].From1);
            Assert.AreEqual(new Span(0, -1), diff3[1].From2);

            Assert.AreEqual(Diff3ChangeType.Equal, diff3[2].ChangeType);
            Assert.AreEqual(new Span(3, 3), diff3[2].Base);
            Assert.AreEqual(new Span(3, 3), diff3[2].From1);
            Assert.AreEqual(new Span(1, 1), diff3[2].From2);
        }
Ejemplo n.º 8
0
        public void CompareFirstDiffLongSecondShortRegressionTest()
        {
            var original  = @"
            int outval = 0;
            switch (0x5) {
                case 0x1:
                    outval = 0x7;
                    break;

                case 0x2:
                    outval = 0x6;
                    break;

                case 0x3:
                    outval = 0x5;
                    break;

                case 0x4:
                    outval = 0x4;
                    break;

                case 0x5:
                    outval = 0x3;
                    break;

                case 0x6:
                    outval = 0x2;
                    break;

                case 0x7:
                    outval = 0x1;
                    break;

                case 0x8:
                    outval = 0x0;
                    break;
            }
            ".WrapWithMethod().Parse();
            var changed1  = @"
            int outval = 0x3;
            ".WrapWithMethod().Parse();
            var changed2  = @"
            int outval = 0;
            switch (0x4) {
                case 0x4:
                    outval = 0x4;
                    break;
            }
            ".WrapWithMethod().Parse();
            var conflicts = Diff3.Compare(original, changed1, changed2);

            var localDiff  = Diff.VisualDiff(conflicts.Local, conflicts.AncestorTree);
            var remoteDiff = Diff.VisualDiff(conflicts.Remote, conflicts.AncestorTree);

            conflicts.Conflicts = conflicts.Conflicts.ToList();
            Assert.IsTrue(conflicts.Conflicts.Any());
            var strrep = conflicts.Conflicts.First().ToString();
        }
Ejemplo n.º 9
0
        public void ConflictAndMergeSimple()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "D", "E", "B", "C", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "D", "E", "C", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            //     0    1     2    3    4
            //base A          B  C,D,E  F
            //v1   A    D,E   B  C      F
            //v2   A          B  D,E,C  F

            Assert.AreEqual(5, diff3.Count);

            // Check 0) A same for base, v1, v2
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            // Check 1) Merge from 1
            Assert.AreEqual(Diff3ChangeType.MergeFrom1, diff3[1].ChangeType);
            Assert.AreEqual(Span.Invalid, diff3[1].Base);
            Assert.AreEqual(new Span(1, 2), diff3[1].From1);
            Assert.AreEqual(Span.Invalid, diff3[1].From2);

            // Check 2) B same for base, v1, v2
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[2].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[2].Base);
            Assert.AreEqual(new Span(3, 3), diff3[2].From1);
            Assert.AreEqual(new Span(1, 1), diff3[2].From2);

            // Check 3) Merge from base
            Assert.AreEqual(Diff3ChangeType.Conflict, diff3[3].ChangeType);
            Assert.AreEqual(new Span(2, 4), diff3[3].Base);
            Assert.AreEqual(new Span(4, 4), diff3[3].From1);
            Assert.AreEqual(new Span(2, 4), diff3[3].From2);

            // Check 4) B same for base, v1, v2
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[4].ChangeType);
            Assert.AreEqual(new Span(5, 5), diff3[4].Base);
            Assert.AreEqual(new Span(5, 5), diff3[4].From1);
            Assert.AreEqual(new Span(5, 5), diff3[4].From2);
        }
Ejemplo n.º 10
0
        public void ConflictMultipleElementsFrom1And2()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "X", "Y", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "Y", "Z", "W", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(5, diff3.Count);

            // 0) Equal A = A = A
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            // 1) Conflict on X
            Assert.AreEqual(Diff3ChangeType.Conflict, diff3[1].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[1].Base);
            Assert.AreEqual(new Span(1, 1), diff3[1].From1);
            Assert.AreEqual(Span.Invalid, diff3[1].From2);

            // 2) MergeFrom1And2 "Y" and "Y"
            Assert.AreEqual(Diff3ChangeType.MergeFrom1And2, diff3[2].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[2].Base);
            Assert.AreEqual(new Span(2, 2), diff3[2].From1);
            Assert.AreEqual(new Span(1, 1), diff3[2].From2);

            // 3) MergeFrom2 "Z" and "W"
            Assert.AreEqual(Diff3ChangeType.MergeFrom2, diff3[3].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[3].Base);
            Assert.AreEqual(Span.Invalid, diff3[3].From1);
            Assert.AreEqual(new Span(2, 3), diff3[3].From2);

            // 4) Equal "F"
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[4].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[4].Base);
            Assert.AreEqual(new Span(3, 3), diff3[4].From1);
            Assert.AreEqual(new Span(4, 4), diff3[4].From2);
        }
Ejemplo n.º 11
0
        public void CompareOutOfRangeRegressionTest()
        {
            var ancestor = File.ReadAllText("Newtonsoft.Ancestor.txt").WrapWithNamespace().Parse();
            var local    = File.ReadAllText("Newtonsoft.Local.txt").WrapWithNamespace().Parse();
            var remote   = File.ReadAllText("Newtonsoft.Remote.txt").WrapWithNamespace().Parse();

            var conflicts = Diff3.Compare(ancestor, local, remote);

            var localDiff  = Diff.VisualDiff(conflicts.Local, conflicts.AncestorTree);
            var remoteDiff = Diff.VisualDiff(conflicts.Remote, conflicts.AncestorTree);

            conflicts.Conflicts = conflicts.Conflicts.ToList();
            Assert.IsTrue(conflicts.Conflicts.Any());
            var strrep = conflicts.Conflicts.First().ToString();
        }
Ejemplo n.º 12
0
        public void MergeChangesOnlyFrom2WithEmptyBase()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
            };
            var mod1List = new List <string>()
            {
            };
            var mod2List = new List <string>()
            {
                "A", "D", "E", "B", "C", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(1, diff3.Count);
            Assert.AreEqual(Diff3ChangeType.MergeFrom2, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(Span.Invalid, diff3[0].From1);
            Assert.AreEqual(new Span(0, 5), diff3[0].From2);
        }
Ejemplo n.º 13
0
        public void MergeDifferentSize()
        {
            //                                   0    1    2    3    4    5    6
            var baseList = new List <string>()
            {
                "A", "B", "C"
            };
            var mod1List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F", "G"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(3, diff3.Count);

            // Check 0) Equal "A B C"
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 2), diff3[0].Base);
            Assert.AreEqual(new Span(0, 2), diff3[0].From1);
            Assert.AreEqual(new Span(0, 2), diff3[0].From2);

            // Check 1) MergeFrom1And2 "D E F"
            Assert.AreEqual(Diff3ChangeType.MergeFrom1And2, diff3[1].ChangeType);
            Assert.AreEqual(new Span(3, 3), diff3[1].Base);
            Assert.AreEqual(new Span(3, 5), diff3[1].From1);
            Assert.AreEqual(new Span(3, 5), diff3[1].From2);

            // Check 2) MergeFrom2 "G"
            Assert.AreEqual(Diff3ChangeType.MergeFrom2, diff3[2].ChangeType);
            Assert.AreEqual(new Span(3, 3), diff3[2].Base);
            Assert.AreEqual(Span.Invalid, diff3[2].From1);
            Assert.AreEqual(new Span(6, 6), diff3[2].From2);
        }
Ejemplo n.º 14
0
        public void MergeMiddle()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "B", "C", "D", "E", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "X", "D", "E", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(3, diff3.Count);

            // First set is identical
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 1), diff3[0].Base);
            Assert.AreEqual(new Span(0, 1), diff3[0].From1);
            Assert.AreEqual(new Span(0, 1), diff3[0].From2);

            // Conflict on base:"C", v1:"X", v2:"Y"
            Assert.AreEqual(Diff3ChangeType.MergeFrom2, diff3[1].ChangeType);
            Assert.AreEqual(new Span(2, 2), diff3[1].Base);
            Assert.AreEqual(new Span(2, 2), diff3[1].From1);
            Assert.AreEqual(new Span(2, 2), diff3[1].From2);

            // Last set is identical
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[2].ChangeType);
            Assert.AreEqual(new Span(3, 5), diff3[2].Base);
            Assert.AreEqual(new Span(3, 5), diff3[2].From1);
            Assert.AreEqual(new Span(3, 5), diff3[2].From2);
        }
Ejemplo n.º 15
0
        public void ConflictMergeMultipleElementsFrom1And2()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "F"
            };
            var mod1List = new List <string>()
            {
                "A", "X", "F"
            };
            var mod2List = new List <string>()
            {
                "A", "Y", "F"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(3, diff3.Count);

            // 0) Equal A = A = A
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 0), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 0), diff3[0].From2);

            // 1) Conflict on X
            Assert.AreEqual(Diff3ChangeType.Conflict, diff3[1].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[1].Base);
            Assert.AreEqual(new Span(1, 1), diff3[1].From1);
            Assert.AreEqual(new Span(1, 1), diff3[1].From2);

            // 4) Equal "F"
            Assert.AreEqual(Diff3ChangeType.Equal, diff3[2].ChangeType);
            Assert.AreEqual(new Span(1, 1), diff3[2].Base);
            Assert.AreEqual(new Span(2, 2), diff3[2].From1);
            Assert.AreEqual(new Span(2, 2), diff3[2].From2);
        }
Ejemplo n.º 16
0
        public void MergeFullReplaceFrom1()
        {
            //                                   0    1    2    3    4    5
            var baseList = new List <string>()
            {
                "A", "B", "C"
            };
            var mod1List = new List <string>()
            {
                "D"
            };
            var mod2List = new List <string>()
            {
                "A", "B", "C"
            };

            var diff3 = Diff3.Compare(baseList, mod1List, mod2List, EqualityComparer <string> .Default).ToList();

            Assert.AreEqual(1, diff3.Count);
            Assert.AreEqual(Diff3ChangeType.MergeFrom1, diff3[0].ChangeType);
            Assert.AreEqual(new Span(0, 2), diff3[0].Base);
            Assert.AreEqual(new Span(0, 0), diff3[0].From1);
            Assert.AreEqual(new Span(0, 2), diff3[0].From2);
        }
Ejemplo n.º 17
0
        private void DiffCollection(Diff3Node diff3, DataVisitNode baseNode, DataVisitNode asset1Node, DataVisitNode asset2Node)
        {
            diff3.Type = Diff3NodeType.Collection;

            var baseItems   = baseNode != null ? baseNode.Items ?? EmptyNodes : EmptyNodes;
            var asset1Items = asset1Node != null ? asset1Node.Items ?? EmptyNodes : EmptyNodes;
            var asset2Items = asset2Node != null ? asset2Node.Items ?? EmptyNodes : EmptyNodes;

            var itemEqualityComparer = equalityComparer;

            var node = diff3.Asset1Node ?? diff3.Asset2Node ?? diff3.BaseNode;

            IEnumerable <Diff3Change> changes;
            bool recurseDiff = false;

            // Find an item in any of the list
            var firstItem = baseItems.FirstOrDefault() ?? asset1Items.FirstOrDefault() ?? asset2Items.FirstOrDefault();

            // If we have a DiffUseAsset1Attribute, list of Asset1Node becomes authoritative.
            var dataVisitMember        = node as DataVisitMember;
            var specificAssetAttribute = dataVisitMember != null?dataVisitMember.MemberDescriptor.GetCustomAttributes <DiffUseSpecificAssetAttribute>(true).FirstOrDefault() : null;

            if (specificAssetAttribute != null)
            {
                var isFromAsset2 = specificAssetAttribute is DiffUseAsset2Attribute;
                var diffChange   = isFromAsset2
                    ? new Diff3Change {
                    ChangeType = SharpDiff.Diff3ChangeType.MergeFrom2, From2 = new Span(0, asset2Items.Count - 1)
                }
                    : new Diff3Change {
                    ChangeType = SharpDiff.Diff3ChangeType.MergeFrom1, From1 = new Span(0, asset1Items.Count - 1)
                };

                changes = new[] { diffChange };

                // TODO: Try to merge back data of matching nodes
            }
            else if (firstItem != null && typeof(IDiffKey).IsAssignableFrom(firstItem.InstanceType))
            {
                // If item implement IDataDiffKey, we will use that as equality key
                changes = Diff3.Compare(
                    baseItems.Select(x => ((IDiffKey)x.Instance).GetDiffKey()).ToList(),
                    asset1Items.Select(x => ((IDiffKey)x.Instance).GetDiffKey()).ToList(),
                    asset2Items.Select(x => ((IDiffKey)x.Instance).GetDiffKey()).ToList());
                recurseDiff = true;
            }
            else
            {
                // Otherwise, do a full node comparison
                itemEqualityComparer.Reset();
                changes = Diff3.Compare(baseItems, asset1Items, asset2Items, itemEqualityComparer);
            }

            foreach (var change in changes)
            {
                switch (change.ChangeType)
                {
                case SharpDiff.Diff3ChangeType.Equal:
                    for (int i = 0; i < change.Base.Length; i++)
                    {
                        var diff3Node = recurseDiff
                                ? DiffNode(baseItems[change.Base.From + i], asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                                : new Diff3Node(baseItems[change.Base.From + i], asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.None
                        };
                        AddItem(diff3, diff3Node, change.From1.From != 0);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom1:
                    for (int i = 0; i < change.From1.Length; i++)
                    {
                        var diff3Node = new Diff3Node(null, asset1Items[change.From1.From + i], null)
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset1
                        };
                        AddItem(diff3, diff3Node, change.From1.From != 0);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom2:
                    for (int i = 0; i < change.From2.Length; i++)
                    {
                        var diff3Node = new Diff3Node(null, null, asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset2
                        };
                        AddItem(diff3, diff3Node, true);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom1And2:
                    for (int i = 0; i < change.From2.Length; i++)
                    {
                        var diff3Node = recurseDiff
                                ? DiffNode(null, asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                                : new Diff3Node(null, asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset1And2
                        };
                        AddItem(diff3, diff3Node, change.From1.From != 0);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.Conflict:
                    int baseIndex  = change.Base.IsValid ? change.Base.From : -1;
                    int from1Index = change.From1.IsValid ? change.From1.From : -1;
                    int from2Index = change.From2.IsValid ? change.From2.From : -1;

                    // If there are changes only from 1 or 2 or base.Length == list1.Length == list2.Length, then try to make a diff per item
                    // else output the conflict as a full conflict
                    bool tryResolveConflict = false;
                    if (baseIndex >= 0)
                    {
                        if (from1Index >= 0 && from2Index >= 0)
                        {
                            if ((change.Base.Length == change.From1.Length && change.Base.Length == change.From2.Length) ||
                                (change.From1.Length == change.From2.Length))
                            {
                                tryResolveConflict = true;
                            }
                        }
                        else if (from1Index >= 0)
                        {
                            tryResolveConflict = change.Base.Length == change.From1.Length;
                        }
                        else if (from2Index >= 0)
                        {
                            tryResolveConflict = change.Base.Length == change.From2.Length;
                        }
                        else
                        {
                            tryResolveConflict = true;
                        }
                    }

                    // Iterate on items
                    while ((baseIndex >= 0 && baseItems.Count > 0) || (from1Index >= 0 && asset1Items.Count > 0) || (from2Index >= 0 && asset2Items.Count > 0))
                    {
                        var baseItem   = GetSafeFromList(baseItems, ref baseIndex, ref change.Base);
                        var asset1Item = GetSafeFromList(asset1Items, ref from1Index, ref change.From1);
                        var asset2Item = GetSafeFromList(asset2Items, ref from2Index, ref change.From2);

                        var diff3Node = tryResolveConflict || recurseDiff?
                                        DiffNode(baseItem, asset1Item, asset2Item) :
                                            new Diff3Node(baseItem, asset1Item, asset2Item)
                        {
                            ChangeType = Diff3ChangeType.Conflict
                        };
                        AddItem(diff3, diff3Node, true);
                    }
                    break;
                }
            }

            // Any missing item? (we can detect this only at the end)
            var newItemCount = diff3.Items != null ? diff3.Items.Count : 0;

            if (asset1Items.Count != newItemCount)
            {
                diff3.ChangeType = Diff3ChangeType.Children;
            }
        }
Ejemplo n.º 18
0
        private void DiffCollection(Diff3Node diff3, DataVisitNode baseNode, DataVisitNode asset1Node, DataVisitNode asset2Node)
        {
            var baseItems   = baseNode != null ? baseNode.Items ?? EmptyNodes : EmptyNodes;
            var asset1Items = asset1Node != null ? asset1Node.Items ?? EmptyNodes : EmptyNodes;
            var asset2Items = asset2Node != null ? asset2Node.Items ?? EmptyNodes : EmptyNodes;

            equalityComparer.Reset();
            var changes = Diff3.Compare(baseItems, asset1Items, asset2Items, equalityComparer);

            foreach (var change in changes)
            {
                switch (change.ChangeType)
                {
                case SharpDiff.Diff3ChangeType.Equal:
                    for (int i = 0; i < change.Base.Length; i++)
                    {
                        var diff3Node = new Diff3Node(baseItems[change.Base.From + i], asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.None
                        };
                        AddItem(diff3, diff3Node);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom1:
                    for (int i = 0; i < change.From1.Length; i++)
                    {
                        var diff3Node = new Diff3Node(null, asset1Items[change.From1.From + i], null)
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset1
                        };
                        AddItem(diff3, diff3Node);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom2:
                    for (int i = 0; i < change.From2.Length; i++)
                    {
                        var diff3Node = new Diff3Node(null, null, asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset2
                        };
                        AddItem(diff3, diff3Node);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.MergeFrom1And2:
                    for (int i = 0; i < change.From2.Length; i++)
                    {
                        var diff3Node = new Diff3Node(null, asset1Items[change.From1.From + i], asset2Items[change.From2.From + i])
                        {
                            ChangeType = Diff3ChangeType.MergeFromAsset1And2
                        };
                        AddItem(diff3, diff3Node);
                    }
                    break;

                case SharpDiff.Diff3ChangeType.Conflict:
                    int baseIndex  = change.Base.IsValid ? change.Base.From : -1;
                    int from1Index = change.From1.IsValid ? change.From1.From : -1;
                    int from2Index = change.From2.IsValid ? change.From2.From : -1;

                    // If there are changes only from 1 or 2 or base.Length == list1.Length == list2.Length, then try to make a diff per item
                    // else output the conflict as a full conflict
                    bool tryResolveConflict = false;
                    if (baseIndex >= 0)
                    {
                        if (from1Index >= 0 && from2Index >= 0)
                        {
                            if ((change.Base.Length == change.From1.Length && change.Base.Length == change.From2.Length) ||
                                (change.From1.Length == change.From2.Length))
                            {
                                tryResolveConflict = true;
                            }
                        }
                        else if (from1Index >= 0)
                        {
                            tryResolveConflict = change.Base.Length == change.From1.Length;
                        }
                        else if (from2Index >= 0)
                        {
                            tryResolveConflict = change.Base.Length == change.From2.Length;
                        }
                        else
                        {
                            tryResolveConflict = true;
                        }
                    }

                    // Iterate on items
                    while ((baseIndex >= 0 && baseItems.Count > 0) || (from1Index >= 0 && asset1Items.Count > 0) || (from2Index >= 0 && asset2Items.Count > 0))
                    {
                        var baseItem   = GetSafeFromList(baseItems, ref baseIndex, ref change.Base);
                        var asset1Item = GetSafeFromList(asset1Items, ref from1Index, ref change.From1);
                        var asset2Item = GetSafeFromList(asset2Items, ref from2Index, ref change.From2);

                        var diff3Node = tryResolveConflict ?
                                        DiffNode(baseItem, asset1Item, asset2Item) :
                                        new Diff3Node(baseItem, asset1Item, asset2Item)
                        {
                            ChangeType = Diff3ChangeType.Conflict
                        };
                        AddItem(diff3, diff3Node);
                    }
                    break;
                }
            }

            // Order by descending index
            if (diff3.Items != null)
            {
                diff3.Items.Sort((left, right) =>
                {
                    int leftAsset1Index  = left.Asset1Node != null ? ((DataVisitListItem)left.Asset1Node).Index : -1;
                    int rightAsset1Index = right.Asset1Node != null ? ((DataVisitListItem)right.Asset1Node).Index : -1;

                    return(rightAsset1Index.CompareTo(leftAsset1Index));
                });
            }
        }