Example #1
0
 public SplitDiffModel(DiffTextModel sideA, DiffTextModel sideB,
                       List <IAnchorPos> diffAnchors)
 {
     SideA       = sideA;
     SideB       = sideB;
     DiffAnchors = diffAnchors;
 }
Example #2
0
        public void TestUnifiedDiffParsing_AddedRemoved()
        {
            string inputA =
                "This is a test file!\n" +
                "Added another line to test file\n" +
                "Adding a third line to test file";

            string inputB =
                "This is a test file!\n" +
                "Adding a third line to test file\n" +
                "Adding a fourth line to test file";

            List <Diff.Diff> diff      = DiffFactory.GenerateDiffCache(inputA, inputB);
            DiffTextModel    textModel = DiffFactory.GenerateUnifiedDiff(diff);

            Assert.IsTrue(textModel.LineCount == 5);

            DiffTextLine removedLine = textModel.GetLine(1) as DiffTextLine;

            Assert.IsTrue(removedLine.ToString() == "Added another line to test file");
            Assert.IsTrue(removedLine.BeforeLineNo == 2);
            Assert.IsTrue(removedLine.ChangeType == DiffLineType.Remove);

            DiffTextLine addedLine = textModel.GetLine(3) as DiffTextLine;

            Assert.IsTrue(addedLine.ToString() == "Adding a third line to test file");
            Assert.IsTrue(addedLine.BeforeLineNo == -1);
            Assert.IsTrue(addedLine.LineNo == 2);
            Assert.IsTrue(addedLine.ChangeType == DiffLineType.Insert);
        }
Example #3
0
        public static SplitDiffModel GenerateSplitDiff(List <Diff> diffs)
        {
            // Generate the model
            List <DiffTextLine> sideABuffer = new List <DiffTextLine>();
            List <DiffTextLine> sideBBuffer = new List <DiffTextLine>();

            DiffTextModel sideAModel = new DiffTextModel();
            DiffTextModel sideBModel = new DiffTextModel();

            List <IAnchorPos> diffAnchors = new List <IAnchorPos>();

            foreach (Diff d in diffs)
            {
                bool hasAddedDiffAnchor = false;
                foreach (string line in d.text.SplitToLines())
                {
                    switch (d.operation)
                    {
                    case Operation.DELETE:
                    {
                        // removed on left
                        DiffTextLine newLine = new DiffTextLine(line, DiffLineType.Remove);
                        sideABuffer.Add(newLine);

                        if (!hasAddedDiffAnchor)
                        {
                            diffAnchors.Add(sideAModel.CreateAnchor(newLine));
                            hasAddedDiffAnchor = true;
                        }
                    }
                    break;

                    case Operation.EQUAL:
                    {
                        sideABuffer.Add(new DiffTextLine(line, DiffLineType.Unchanged));
                        sideBBuffer.Add(new DiffTextLine(line, DiffLineType.Unchanged));
                    }
                    break;

                    case Operation.INSERT:
                    {
                        // added on the right
                        DiffTextLine newLine = new DiffTextLine(line, DiffLineType.Insert);
                        sideBBuffer.Add(newLine);

                        if (!hasAddedDiffAnchor)
                        {
                            diffAnchors.Add(sideBModel.CreateAnchor(newLine));
                            hasAddedDiffAnchor = true;
                        }
                    }
                    break;
                    }
                }
            }

            int leftLineNo  = 1;
            int rightLineNo = 1;

            int lineNoCount = Math.Max(sideABuffer.Count, sideBBuffer.Count);

            DiffTextLine leftLine      = null;
            DiffTextLine rightLine     = null;
            DiffTextLine emptyTextLine = new DiffTextLine("", DiffLineType.Empty);

            // Make sure we visit every line
            for (int i = 0; i < lineNoCount; i++)
            {
                leftLine  = leftLineNo <= sideABuffer.Count ? sideABuffer[leftLineNo - 1] : null;
                rightLine = rightLineNo <= sideBBuffer.Count ? sideBBuffer[rightLineNo - 1] : null;

                if (leftLine == null && rightLine != null)
                {
                    rightLine.LineNo = rightLineNo;
                    sideBModel.InsertLine(rightLine);
                    rightLineNo++;
                    continue;
                }

                if (leftLine != null && rightLine == null)
                {
                    leftLine.LineNo = leftLineNo;
                    sideAModel.InsertLine(leftLine);
                    leftLineNo++;
                    continue;
                }

                if (leftLine.ChangeType == DiffLineType.Unchanged &&
                    rightLine.ChangeType == DiffLineType.Unchanged)
                {
                    leftLine.LineNo  = leftLineNo;
                    rightLine.LineNo = rightLineNo;

                    // easymode: unchanged lines
                    sideAModel.InsertLine(leftLine);
                    sideBModel.InsertLine(rightLine);

                    leftLineNo++;
                    rightLineNo++;
                }
                else if (leftLine.ChangeType == DiffLineType.Remove &&
                         rightLine.ChangeType == DiffLineType.Insert)
                {
                    leftLine.LineNo  = leftLineNo;
                    rightLine.LineNo = rightLineNo;

                    // removed left, added right, so it's 1-to-1
                    sideAModel.InsertLine(leftLine);
                    sideBModel.InsertLine(rightLine);

                    leftLineNo++;
                    rightLineNo++;
                }
                else if (leftLine.ChangeType == DiffLineType.Remove &&
                         rightLine.ChangeType == DiffLineType.Unchanged)
                {
                    leftLine.LineNo = leftLineNo;

                    // removed on left, but wasn't replaced with anything on right
                    sideAModel.InsertLine(leftLine);
                    sideBModel.InsertLine(emptyTextLine);

                    leftLineNo++; // only advance the left line counter because empty lines don't count
                }
                else if (leftLine.ChangeType == DiffLineType.Unchanged &&
                         rightLine.ChangeType == DiffLineType.Insert)
                {
                    rightLine.LineNo = rightLineNo;

                    // added on right, but didn't have existing change on left
                    sideAModel.InsertLine(emptyTextLine);
                    sideBModel.InsertLine(rightLine);

                    rightLineNo++; // only advance the right line counter because empty lines don't count
                }
            }

            return(new SplitDiffModel(sideAModel, sideBModel, diffAnchors));
        }