Exemplo n.º 1
0
        public void Align_WithNullElements()
        {
            var collection1 = new[]
            {
                "Line 1", "Line 2", null, "Line 3", "Line 4",
            };

            var collection2 = new[]
            {
                "Line 1", null, "Line 2", "Line 4",
            };

            DiffSection[] sections = Diff.CalculateSections(collection1, collection2).ToArray();
            var           elements = Diff.AlignElements(collection1, collection2, sections, new StringSimilarityDiffElementAligner());

            CollectionAssert.AreEqual(new[]
            {
                new DiffElement <string>("Line 1", "Line 1", DiffOperation.Match),
                new DiffElement <string>(Option <string> .None, null, DiffOperation.Insert),
                new DiffElement <string>("Line 2", "Line 2", DiffOperation.Match),
                new DiffElement <string>(null, Option <string> .None, DiffOperation.Delete),
                new DiffElement <string>("Line 3", Option <string> .None, DiffOperation.Delete),
                new DiffElement <string>("Line 4", "Line 4", DiffOperation.Match),
            }, elements);
        }
Exemplo n.º 2
0
        private IDisposable BindFromSource <TModel>(TModel model, Expression <Func <TModel, SelectionData> > propertyExpr, Func <IDisposable> startTransaction)
        {
            return(model.WhenAnyValue(propertyExpr)
                   .Buffer(2, 1)
                   .Where(b => b.Count == 2)
                   .Select(b =>
            {
                var previous = b[0].ObjectIds.ToList();
                var current = b[1].ObjectIds.ToList();
                var sections = Diff.CalculateSections(previous, current);
                var alignedElements = Diff
                                      .AlignElements(previous, current, sections,
                                                     new BasicInsertDeleteDiffElementAligner <SelectionData.ObjectId>())
                                      .ToList();
                var oldObjectIds = alignedElements
                                   .Where(e => e.Operation == DiffOperation.Delete || e.Operation == DiffOperation.Replace)
                                   .Select(e => e.ElementFromCollection1.Value);

                var newObjectIds = alignedElements
                                   .Where(e => e.Operation == DiffOperation.Insert || e.Operation == DiffOperation.Replace)
                                   .Select(e => e.ElementFromCollection2.Value);

                return new { oldSelectionData = b[0], oldObjectIds, newSelectionData = b[1], newObjectIds };
            })
                   .Subscribe(o =>
            {
                using (startTransaction())
                {
                    ModelDoc.ClearSelection(o.oldSelectionData.WithObjectIds(o.oldObjectIds));
                    ModelDoc.AddSelection(o.newSelectionData.WithObjectIds(o.newObjectIds));
                }
            }));
        }
Exemplo n.º 3
0
        public void BasicReplaceInsertDeleteDiffElementAlignerTestCases(string s1, string s2, string expected)
        {
            var sections = Diff.CalculateSections(s1.ToCharArray(), s2.ToCharArray());
            var elements = Diff.AlignElements(s1.ToCharArray(), s2.ToCharArray(), sections, new BasicReplaceInsertDeleteDiffElementAligner <char>());
            var output   = GetElementOperationsAsAString(elements);

            Assert.That(output, Is.EqualTo(expected));
        }
Exemplo n.º 4
0
        public void AlignElements_NullAligner_ThrowsArgumentNullException()
        {
            IList <int> collection1 = new int[0];
            IList <int> collection2 = new int[0];
            IEnumerable <DiffSection> diffSections = new DiffSection[0];
            IDiffElementAligner <int> aligner      = null;

            Assert.Throws <ArgumentNullException>(() => Diff.AlignElements(collection1, collection2, diffSections, aligner));
        }
