private static void VerifyReportRows(ErrorWriter writer, InstanceReport baseReport, InstanceReport genReport) { if (baseReport.Rows.Count != genReport.Rows.Count) { int differences = Math.Abs(baseReport.Rows.Count - genReport.Rows.Count); List <string> baseRows = baseReport.Rows.ConvertAll(row => WHITE_SPACE.Replace(row.Label, " ")); List <string> genRows = genReport.Rows.ConvertAll(row => WHITE_SPACE.Replace(row.Label, " ")); if (baseRows.Count < genRows.Count) { writer.StartError("<strong>The new rendering generated too MANY rows.</strong>"); foreach (string commonLabel in baseRows) { if (genRows.Contains(commonLabel)) { genRows.Remove(commonLabel); } } if (genRows.Count == differences) { foreach (string newLabel in genRows) { writer.WriteError("\tAdded: " + newLabel); } } else { writer.WriteError("\tSEVERAL LABELS CHANGED"); } writer.EndError(); } else { writer.StartError("<strong>The new rendering generated too FEW rows.</strong>"); foreach (string commonLabel in genRows) { if (baseRows.Contains(commonLabel)) { baseRows.Remove(commonLabel); } } if (baseRows.Count == differences) { foreach (string newLabel in baseRows) { writer.WriteError("\tRemoved: " + newLabel); } } else { writer.WriteError("\tSEVERAL LABELS CHANGED"); } writer.EndError(); } } for (int bIdx = 0; bIdx < baseReport.Rows.Count; bIdx++) { InstanceReportRow baseRow = baseReport.Rows[bIdx]; string baseLabel = WHITE_SPACE.Replace(baseRow.Label, " "); int gIdx = -1; InstanceReportRow genRow = null; if (genReport.Rows.Count > bIdx) { if (WHITE_SPACE.Replace(genReport.Rows[bIdx].Label, " ") == baseLabel) { gIdx = bIdx; genRow = genReport.Rows[bIdx]; } } if (genRow == null) { if (bIdx >= genReport.Rows.Count) { writer.WriteError( "<strong>Generated report has too few rows to match Base row:</strong>", "\tRow " + bIdx + ": " + baseLabel, "\t***Row Skipped***" ); continue; } gIdx = bIdx == 0 ? genReport.Rows.FindIndex(bIdx, row => WHITE_SPACE.Replace(row.Label, " ") == baseLabel) : genReport.Rows.FindIndex(bIdx - 1, row => WHITE_SPACE.Replace(row.Label, " ") == baseLabel); if (gIdx == -1) { writer.WriteError( "<strong>Base row not found in generated report:</strong>", "\tRow " + bIdx + ": " + baseLabel, "\t***Row Skipped***" ); continue; } genRow = genReport.Rows[gIdx]; if (bIdx != gIdx) { writer.WriteError( "<strong>Row moved:</strong> " + baseLabel, "\tExpected: " + bIdx.ToString(), "\tGenerated: " + gIdx.ToString() ); } } if (!string.Equals(baseRow.FootnoteIndexer, genRow.FootnoteIndexer)) { writer.WriteError( "<strong>Row footnotes changed:</strong> " + baseLabel, "\tExpected: " + baseRow.FootnoteIndexer, "\tGenerated: " + genRow.FootnoteIndexer ); } decimal baseSum = 0M; baseRow.Cells.FindAll(c => c.IsNumeric).ForEach(c => baseSum += c.NumericAmount); decimal genSum = 0M; genRow.Cells.FindAll(c => c.IsNumeric).ForEach(c => genSum += c.NumericAmount); decimal difference = baseSum - genSum; if (difference != 0) { if (difference > 0) { writer.WriteError( "<strong>Row sum is SMALLER than expected:</strong>", "\tRow " + bIdx + ": " + baseLabel, "\tExpected: " + baseSum, "\tGenerated: " + genSum ); } else { writer.WriteError( "<strong>Row sum is LARGER than expected:</strong>", "\tRow " + bIdx + ": " + baseLabel, "\tExpected: " + baseSum, "\tGenerated: " + genSum ); } } if (baseRow.IsTotalLabel != genRow.IsTotalLabel) { writer.WriteError( "<strong>Row 'Total Label' flag changed:</strong>", "\tRow " + bIdx + ": " + baseLabel, "\tExpected: " + baseRow.IsTotalLabel, "\tGenerated: " + genRow.IsTotalLabel ); } foreach (Cell baseCell in baseRow.Cells) { Cell genCell = null; int cIdx = baseRow.Cells.IndexOf(baseCell); if (genRow.Cells.Count > cIdx) { genCell = genRow.Cells[cIdx]; } if (genCell == null) { writer.WriteError("\tBase cell not found in Generated report."); continue; } if (!genCell.IsNumeric) { genCell.NonNumbericText = WHITE_SPACE.Replace(genCell.NonNumbericText, " "); } if (!baseCell.IsNumeric) { if (baseCell.NonNumbericText == " ") { baseCell.NonNumbericText = Cell.NILL_PLACEHOLDER; } else { baseCell.NonNumbericText = WHITE_SPACE.Replace(baseCell.NonNumbericText, " "); } } List <string> diffs = new List <string>(); if (!baseCell.ValueEquals(genCell, ref diffs)) { baseCell.FlagID = 1; genCell.FlagID = 1; string props = string.Join(", ", diffs.ToArray()); if (!string.IsNullOrEmpty(props)) { props = "\t\tProperties: " + props; } writer.WriteError("\t<strong>Cell value does not match:</strong>", "\t\tRow " + bIdx + ", Cell " + cIdx, "\t\tExpected: " + baseCell.ToString(), "\t\tGenerated: " + genCell.ToString(), props); } else if (!string.Equals(baseCell.FootnoteIndexer, genCell.FootnoteIndexer)) { baseCell.FlagID = 1; genCell.FlagID = 1; writer.WriteError("<strong>Cell footnotes changed:</strong>", "\t\tRow " + bIdx + ", Cell " + cIdx, "\t\tExpected: " + baseCell.FootnoteIndexer, "\t\tGenerated: " + genCell.FootnoteIndexer); } } List <Cell> baseEmbedCells = baseRow.Cells.FindAll(c => c.HasEmbeddedReport && c.EmbeddedReport != null && c.EmbeddedReport.InstanceReport != null); List <Cell> genEmbedCells = genRow.Cells.FindAll(c => c.HasEmbeddedReport && c.EmbeddedReport != null && c.EmbeddedReport.InstanceReport != null); if (baseEmbedCells.Count != genEmbedCells.Count) { difference = Math.Abs(baseEmbedCells.Count - genEmbedCells.Count); if (baseEmbedCells.Count > genEmbedCells.Count) { writer.WriteError("<strong>Row has MISSING embedded reports:</strong>", "\tExpected: " + baseEmbedCells.Count, "\tGenerated: " + genEmbedCells.Count); } else { writer.WriteError("<strong>Row has EXTRA embedded reports:</strong>", "\tExpected: " + baseEmbedCells.Count, "\tGenerated: " + genEmbedCells.Count); } } for (int c = 0; c < baseEmbedCells.Count; c++) { Cell embedCell = baseEmbedCells[c]; InstanceReport baseEmbed = embedCell.EmbeddedReport.InstanceReport; int genCellIndex = c == 0 ? genEmbedCells.FindIndex(cell => baseEmbed.ReportLongName == cell.EmbeddedReport.InstanceReport.ReportLongName) : genEmbedCells.FindIndex(c - 1, cell => baseEmbed.ReportLongName == cell.EmbeddedReport.InstanceReport.ReportLongName); if (genCellIndex == -1) { writer.WriteError("<strong>Embedded report not found in generated report:</strong>", "\tRow " + bIdx + ", Cell " + c + ": " + baseEmbed.ReportName, "\tEMBED Skipped"); continue; } Cell genEmbedCell = genEmbedCells[genCellIndex]; InstanceReport genEmbed = genEmbedCell.EmbeddedReport.InstanceReport; try { writer.StartReport(baseEmbed.ReportLongName + ".xml", baseEmbed, genEmbed, null); writer.WriteLine("*************** EMBED Comparison Started ***************"); VerifyReports(writer, baseEmbed, genEmbed); writer.WriteLine("*************** EMBED Comparison Ended ***************"); } finally { writer.EndReport(baseEmbed.ReportLongName + ".xml"); } } } }
public static void VerifyIndividualReports(ErrorWriter writer, IDirectoryInfo baselineResultInfo, IDirectoryInfo generatedResultInfo, string failedResultsFolder) { IFileInfo[] baseFiles = new IFileInfo[0]; if (baselineResultInfo.Exists) { baseFiles = baselineResultInfo.GetFiles("R*.xml"); Array.Sort(baseFiles, natcasecmp); } IFileInfo[] genFiles = new IFileInfo[0]; if (generatedResultInfo.Exists) { genFiles = generatedResultInfo.GetFiles("R*.xml"); Array.Sort(genFiles, natcasecmp); } if (baseFiles.Length < genFiles.Length) { writer.StartError("The new rendering generated too MANY files:"); for (int i = 0; i < genFiles.Length; i++) { bool found = Array.Exists(baseFiles, bFile => string.Equals(bFile.Name, genFiles[i].Name)); if (!found) { writer.WriteError("\tAdded: " + genFiles[i].Name); } } writer.EndError(); } else if (baseFiles.Length > genFiles.Length) { writer.StartError("The new rendering generated too FEW files."); for (int i = 0; i < baseFiles.Length; i++) { bool found = Array.Exists(genFiles, gFile => string.Equals(gFile.Name, baseFiles[i].Name)); if (!found) { writer.WriteError("\tAdded: " + baseFiles[i].Name); } } writer.EndError(); } Dictionary <string, int> allFiles = new Dictionary <string, int>(); foreach (IFileInfo bFile in baseFiles) { allFiles[bFile.Name] = 1; } foreach (IFileInfo gFile in genFiles) { allFiles[gFile.Name] = 1; } Dictionary <string, InstanceReport> tryVerifyEmbedded = new Dictionary <string, InstanceReport>(); foreach (string file in allFiles.Keys) { if (!R_FILE_REGEX.IsMatch(file)) { continue; } InstanceReport baseReport = null; InstanceReport genReport = null; try { if (baselineResultInfo.FileExists(file)) { using (Stream fileStream = baselineResultInfo.OpenStream(file)) { baseReport = InstanceReport.LoadXmlStream(fileStream); } } if (generatedResultInfo.FileExists(file)) { using (Stream fileStream = generatedResultInfo.OpenStream(file)) { genReport = InstanceReport.LoadXmlStream(fileStream); } } if (baseReport == null) { throw new Exception("Base report is missing."); } else { foreach (InstanceReportRow row in baseReport.Rows) { foreach (Cell cell in row.Cells) { cell.FlagID = 0; } } } if (genReport == null) { throw new Exception("Generated report is missing."); } else { foreach (InstanceReportRow row in baseReport.Rows) { foreach (Cell cell in row.Cells) { cell.FlagID = 0; } } } writer.StartReport(file, baseReport, genReport, failedResultsFolder); writer.WriteLine(PathCombine(baselineResultInfo.FullName, file)); writer.WriteLine(PathCombine(generatedResultInfo.FullName, file)); VerifyReports(writer, baseReport, genReport); } catch (Exception ex) { writer.StartReport(file, baseReport, genReport, failedResultsFolder); writer.WriteError(ex.Message); } finally { writer.EndReport(file); } } }