private void Form1_Load(object sender, System.EventArgs e) { var d = new Differ(); var inlineBuilder = new SideBySideDiffBuilder(d); var diffmodel = inlineBuilder.BuildDiffModel(OldText, NewText); webBrowser1.DocumentText = GetHtml2Render(diffmodel.OldText); webBrowser2.DocumentText = GetHtml2Render(diffmodel.NewText); webBrowser1.Refresh(); webBrowser2.Refresh(); }
public void Will_throw_is_OldText_is_null() { var differ = new Mock <IDiffer>(); var builder = new SideBySideDiffBuilder(differ.Object); var ex = Record.Exception(() => builder.BuildDiffModel(null, "asd")); Assert.IsType <ArgumentNullException>(ex); var an = (ArgumentNullException)ex; Assert.Equal("oldText", an.ParamName); }
public List <string> GetDiffer(string OldText, string NewText) { List <string> Diff = new List <string>(); var inlineBuilder = new SideBySideDiffBuilder(new Differ()); var diffmodel = inlineBuilder.BuildDiffModel(OldText, NewText); Diff.Add(Differ(diffmodel.OldText)); Diff.Add(Differ(diffmodel.NewText)); return(Diff); }
public void Will_not_ignore_word_white_space() { string oldText = "My name is matt"; string newText = "My name is matt"; var sideBySideDiffBuilder = new SideBySideDiffBuilder(); var sideBySideDiffModel = sideBySideDiffBuilder.BuildDiffModel(oldText, newText, false); Assert.NotNull(sideBySideDiffModel); Assert.Single(sideBySideDiffModel.OldText.Lines); Assert.Single(sideBySideDiffModel.NewText.Lines); Assert.True(sideBySideDiffModel.OldText.HasDifferences); Assert.True(sideBySideDiffModel.NewText.HasDifferences); }
private void ShowDiffs(string oldText, string newText) { IDiffer differ = new Differ(); DiffResult diffResult = differ.CreateLineDiffs(oldText, newText, false); ISideBySideDiffBuilder diffBuilder = new SideBySideDiffBuilder(differ); SideBySideDiffModel model = diffBuilder.BuildDiffModel(oldText, newText); this.DisplayDiffPiece(this.rtbSnapshotLeft, model.OldText.Lines, string.IsNullOrEmpty(newText)); this.DisplayDiffPiece(this.rtbSnapshotRight, model.NewText.Lines, false); }
internal static string[] DoSideBySideDiff(string SourceText, string DestinationText) { string[] Result = new string[3]; Differ DiffMaker = new Differ(); SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker); SideBySideDiffModel SideBySideDiffResult = SideBySideDiffer.BuildDiffModel(SourceText, DestinationText); int DiffLevel = IronDiffer.GetLevel(SideBySideDiffResult, SourceText, DestinationText); Result[0] = FullDiff(SideBySideDiffResult.OldText.Lines); Result[1] = FullDiff(SideBySideDiffResult.NewText.Lines); Result[2] = DiffLevel.ToString(); return(Result); }
public SideBySideDiff CompareString(string generatedFile, string referenceFile, string filenameA, string filenameB) { var generated = generatedFile.TrimEnd(); var reference = referenceFile.TrimEnd(); var diffBuilder = new SideBySideDiffBuilder(new Differ()); var diff = diffBuilder.BuildDiffModel(generated, reference, true); return(new SideBySideDiff { A = filenameA, B = filenameB, Diff = diff }); }
private void ShowChanges(int leftIndex, int rightIndex) { if (InvokeRequired) { Invoke(new Action <int, int>(ShowChanges), leftIndex, rightIndex); return; } var left = leftIndex == -1 ? string.Empty : revisionProvider.Revisions[leftIndex].GetContent(); var right = revisionProvider.Revisions[rightIndex].GetContent(); var builder = new SideBySideDiffBuilder(new Differ()); var model = builder.BuildDiffModel(left, right); ChangeStartPositions = ModelToTextBox(model.OldText, rtbLeft, rtbLeftNumbers); ModelToTextBox(model.NewText, rtbRight, rtbRightNumbers); lblChanges.Text = ChangeStartPositions.Count + " change" + (ChangeStartPositions.Count == 1 ? string.Empty : "s"); }
private static void InitializeChildRows(CremaDataRow diffRow1, CremaDataRow diffRow2, CremaDataRow dataRow1, CremaDataRow dataRow2, CremaDataTable diffChildTable1, CremaDataTable diffChildTable2, CremaDataTable childTable1, CremaDataTable childTable2) { var emptyRows = new CremaDataRow[] { }; var inlineBuilder = new SideBySideDiffBuilder(new Differ()); var childRows1 = dataRow1 != null && childTable1 != null?dataRow1.GetChildRows(childTable1) : emptyRows; var childRows2 = dataRow2 != null && childTable2 != null?dataRow2.GetChildRows(childTable2) : emptyRows; var rowText1 = GetString(childRows1); var rowText2 = GetString(childRows2); var rowDiff = inlineBuilder.BuildDiffModel(rowText1, rowText2); FillChildRow(diffRow1, dataRow1, diffChildTable1, childTable1, childRows1, rowDiff.OldText.Lines); FillChildRow(diffRow2, dataRow2, diffChildTable2, childTable2, childRows2, rowDiff.NewText.Lines); }
public void Will_pass_correct_word_separators_to_constructor_to_create_word_diff() { string text = "a\nb\nc\nd\n\n"; string[] textLines = { "a", "b", "c", "d", "" }; char[] chars = { ' ', '.' }; var builder = new SideBySideDiffBuilder(new Differ(), chars); builder.BuildDiffModel(text, text); Assert.Equal(builder.WordSeparaters.Length, chars.Length); foreach (var c in builder.WordSeparaters) { Assert.Contains(c, chars); } }
private void compareTreeViewStrings(MyTreeView newTreeView, string newText, MyTreeView oldTreeView, string oldText) { ISideBySideDiffBuilder diffBuilder = new SideBySideDiffBuilder(new Differ()); SideBySideDiffModel sideBySideModel = diffBuilder.BuildDiffModel(oldText, newText); newTreeView.Nodes.Clear(); oldTreeView.Nodes.Clear(); TreeNode newParentNode = newTreeView.Nodes.Add(sideBySideModel.NewText.Lines[0].Text); TreeNode oldParentNode = oldTreeView.Nodes.Add(sideBySideModel.OldText.Lines[0].Text); colorTreeView(newParentNode.FullPath, newParentNode, sideBySideModel.NewText.Lines, sideBySideModel.OldText.Lines, 1, true); colorTreeView(oldParentNode.FullPath, oldParentNode, sideBySideModel.OldText.Lines, sideBySideModel.NewText.Lines, 1, false); newTreeView.AddLinkedTreeView(oldTreeView); }
public void ThenCompareWithDiffPlexTheFollowngFilesVs(string fileOne, string fileTwo) { string str1 = FileStorage.ReadFileText(fileOne.StrVar()); string str2 = FileStorage.ReadFileText(fileTwo.StrVar()); var d1 = new Differ(); var sidebYSide = new SideBySideDiffBuilder(d1); var result1 = sidebYSide.BuildDiffModel(str1, str2); foreach (var line in result1.NewText.Lines) { if (line.Type == ChangeType.Modified) { Assert.Fail(line.Position + " " + line.Text); } } }
public void Report(string approved, string received) { var approvedText = File.ReadAllText(approved); var receivedText = File.ReadAllText(received); var diffBuilder = new SideBySideDiffBuilder(new Differ()); var diff = diffBuilder.BuildDiffModel(approvedText, receivedText); var sb = new StringBuilder() .AppendLine($"<<<<<<<<< {Path.GetFileName(approved)}") .AppendDiff(diff.OldText) .AppendLine("=========") .AppendDiff(diff.NewText) .Append($">>>>>>>>> {Path.GetFileName(received)}"); //_out.WriteLine(sb.ToString()); throw new ApiNotApprovedException(sb.ToString()); }
public ActionResult Index(int id, List <int> grSel) { var db = new ZkDataContext(); var post = db.ForumPosts.Find(id); string txt1 = ""; string txt2 = ""; if (grSel != null && grSel.Any()) { if (grSel.Count > 1) { txt1 = db.ForumPostEdits.Find(grSel.Min())?.NewText; txt2 = db.ForumPostEdits.Find(grSel.Max())?.NewText; } else { var edit = db.ForumPostEdits.Find(grSel.First()); if (edit != null) { txt1 = edit.OriginalText; txt2 = edit.NewText; } } var sd = new SideBySideDiffBuilder(new Differ()); ViewBag.DiffModel = sd.BuildDiffModel(txt1, txt2); } else { var edit = post.ForumPostEdits.OrderByDescending(x => x.ForumPostEditID).FirstOrDefault(); if (edit != null) { var sd = new SideBySideDiffBuilder(new Differ()); ViewBag.DiffModel = sd.BuildDiffModel(edit.OriginalText, edit.NewText); } } return(View("PostHistoryIndex", post)); }
public void Will_build_diffModel_for_partially_different_lines() { string textOld = "m is h"; string textNew = "m ai is n h"; string[] textLinesOld = { "m is h" }; string[] textLinesNew = { "m ai is n h" }; var differ = new Mock <IDiffer>(); differ.Setup(x => x.CreateDiffs(textOld, textNew, true, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult(textLinesOld, textLinesNew, new List <DiffBlock> { new DiffBlock(0, 1, 0, 1) })); differ.Setup(x => x.CreateDiffs(It.IsAny <string>(), It.IsAny <string>(), false, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult( new[] { "m ", "is ", "h" }, new[] { "m ", "ai ", "is ", "n ", "h" }, new List <DiffBlock> { new DiffBlock(1, 0, 1, 1), new DiffBlock(3, 0, 3, 1) })); var builder = new SideBySideDiffBuilder(differ.Object); var bidiff = builder.BuildDiffModel(textOld, textNew); Assert.NotNull(bidiff); Assert.Single(bidiff.OldText.Lines); Assert.Single(bidiff.NewText.Lines); Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[0].SubPieces[0].Type); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[0].SubPieces[1].Type); Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[0].SubPieces[2].Type); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[0].SubPieces[3].Type); Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[0].SubPieces[4].Type); Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[0].SubPieces[0].Type); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[0].SubPieces[1].Type); Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[0].SubPieces[2].Type); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[0].SubPieces[3].Type); Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[0].SubPieces[4].Type); Assert.True(bidiff.OldText.HasDifferences && bidiff.NewText.HasDifferences); }
public virtual ActionResult Diff(string folderName, string parentFolder, string uuid, string version) { TextFolder textFolder = new TextFolder(Repository, folderName).AsActual(); var schema = textFolder.GetSchema().AsActual(); var versions = version.Split(','); var v1 = int.Parse(versions[0]); var v2 = int.Parse(versions[1]); var textContent = schema.CreateQuery().WhereEquals("UUID", uuid).FirstOrDefault(); var version1 = VersionManager.GetVersion(textContent, v1); var version1Content = new TextContent(version1.TextContent); var version2 = VersionManager.GetVersion(textContent, v2); var version2Content = new TextContent(version2.TextContent); var sideBySideDiffBuilder = new SideBySideDiffBuilder(new Differ()); var model = new TextContentDiffModel() { UUID = uuid, Version1Name = v1, Version2Name = v2 }; foreach (var k in textContent.Keys) { var version1Text = version1Content[k] != null ? version1Content[k].ToString() : ""; var version2Text = version2Content[k] != null ? version2Content[k].ToString() : ""; var diffModel = sideBySideDiffBuilder.BuildDiffModel(version1Text, version2Text); model.Version1.Add(k, diffModel.OldText); model.Version2.Add(k, diffModel.NewText); } return(View(model)); }
public void Will_build_diffModel_when_oldText_is_empty() { string textOld = ""; string textNew = "z\ny\nx\nw\n"; string[] textLinesOld = {}; string[] textLinesNew = { "z", "y" }; var differ = new Mock <IDiffer>(); differ.Setup(x => x.CreateDiffs(textOld, textNew, true, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult(textLinesOld, textLinesNew, new List <DiffBlock> { new DiffBlock(0, 0, 0, 2) })); differ.Setup(x => x.CreateDiffs(It.IsAny <string>(), It.IsAny <string>(), false, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult(new string[0], new string[0], new List <DiffBlock>())); var builder = new SideBySideDiffBuilder(differ.Object); var bidiff = builder.BuildDiffModel(textOld, textNew); Assert.NotNull(bidiff); Assert.Equal(2, bidiff.OldText.Lines.Count); Assert.Equal(2, bidiff.NewText.Lines.Count); for (int j = 0; j < textLinesNew.Length; j++) { Assert.Equal(textLinesNew[j], bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[j].Type); Assert.Equal(j + 1, bidiff.NewText.Lines[j].Position); Assert.Null(bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[j].Type); Assert.False(bidiff.OldText.Lines[j].Position.HasValue); } Assert.True(bidiff.OldText.HasDifferences && bidiff.NewText.HasDifferences); }
public static IEnumerable <FileDifferences> CompareFileContent(string oldFileContent, string newFileContent) { if (oldFileContent == null || newFileContent == null) { Trace.WriteLine("One of the file content is null"); return(null); } if (oldFileContent == newFileContent) { Trace.WriteLine("Files are identical"); return(null); } const string matchText = "<tr><th>Coverage:</th><td>0%</td></tr>"; if (oldFileContent.Contains(matchText) && newFileContent.Contains(matchText)) { Trace.WriteLine("Both files have no coverage."); return(null); } oldFileContent = RemoveLineNumbers(oldFileContent); newFileContent = RemoveLineNumbers(newFileContent); SideBySideDiffBuilder sideBySideDiffer = new SideBySideDiffBuilder(new Differ()); SideBySideDiffModel diff = sideBySideDiffer.BuildDiffModel(oldFileContent, newFileContent); DiffPiece[] newLines = diff.NewText.Lines.Where(DoesLineHaveDifferentCoverage).ToArray(); if (!diff.OldText.Lines.Where(DoesLineHaveDifferentCoverage).Concat(newLines).Any()) { Trace.WriteLine("No changes to code coverage"); return(null); } return(AnalyzeDiff(diff, newLines)); }
private void Row_DoubleClick(object sender, MouseButtonEventArgs e) { // execute some code DataGridRow r = (DataGridRow)sender; dynamic i = r.Item; FHXCompareResult rs = i.Value; var diffBuilder = new SideBySideDiffBuilder(new Differ()); if (rs.NewValue == null) { this.tbOld.Document.Blocks.Clear(); this.tbNew.Document.Blocks.Clear(); var p = new Paragraph(); var tr = new TextRange(p.ContentStart, p.ContentEnd); tr.Text = rs.OldValue; this.tbOld.Document.Blocks.Add(p); } else { var diff = diffBuilder.BuildDiffModel(rs.OldValue, rs.NewValue); RichTextBox[] tb = new RichTextBox[2] { this.tbOld, this.tbNew }; List <DiffPiece>[] t = new List <DiffPiece>[2] { diff.OldText.Lines, diff.NewText.Lines }; for (int j = 0; j < 2; j++) { tb[j].Document.Blocks.Clear(); foreach (DiffPiece line in t[j]) { var p = new Paragraph(); p.Margin = new Thickness(0); TextRange tr; tr = new TextRange(p.ContentStart, p.ContentEnd); switch (line.Type) { case ChangeType.Inserted: tr.Text = line.Text; tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.LightGreen); break; case ChangeType.Deleted: tr.Text = line.Text; tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.LightPink); break; case ChangeType.Modified: tr.Text = line.Text; tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.Goldenrod); break; case ChangeType.Imaginary: tr.Text = " "; tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.Gray); break; case ChangeType.Unchanged: tr.Text = line.Text; tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black); break; default: tr.Text = line.Text; tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White); break; } tb[j].Document.Blocks.Add(p); } } } }
public void Will_build_diffModel_for_partially_different_documents() { string textOld = "1\n2\na\nb\nc\nd\n\n"; string textNew = "1\n2\nz\ny\nx\nw\n"; string[] textLinesOld = { "1", "2", "a", "b", "c", "d", "" }; string[] textLinesNew = { "1", "2", "z", "y", "x", "w" }; var differ = new Mock <IDiffer>(); differ.Setup(x => x.CreateLineDiffs(textOld, textNew, true)) .Returns(new DiffResult(textLinesOld, textLinesNew, new List <DiffBlock> { new DiffBlock(2, 5, 2, 4) })); differ.Setup(x => x.CreateWordDiffs(It.IsAny <string>(), It.IsAny <string>(), false, It.IsAny <char[]>())) .Returns(new DiffResult(new string[0], new string[0], new List <DiffBlock>())); var builder = new SideBySideDiffBuilder(differ.Object); var bidiff = builder.BuildDiffModel(textOld, textNew); Assert.NotNull(bidiff); Assert.Equal(7, bidiff.OldText.Lines.Count); Assert.Equal(7, bidiff.NewText.Lines.Count); int i = 0; for (; i < 2; i++) { Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text); Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[i].Type); Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position); Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text); Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[i].Type); Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position); } for (; i < Math.Min(textLinesOld.Length, textLinesNew.Length); i++) { Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.OldText.Lines[i].Type); Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position); Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.NewText.Lines[i].Type); Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position); } if (textLinesOld.Length < textLinesNew.Length) { for (int j = i; j < textLinesNew.Length; j++) { Assert.Equal(textLinesNew[j], bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[j].Type); Assert.Equal(j + 1, bidiff.NewText.Lines[j].Position); Assert.Null(bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[j].Type); Assert.False(bidiff.OldText.Lines[j].Position.HasValue); } } else { for (int j = i; j < textLinesOld.Length; j++) { Assert.Equal(textLinesOld[j], bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Deleted, bidiff.OldText.Lines[j].Type); Assert.Equal(j + 1, bidiff.OldText.Lines[j].Position); Assert.Null(bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.NewText.Lines[j].Type); Assert.False(bidiff.NewText.Lines[j].Position.HasValue); } } }
private string ConstructEstimateCodeDiff(MethodDefinition method) { var decompilationOutput = new PlainTextOutput(); try { _cSharpDecompiler.DecompileMethod(method, decompilationOutput, _decompilationOptions); } catch { return("\t\tNo decompilation available for mutated version.\n"); } string newText = decompilationOutput.ToString(); var model = _differ.BuildDiffModel(_oldText, newText); string diffOutput = "\t\tApproximate source code difference from IL decompilation:\n"; var lines = new SortedSet <int>(); for (int i = 0; i < Math.Max(model.OldText.Lines.Count, model.NewText.Lines.Count); i++) { if ((i < model.OldText.Lines.Count && model.OldText.Lines[i].Type != ChangeType.Unchanged) || (i < model.NewText.Lines.Count && model.NewText.Lines[i].Type != ChangeType.Unchanged)) { lines.Add(i - 2); lines.Add(i - 1); lines.Add(i); lines.Add(i + 1); lines.Add(i + 2); } } int lastLine = -1; string adds = ""; string takes = ""; foreach (var line in lines) { if (line < 0) { continue; } if (line > lastLine + 1) { diffOutput += string.Format("{1}{2}\t\t@@ {0} @@\n", line, takes, adds); takes = ""; adds = ""; } if (line < model.OldText.Lines.Count) { takes += string.Format("\t\t- {0}\n", (model.OldText.Lines[line].Text ?? "").Replace("\t", " ")); } if (line < model.NewText.Lines.Count) { adds += string.Format("\t\t+ {0}\n", (model.NewText.Lines[line].Text ?? "").Replace("\t", " ")); } lastLine = line; } if (!string.IsNullOrEmpty(adds) || !string.IsNullOrEmpty(takes)) { diffOutput += takes + adds; } return(diffOutput); }
public void Can_compare_whitespace() { string textOld = "1\n 2\n3 \n 4 \n5"; string textNew = "1\n2\n3\n4\n5"; var builder = new SideBySideDiffBuilder(new Differ()); var model = builder.BuildDiffModel(textOld, textNew, ignoreWhitespace: false); Assert.Equal( model.OldText.Lines, new DiffPiece[] { new DiffPiece("1", ChangeType.Unchanged, 1), new DiffPiece(" 2", ChangeType.Modified, 2) { SubPieces = { new DiffPiece("", ChangeType.Deleted, 1), new DiffPiece(" ", ChangeType.Deleted, 2), new DiffPiece("2", ChangeType.Unchanged, 3), }, }, new DiffPiece("3 ", ChangeType.Modified, 3) { SubPieces = { new DiffPiece("3", ChangeType.Unchanged, 1), new DiffPiece(" ", ChangeType.Deleted, 2), }, }, new DiffPiece(" 4 ", ChangeType.Modified, 4) { SubPieces = { new DiffPiece("", ChangeType.Deleted, 1), new DiffPiece(" ", ChangeType.Deleted, 2), new DiffPiece("4", ChangeType.Unchanged, 3), new DiffPiece(" ", ChangeType.Deleted, 4), }, }, new DiffPiece("5", ChangeType.Unchanged, 5), }); Assert.Equal( model.NewText.Lines, new DiffPiece[] { new DiffPiece("1", ChangeType.Unchanged, 1), new DiffPiece("2", ChangeType.Modified, 2) { SubPieces = { new DiffPiece(null, ChangeType.Imaginary), new DiffPiece(null, ChangeType.Imaginary), new DiffPiece("2", ChangeType.Unchanged,1), }, }, new DiffPiece("3", ChangeType.Modified, 3) { SubPieces = { new DiffPiece("3", ChangeType.Unchanged, 1), new DiffPiece(null, ChangeType.Imaginary), }, }, new DiffPiece("4", ChangeType.Modified, 4) { SubPieces = { new DiffPiece(null, ChangeType.Imaginary), new DiffPiece(null, ChangeType.Imaginary), new DiffPiece("4", ChangeType.Unchanged,1), new DiffPiece(null, ChangeType.Imaginary), }, }, new DiffPiece("5", ChangeType.Unchanged, 5), }); }
private async Task DiffTwoFilesAsync(string file, FileCompareModel diffViewModel, StreamWriter streamWriter) { var title = GetSectionTitle("Diff Comparison"); var builder = new SideBySideDiffBuilder(new Differ()); if (!File.Exists(diffViewModel.RightPath) && !File.Exists(diffViewModel.LeftPath)) { // use the repository item path in the message var html = title + WrapTableDefinition(BuildRow($"Could not locate file {diffViewModel.RightPath}. A Diff Comparison was not generated")); streamWriter.Write(html); return; } if (!File.Exists(diffViewModel.RightPath) || !File.Exists(diffViewModel.LeftPath)) { var html = title + WrapTableDefinition(BuildRow("Only One Version of this file is available. A Diff Comparison was not generated")); streamWriter.Write(html); return; } // add the repository items path for the sub title. title += GetSubSectionTitle(file); var leftText = ""; var rightText = ""; var sw = new System.Diagnostics.Stopwatch(); sw.Start(); using (var reader = File.OpenText(diffViewModel.LeftPath)) { Log($"[AuditReports]:[Reading Left]:[Started]"); leftText = await reader.ReadToEndAsync(); Log($"[AuditReports]:[Reading Left]:[Completed]"); } using (var reader = File.OpenText(diffViewModel.RightPath)) { Log($"[AuditReports]:[Reading Right]:[Started]"); rightText = await reader.ReadToEndAsync(); Log($"[AuditReports]:[Reading Right]:[Completed]"); } Log($"[AuditReports]:[BuildDiffModel]:[Started]"); var diff = await Task.Run(() => { return(builder.BuildDiffModel(leftText, rightText)); }); Log($"[AuditReports]:[BuildDiffModel]:[Completed]"); var htmlBuilder = new Html.DiffHtml(); var include = IncludeUnChangedText(diffViewModel.RightPath, diffViewModel.LeftPath); if (!include) { title += GetSubSectionTitle("Due to the size of the original files, the comparison will only show modified lines."); } await streamWriter.WriteLineAsync(title); Log($"[AuditReports]:[Build]:[Started]"); await htmlBuilder.BuildAsync(diff, streamWriter, include); Log($"[AuditReports]:[Build]:[Completed]"); Console.ForegroundColor = ConsoleColor.Green; sw.Stop(); Log($"[AuditReports]:[{nameof(DiffTwoFilesAsync)}]:[Completed In]:[{ElapsedTime(sw.Elapsed)}]"); Console.ResetColor(); }
//----------------------------------------------------------------------- public void DoTransform() { var preview = new TransformPreview(); var projectDir = Path.GetDirectoryName(Workspace.ProjectRoot); var files = Directory.EnumerateFiles(projectDir, "*", SearchOption.AllDirectories).ToList(); foreach (var file in files) { var ext = Path.GetExtension(file); if (ext == ".xml" || ext == ".json" || ext == ".yaml" || Workspace.SupportedExtensionMap.ContainsKey(ext)) { try { var doc = XDocument.Load(file); var transformed = DataTransformer.TransformDocument(doc.Root); var asString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { Indent = true, IndentChars = "\t", NewLineChars = "\r\n", NewLineHandling = NewLineHandling.Replace, OmitXmlDeclaration = true, Encoding = new UTF8Encoding(false) }; using (XmlWriter writer = XmlTextWriter.Create(asString, settings)) { doc.Save(writer); } var original = File.ReadAllText(file); var newContents = asString.ToString(); if (transformed && original != newContents) { var builder = new SideBySideDiffBuilder(new Differ()); var diff = builder.BuildDiffModel(original, newContents); if (diff.NewText.Lines.Any(e => e.Type != ChangeType.Unchanged) || diff.OldText.Lines.Any(e => e.Type != ChangeType.Unchanged)) { preview.Files.Add(new Tuple <string, string, string, SideBySideDiffModel>(file, Path.GetFileNameWithoutExtension(file), newContents, diff)); } } } catch (Exception) { } } } if (preview.Files.Count == 0) { Message.Show("No matching files found in project", "Completed transform"); } else { Preview = preview; RaisePropertyChangedEvent(nameof(Preview)); } }
/// <summary> /// 差分比較情報を作成 /// </summary> private SideBySideDiffModel CreateDiff() { var diff = new SideBySideDiffBuilder(new Differ()); return(diff.BuildDiffModel(pathModel.InputFileName, pathModel.OutputFileName)); }
public void Will_build_diffModel_for_partially_different_documents() { string textOld = "1\n2\na\nb\nc\nd\n\n"; string textNew = "1\n2\nz\ny\nx\nw\n"; string[] textLinesOld = { "1", "2", "a", "b", "c", "d", "" }; string[] textLinesNew = { "1", "2", "z", "y", "x", "w" }; var builder = new SideBySideDiffBuilder(); var bidiff = builder.BuildDiffModel(textOld, textNew); Assert.NotNull(bidiff); Assert.Equal(8, bidiff.OldText.Lines.Count); Assert.Equal(8, bidiff.NewText.Lines.Count); int i = 0; for (; i < 2; i++) { Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text); Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[i].Type); Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position); Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text); Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[i].Type); Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position); } for (; i < Math.Min(textLinesOld.Length, textLinesNew.Length); i++) { Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.OldText.Lines[i].Type); Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position); Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.NewText.Lines[i].Type); Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position); } if (textLinesOld.Length < textLinesNew.Length) { for (int j = i; j < textLinesNew.Length; j++) { Assert.Equal(textLinesNew[j], bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[j].Type); Assert.Equal(j + 1, bidiff.NewText.Lines[j].Position); Assert.Null(bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[j].Type); Assert.False(bidiff.OldText.Lines[j].Position.HasValue); } } else { for (int j = i; j < textLinesOld.Length; j++) { Assert.Equal(textLinesOld[j], bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Deleted, bidiff.OldText.Lines[j].Type); Assert.Equal(j + 1, bidiff.OldText.Lines[j].Position); Assert.Null(bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.NewText.Lines[j].Type); Assert.False(bidiff.NewText.Lines[j].Position.HasValue); } } Assert.True(bidiff.OldText.HasDifferences && bidiff.NewText.HasDifferences); }
// 创建展示两个 OPAC 记录差异的 HTML 字符串 // parameters: // strNewText 如果为 "",表示内容全部被删除,依然会输出对照格式;如果为 null,表示只输出左边的部分 // return: // -1 出错 // 0 成功。两边相等 // 1 两边不相等 public static int DiffOpacHtml( string strOldText, string strNewText, out string strHtml, out string strError) { strError = ""; strHtml = ""; if (string.IsNullOrEmpty(strOldText) == true && string.IsNullOrEmpty(strNewText) == true) { return(0); } var marc_differ = new Differ(); var marc_builder = new SideBySideDiffBuilder(marc_differ); var marc_diff_result = marc_builder.BuildDiffModel(strOldText, strNewText == null? "" : strNewText); Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, ""); /* * public enum ChangeType * { * Unchanged, * Deleted, * Inserted, * Imaginary, * Modified * } * */ bool bChanged = false; StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096); for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++) { var newline = marc_diff_result.NewText.Lines[index]; var oldline = marc_diff_result.OldText.Lines[index]; if (string.IsNullOrEmpty(newline.Text) == true && string.IsNullOrEmpty(oldline.Text) == true) { continue; } if (oldline.Type != ChangeType.Unchanged || newline.Type != ChangeType.Unchanged) { bChanged = true; } string strLineClass = "datafield"; if (strNewText == null) { strResult.Append("\r\n<tr class='" + strLineClass + "'>"); // 创建一个字段的 HTML 局部 三个 <td> strResult.Append(BuildOpacFieldHtml(ChangeType.Unchanged, oldline.Text)); strResult.Append("\r\n</tr>"); continue; } strResult.Append("\r\n<tr class='" + strLineClass + "'>"); // 创建一个字段的 HTML 局部 三个 <td> strResult.Append(BuildOpacFieldHtml(oldline.Type, oldline.Text)); strResult.Append(SEP); strResult.Append(BuildOpacFieldHtml(newline.Type, newline.Text)); strResult.Append("\r\n</tr>"); } strResult.Append("</table>"); strHtml = strResult.ToString(); if (bChanged == false) { return(0); } return(1); }
// 创建展示两个 MARC 记录差异的 HTML 字符串 // return: // -1 出错 // 0 成功 public static int DiffHtml( string strOldTitle, string strOldMarc, string strOldFragmentXml, string strOldImageFragment, string strNewTitle, string strNewMarc, string strNewFragmentXml, string strNewImageFragment, out string strHtml, out string strError) { strError = ""; strHtml = ""; // int nRet = 0; if (string.IsNullOrEmpty(strOldMarc) == true && string.IsNullOrEmpty(strNewMarc) == true) { return(0); } string strOldHeader = ""; string strNewHeader = ""; string strOldBody = ""; string strNewBody = ""; SplitMarc(strOldMarc, out strOldHeader, out strOldBody); SplitMarc(strNewMarc, out strNewHeader, out strNewBody); if (strOldHeader.Length < 24) { strOldHeader = strOldHeader.PadRight(24, '?'); } if (strNewHeader.Length < 24) { strNewHeader = strNewHeader.PadRight(24, '?'); } var marc_differ = new MarcDiffer(); var marc_builder = new MarcDiffBuilder(marc_differ); var marc_diff_result = marc_builder.BuildDiffModel(strOldBody, strNewBody); Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, ""); /* * public enum ChangeType * { * Unchanged, * Deleted, * Inserted, * Imaginary, * Modified * } * */ StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096); if (string.IsNullOrEmpty(strOldTitle) == false || string.IsNullOrEmpty(strNewTitle) == false) { string strLineClass = "header"; strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append(BuildHeaderHtml(false, strOldTitle)); strResult.Append(SEP); strResult.Append(BuildHeaderHtml(false, strNewTitle)); strResult.Append("\r\n</tr>"); } { string strLineClass = "header"; bool bModified = strOldHeader != strNewHeader; strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append(BuildHeaderHtml(bModified, strOldHeader)); strResult.Append(SEP); strResult.Append(BuildHeaderHtml(bModified, strNewHeader)); strResult.Append("\r\n</tr>"); } if (string.IsNullOrEmpty(strOldImageFragment) == false || string.IsNullOrEmpty(strNewImageFragment) == false) { string strLineClass = "header"; strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append(GetImageHtml(strOldImageFragment)); strResult.Append(SEP); strResult.Append(GetImageHtml(strNewImageFragment)); strResult.Append("\r\n</tr>"); } for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++) { var newline = marc_diff_result.NewText.Lines[index]; var oldline = marc_diff_result.OldText.Lines[index]; if (string.IsNullOrEmpty(newline.Text) == true && string.IsNullOrEmpty(oldline.Text) == true) { continue; } string strLineClass = "datafield"; strResult.Append("\r\n<tr class='" + strLineClass + "'>"); // 创建一个字段的 HTML 局部 三个 <td> strResult.Append(BuildFieldHtml(oldline.Type, oldline.Text)); strResult.Append(SEP); strResult.Append(BuildFieldHtml(newline.Type, newline.Text)); strResult.Append("\r\n</tr>"); #if NO if (newline.Type == ChangeType.Unchanged) { } else if (newline.Type == ChangeType.Inserted) { } else if (newline.Type == ChangeType.Modified) { } else if (oldline.Type == ChangeType.Deleted) { } #endif } #if NO if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false) { var xml_differ = new Differ(); var xml_builder = new SideBySideDiffBuilder(xml_differ); var xml_diff_result = xml_builder.BuildDiffModel(GetComparableXmlString(strOldFragmentXml), GetComparableXmlString(strNewFragmentXml)); Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, ""); for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++) { var newline = xml_diff_result.NewText.Lines[index]; var oldline = xml_diff_result.OldText.Lines[index]; string strLineClass = "datafield"; if (newline.Type == ChangeType.Modified) { } strResult.Append("\r\n<tr class='" + strLineClass + "'>"); // 创建一个 XML 字段的 HTML 局部 三个 <td> strResult.Append(BuildFragmentFieldHtml(oldline.Type, oldline.Text)); strResult.Append(SEP); strResult.Append(BuildFragmentFieldHtml(newline.Type, newline.Text)); strResult.Append("\r\n</tr>"); } } #endif if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false) { string strLineClass = "sepline"; strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append("<td class='sepline' colspan='3'> </td>"); strResult.Append("<td class='cross'> </td>"); strResult.Append("<td class='sepline' colspan='3'> </td>"); strResult.Append("\r\n</tr>"); } strResult.Append(DiffXml( 0, strOldFragmentXml, XmlNodeType.Element, strNewFragmentXml, XmlNodeType.Element)); strResult.Append("</table>"); strHtml = strResult.ToString(); return(0); }
public void Will_build_diffModel_for_unique_strings() { string textOld = "a\nb\nc\nd\n\n"; string textNew = "z\ny\nx\nw\n"; string[] textLinesOld = { "a", "b", "c", "d", "" }; string[] textLinesNew = { "z", "y", "x", "w" }; var differ = new Mock <IDiffer>(); differ.Setup(x => x.CreateDiffs(textOld, textNew, true, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult(textLinesOld, textLinesNew, new List <DiffBlock> { new DiffBlock(0, 5, 0, 4) })); differ.Setup(x => x.CreateDiffs(It.IsAny <string>(), It.IsAny <string>(), false, false, It.IsNotNull <IChunker>())) .Returns(new DiffResult(new string[0], new string[0], new List <DiffBlock>())); var builder = new SideBySideDiffBuilder(differ.Object); var bidiff = builder.BuildDiffModel(textOld, textNew); Assert.NotNull(bidiff); Assert.Equal(5, bidiff.OldText.Lines.Count); Assert.Equal(5, bidiff.NewText.Lines.Count); int i = 0; for (; i < Math.Min(textLinesOld.Length, textLinesNew.Length); i++) { Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.OldText.Lines[i].Type); Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position); Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text); Assert.Equal(ChangeType.Modified, bidiff.NewText.Lines[i].Type); Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position); } if (textLinesOld.Length < textLinesNew.Length) { for (int j = i; j < textLinesNew.Length; j++) { Assert.Equal(textLinesNew[j], bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[j].Type); Assert.Equal(j + 1, bidiff.NewText.Lines[j].Position); Assert.Null(bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[j].Type); Assert.False(bidiff.OldText.Lines[j].Position.HasValue); } } else { for (int j = i; j < textLinesOld.Length; j++) { Assert.Equal(textLinesOld[j], bidiff.OldText.Lines[j].Text); Assert.Equal(ChangeType.Deleted, bidiff.OldText.Lines[j].Type); Assert.Equal(j + 1, bidiff.OldText.Lines[j].Position); Assert.Null(bidiff.NewText.Lines[j].Text); Assert.Equal(ChangeType.Imaginary, bidiff.NewText.Lines[j].Type); Assert.False(bidiff.NewText.Lines[j].Position.HasValue); } } Assert.True(bidiff.OldText.HasDifferences && bidiff.NewText.HasDifferences); }
static string DiffXml( int nLevel, string strOldFragmentXml, XmlNodeType old_nodetype, string strNewFragmentXml, XmlNodeType new_nodetype) { if (string.IsNullOrEmpty(strOldFragmentXml) == true && string.IsNullOrEmpty(strNewFragmentXml) == true) { return(""); } if (old_nodetype != XmlNodeType.Element || new_nodetype != XmlNodeType.Element) { if (old_nodetype == XmlNodeType.Element) { strOldFragmentXml = GetIndentXml(strOldFragmentXml); } if (new_nodetype == XmlNodeType.Element) { strNewFragmentXml = GetIndentXml(strNewFragmentXml); } return(GetPlanTextDiffHtml( nLevel, strOldFragmentXml, strNewFragmentXml)); } string strOldChildren = ""; string strOldBegin = ""; string strOldEnd = ""; List <XmlNode> old_childnodes = null; string strOldElementName = ""; GetComparableXmlString(strOldFragmentXml, out strOldChildren, out old_childnodes, out strOldElementName, out strOldBegin, out strOldEnd); string strNewChildren = ""; string strNewBegin = ""; string strNewEnd = ""; List <XmlNode> new_childnodes = null; string strNewElementName = ""; GetComparableXmlString(strNewFragmentXml, out strNewChildren, out new_childnodes, out strNewElementName, out strNewBegin, out strNewEnd); bool bSpecialCompare = false; // 是否属于特殊情况: 根元素名不相同,但仍需要比较下级 if (strOldElementName != strNewElementName && nLevel == 0) { bSpecialCompare = true; } if (strOldElementName != strNewElementName && bSpecialCompare == false) { // 元素名不一样了并且不是根级别,就没有必要做细节比较了 // 意思是说如果是根级别,即便根元素名不一样,也要比较其下级 if (old_nodetype == XmlNodeType.Element) { strOldFragmentXml = GetIndentXml(strOldFragmentXml); } if (new_nodetype == XmlNodeType.Element) { strNewFragmentXml = GetIndentXml(strNewFragmentXml); } return(GetPlanTextDiffHtml( nLevel, strOldFragmentXml, strNewFragmentXml)); } string strLineClass = "datafield"; StringBuilder strResult = new StringBuilder(4096); if (nLevel > 0 || bSpecialCompare == true) { ChangeType begin_type = ChangeType.Unchanged; if (strOldBegin != strNewBegin) { begin_type = ChangeType.Modified; } // Begin strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strOldBegin)); strResult.Append(SEP); strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strNewBegin)); strResult.Append("\r\n</tr>"); } // return "\r\n<td class='content' colspan='3'></td>"; if (string.IsNullOrEmpty(strOldChildren) == false || string.IsNullOrEmpty(strNewChildren) == false) { var xml_differ = new Differ(); var xml_builder = new SideBySideDiffBuilder(xml_differ); var xml_diff_result = xml_builder.BuildDiffModel(strOldChildren, strNewChildren); Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, ""); int old_index = 0; int new_index = 0; for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++) { var newline = xml_diff_result.NewText.Lines[index]; var oldline = xml_diff_result.OldText.Lines[index]; XmlNode new_node = null; if (newline.Type != ChangeType.Imaginary) { new_node = new_childnodes[new_index++]; } XmlNode old_node = null; if (oldline.Type != ChangeType.Imaginary) { old_node = old_childnodes[old_index++]; } if (newline.Type == ChangeType.Modified) { strResult.Append(DiffXml(nLevel + 1, oldline.Text, old_node.NodeType, newline.Text, new_node.NodeType)); continue; } string strOldText = ""; if (old_node != null && old_node.NodeType == XmlNodeType.Element) { strOldText = GetIndentXml(oldline.Text); } else { strOldText = oldline.Text; } string strNewText = ""; if (new_node != null && new_node.NodeType == XmlNodeType.Element) { strNewText = GetIndentXml(newline.Text); } else { strNewText = newline.Text; } strResult.Append("\r\n<tr class='" + strLineClass + "'>"); // 创建一个 XML 字段的 HTML 局部 三个 <td> strResult.Append(BuildFragmentFieldHtml(nLevel + 1, oldline.Type, strOldText)); strResult.Append(SEP); strResult.Append(BuildFragmentFieldHtml(nLevel + 1, newline.Type, strNewText)); strResult.Append("\r\n</tr>"); } } if (nLevel > 0 || bSpecialCompare == true) { ChangeType end_type = ChangeType.Unchanged; if (strOldEnd != strNewEnd) { end_type = ChangeType.Modified; } // End strResult.Append("\r\n<tr class='" + strLineClass + "'>"); strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strOldEnd)); strResult.Append(SEP); strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strNewEnd)); strResult.Append("\r\n</tr>"); } return(strResult.ToString()); }