Exemplo n.º 5
0
        public static bool Compare(string input1, string input2, StringWriter diff, Func <string, string> normalizeLine, string[] definedSymbols = null)
        {
            var collection1  = NormalizeAndSplitCode(input1, definedSymbols ?? new string[0]);
            var collection2  = NormalizeAndSplitCode(input2, definedSymbols ?? new string[0]);
            var diffSections = DiffLib.Diff.CalculateSections(
                collection1, collection2, new CodeLineEqualityComparer(normalizeLine)
                );
            var alignedDiff = Diff.AlignElements(collection1, collection2, diffSections, new StringSimilarityDiffElementAligner());

            bool result = true, ignoreChange;

            int line1 = 0, line2 = 0;

            foreach (var change in alignedDiff)
            {
                switch (change.Operation)
                {
                case DiffOperation.Match:
                    diff.Write("{0,4} {1,4} ", ++line1, ++line2);
                    diff.Write("  ");
                    diff.WriteLine(change.ElementFromCollection1.Value);
                    break;

                case DiffOperation.Insert:
                    diff.Write("     {1,4} ", line1, ++line2);
                    result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection2.Value);
                    diff.Write(ignoreChange ? "    " : " +  ");
                    diff.WriteLine(change.ElementFromCollection2.Value);
                    break;

                case DiffOperation.Delete:
                    diff.Write("{0,4}      ", ++line1, line2);
                    result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection1.Value);
                    diff.Write(ignoreChange ? "    " : " -  ");
                    diff.WriteLine(change.ElementFromCollection1.Value);
                    break;

                case DiffOperation.Modify:
                case DiffOperation.Replace:
                    diff.Write("{0,4}      ", ++line1, line2);
                    result = false;
                    diff.Write("(-) ");
                    diff.WriteLine(change.ElementFromCollection1.Value);
                    diff.Write("     {1,4} ", line1, ++line2);
                    diff.Write("(+) ");
                    diff.WriteLine(change.ElementFromCollection2.Value);
                    break;
                }
            }

            return(result);
        }
 public static IObservable <List <DiffElement <T> > > ChangesObservable <T>(this ICompositeList <T> source, IEqualityComparer <T> comparer = null)
 {
     return(source
            .Items
            .StartWith(ImmutableList <T> .Empty)
            .Buffer(2, 1).Where(b => b.Count == 2)
            .Select(b =>
     {
         var sections = Diff.CalculateSections(b[0], b[1], comparer);
         var alignment = Diff.AlignElements
                             (b[0], b[1], sections, new BasicReplaceInsertDeleteDiffElementAligner <T>());
         return alignment.ToList();
     }));
 }
Exemplo n.º 7
0
        public void ElementSimilarityDiffElementAlignerTestCases(string s1, string s2, string expected)
        {
            double aligner(char element1, char element2)
            {
                if (element1 == element2)
                {
                    return(1.0);
                }

                if (char.ToUpper(element1) == char.ToUpper(element2))
                {
                    return(0.75);
                }

                return(0.0);
            }

            var sections = Diff.CalculateSections(s1.ToCharArray(), s2.ToCharArray());
            var elements = Diff.AlignElements(s1.ToCharArray(), s2.ToCharArray(), sections, new ElementSimilarityDiffElementAligner <char>(aligner));
            var output   = GetElementOperationsAsAString(elements);

            Assert.That(output, Is.EqualTo(expected));
        }
