public DirectoryComparisonDifference Compare() { DirectoryComparisonDifference comparisonResult = new DirectoryComparisonDifference(); if (!BaselineDifference.IsValidBaseline) { comparisonResult.InvalidBaselineData = true; return(comparisonResult); } if (!CheckDifference.IsValidBaseline) { comparisonResult.InvalidSecondaryData = true; return(comparisonResult); } IReadOnlyDictionary <string, FileDifference> checkFileLookup = CheckDifference.FileResults.ToDictionary(x => x.File, x => x); foreach (FileDifference baselineFileDiff in BaselineDifference.FileResults) { if (!checkFileLookup.TryGetValue(baselineFileDiff.File, out FileDifference checkFileDiff)) { FileComparisonDifference fileResult = new FileComparisonDifference(baselineFileDiff.File); fileResult.MissingSecondaryFile = true; comparisonResult.AddFileResult(fileResult); } else { FileDifferenceComparer comparer = new FileDifferenceComparer(baselineFileDiff, checkFileDiff); FileComparisonDifference fileResult = comparer.Compare(); comparisonResult.AddFileResult(fileResult); } } // check for files in the check result but not the baseline. HashSet <string> baselineFileLookup = new HashSet <string>(BaselineDifference.FileResults.Select(x => x.File)); foreach (FileDifference checkFileDifference in CheckDifference.FileResults) { if (!baselineFileLookup.Contains(checkFileDifference.File)) { FileComparisonDifference fileResult = new FileComparisonDifference(checkFileDifference.File); fileResult.MissingBaselineFile = true; comparisonResult.AddFileResult(fileResult); } } return(comparisonResult); }
public void AddFileResult(FileComparisonDifference fileComparison) { _fileResults.Add(fileComparison); }
public FileComparisonDifference Compare() { int baselineDiffIndex = 0; int checkDiffIndex = 0; FileComparisonDifference fileResult = new FileComparisonDifference(BaselineComparisonDifferences.File); while (baselineDiffIndex < BaselineComparisonDifferences.Differences.Count && checkDiffIndex < CheckComparisonDifferences.Differences.Count) { PositionalDifference baselineDiff = BaselineComparisonDifferences.Differences[baselineDiffIndex]; PositionalDifference checkDiff = CheckComparisonDifferences.Differences[checkDiffIndex]; if (Math.Abs(baselineDiff.BaselineStartPosition - checkDiff.BaselineStartPosition) > baselineDiff.LocationLeeway) { // The differences are too far apart in absolute baseline position, it's a non-match. Consume the first one. // Once one of these occurs, the overall match has failed, and the rest will probably be bad too. if (baselineDiff.BaselineStartPosition < checkDiff.BaselineStartPosition) { fileResult.AddBaselineOnlyDifference(baselineDiff); ++baselineDiffIndex; } else { fileResult.AddCheckOnlyDifference(checkDiff); ++checkDiffIndex; } } else { // the differences are close enough to compare to each other. if (baselineDiff.Classification != checkDiff.Classification) { // The classifications are different, it's a non-match fileResult.AddPositionallyMatchedDifference(baselineDiff, checkDiff, PositionalComparisonDisposition.DatatypeMismatch); } else if (Math.Abs(baselineDiff.SecondaryData.Length - checkDiff.SecondaryData.Length) > baselineDiff.LocationLeeway) { // The check data length is more than the allowed difference in length. fileResult.AddPositionallyMatchedDifference(baselineDiff, checkDiff, PositionalComparisonDisposition.LengthMismatch); } else { fileResult.AddPositionallyMatchedDifference(baselineDiff, checkDiff, PositionalComparisonDisposition.Match); } // The baseline & check differences are positionally similar in the above cases, both get consumed. ++baselineDiffIndex; ++checkDiffIndex; } } // One of the comparisons may have additional unhandled differences, can't possibly be both. // So at most one of these loops can actually iterate. while (baselineDiffIndex < BaselineComparisonDifferences.Differences.Count) { PositionalDifference baselineDiff = BaselineComparisonDifferences.Differences[baselineDiffIndex]; fileResult.AddBaselineOnlyDifference(baselineDiff); ++baselineDiffIndex; } while (checkDiffIndex < CheckComparisonDifferences.Differences.Count) { PositionalDifference checkDiff = CheckComparisonDifferences.Differences[checkDiffIndex]; fileResult.AddCheckOnlyDifference(checkDiff); ++checkDiffIndex; } // verify the results are sane - that all differences got classified. int classifiedDiffCount = fileResult.BaselineOnlyDifferences.Count + fileResult.SecondaryOnlyDifferences.Count + 2 * fileResult.PositionallyMatchedDifferences.Count; // these are counted twice because they consume both a baseline & secondary diff int actualDiffCount = BaselineComparisonDifferences.Differences.Count + CheckComparisonDifferences.Differences.Count; if (classifiedDiffCount != actualDiffCount) { fileResult.HasDifferenceResolutionError = true; } return(fileResult); }
public static StructuredFileComparisonDifference FromFileComparisonDifference(FileComparisonDifference differences) { StructuredFileComparisonDifference structuredDifference = new StructuredFileComparisonDifference() { Filename = differences.Filename, HasDifferenceResolutionError = differences.HasDifferenceResolutionError, HasInvalidDifferences = differences.AnyInvalidDifferences, BaselineOnlyDifferences = differences.BaselineOnlyDifferences, SecondaryOnlyDifferences = differences.SecondaryOnlyDifferences, FullyMatchedDifferences = differences.PositionallyMatchedDifferences.Where(d => d.Disposition == PositionalComparisonDisposition.Match) .Select(m => StructuredPositionalComparisonDifference.FromPositionalComparisonDifference(m)).ToList(), PositionallyMatchedDifferencesWithIssues = differences.PositionallyMatchedDifferences.Where(d => d.Disposition != PositionalComparisonDisposition.Match) .Select(m => StructuredPositionalComparisonDifference.FromPositionalComparisonDifference(m)).ToList(), MissingBaselineFile = differences.MissingBaselineFile, MissingSecondaryFile = differences.MissingSecondaryFile }; return(structuredDifference); }