Exemplo n.º 8
0
        public static bool Compare(string input1, string input2, StringWriter diff, Func <string, string> normalizeLine, string[] definedSymbols = null)
        {
            var collection1  = NormalizeAndSplitCode(input1, definedSymbols ?? new string[0]);
            var collection2  = NormalizeAndSplitCode(input2, definedSymbols ?? new string[0]);
            var diffSections = DiffLib.Diff.CalculateSections(
                collection1, collection2, new CodeLineEqualityComparer(normalizeLine)
                );
            var alignedDiff = Diff.AlignElements(collection1, collection2, diffSections, new StringSimilarityDiffElementAligner());

            bool      result = true;
            int       line1 = 0, line2 = 0;
            const int contextSize        = 10;
            int       consecutiveMatches = contextSize;
            var       hiddenMatches      = new List <string>();

            foreach (var change in alignedDiff)
            {
                switch (change.Operation)
                {
                case DiffOperation.Match:
                    AppendMatch($"{++line1,4} {++line2,4} ", change.ElementFromCollection1.Value);
                    break;

                case DiffOperation.Insert:
                    string pos = $"     {++line2,4} ";
                    if (ShouldIgnoreChange(change.ElementFromCollection2.Value))
                    {
                        AppendMatch(pos, change.ElementFromCollection2.Value);
                    }
                    else
                    {
                        AppendDelta(pos, " + ", change.ElementFromCollection2.Value);
                        result = false;
                    }
                    break;

                case DiffOperation.Delete:
                    pos = $"{++line1,4}      ";
                    if (ShouldIgnoreChange(change.ElementFromCollection1.Value))
                    {
                        AppendMatch(pos, change.ElementFromCollection1.Value);
                    }
                    else
                    {
                        AppendDelta(pos, " - ", change.ElementFromCollection1.Value);
                        result = false;
                    }
                    break;

                case DiffOperation.Modify:
                case DiffOperation.Replace:
                    AppendDelta($"{++line1,4}      ", "(-)", change.ElementFromCollection1.Value);
                    AppendDelta($"     {++line2,4} ", "(+)", change.ElementFromCollection2.Value);
                    result = false;
                    break;
                }
            }
            if (hiddenMatches.Count > 0)
            {
                diff.WriteLine("  ...");
            }

            return(result);

            void AppendMatch(string pos, string code)
            {
                consecutiveMatches++;
                if (consecutiveMatches > contextSize)
                {
                    // hide this match
                    hiddenMatches.Add(pos + "    " + code);
                }
                else
                {
                    diff.WriteLine(pos + "    " + code);
                }
            }

            void AppendDelta(string pos, string changeType, string code)
            {
                consecutiveMatches = 0;
                if (hiddenMatches.Count > contextSize)
                {
                    diff.WriteLine("  ...");
                }
                for (int i = Math.Max(0, hiddenMatches.Count - contextSize); i < hiddenMatches.Count; i++)
                {
                    diff.WriteLine(hiddenMatches[i]);
                }
                hiddenMatches.Clear();
                diff.WriteLine(pos + changeType + " " + code);
            }
        }
Exemplo n.º 9
0
        public static bool Compare(string input1, string input2, StringWriter diff)
        {
            List <string> input1List = NormalizeAndSplitCode(input1).ToList();
            List <string> input2List = NormalizeAndSplitCode(input2).ToList();

            IEnumerable <DiffSection>           diffSections = Diff.CalculateSections(input1List, input2List, new CodeLineEqualityComparer());
            IEnumerable <DiffElement <string> > diffElements = Diff.AlignElements(
                input1List,
                input2List,
                diffSections,
                new StringSimilarityDiffElementAligner());

            bool result = true;
            int  line1 = 0, line2 = 0;

            foreach (DiffElement <string> change in diffElements)
            {
                bool ignoreChange;
                switch (change.Operation)
                {
                case DiffOperation.Match:
                    diff.Write("{0,4} {1,4} ", ++line1, ++line2);
                    diff.Write("  ");
                    diff.WriteLine(change.ElementFromCollection1);
                    break;

                case DiffOperation.Insert:
                    diff.Write("     {1,4} ", line1, ++line2);
                    result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection2.Value);
                    diff.Write(ignoreChange ? "    " : " +  ");
                    diff.WriteLine(change.ElementFromCollection2);
                    break;

                case DiffOperation.Delete:
                    diff.Write("{0,4}      ", ++line1, line2);
                    result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection1.Value);
                    diff.Write(ignoreChange ? "    " : " -  ");
                    diff.WriteLine(change.ElementFromCollection1);
                    break;

                case DiffOperation.Replace:
                    diff.Write("{0,4}      ", ++line1, line2);
                    result = false;
                    diff.Write("(-) ");
                    diff.WriteLine(change.ElementFromCollection1);
                    diff.Write("     {1,4} ", line1, ++line2);
                    diff.Write("(+) ");
                    diff.WriteLine(change.ElementFromCollection2);
                    break;

                case DiffOperation.Modify:
                    diff.Write("{0,4}      ", ++line1, line2);
                    result = false;
                    diff.Write("(-) ");
                    diff.WriteLine(change.ElementFromCollection1);
                    diff.Write("     {1,4} ", line1, ++line2);
                    diff.Write("(*) ");
                    diff.WriteLine(change.ElementFromCollection2);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(result);
        }