private void BuildRowDictionary(DataTable dt, DataRowKeysComparer keyComparer, Dictionary <KeyCollection, int> dict) { dict.Clear(); foreach (DataRow row in dt.Rows) { RowHelper hlpr = new RowHelper(); var keys = keyComparer.GetKeys(row); hlpr.Keys = keys; //Check that the rows in the reference are unique // All the rows should be unique regardless of whether it is the system under test or the result set. if (dict.ContainsKey(keys)) { dict[keys]++; } else { dict.Add(keys, 1); } } }
private void BuildRowDictionary(DataTable dt, Dictionary <KeyCollection, RowHelper> dict, DataRowKeysComparer keyComparer, bool isSystemUnderTest) { dict.Clear(); foreach (DataRow row in dt.Rows) { RowHelper hlpr = new RowHelper(); var keys = keyComparer.GetKeys(row); hlpr.Keys = keys; hlpr.DataRowObj = row; //Check that the rows in the reference are unique // All the rows should be unique regardless of whether it is the system under test or the result set. if (dict.ContainsKey(keys)) { throw new EquivalerException( string.Format("The {0} data set has some duplicated keys. Check your keys definition or the result set defined in your {1}. The duplicated hashcode is {2}.\r\nRow to insert:{3}.\r\nRow already inserted:{4}.", isSystemUnderTest ? "actual" : "expected", isSystemUnderTest ? "system-under-test" : "assertion", keys.GetHashCode(), RowToString(row), RowToString(dict[keys].DataRowObj) ) ); } dict.Add(keys, hlpr); } }
private void CalculateHashValues(DataTable dt, Dictionary<Int64, CompareHelper> dict, DataRowKeysComparer keyComparer, bool isSystemUnderTest) { dict.Clear(); Int64 keysHashed; Int64 valuesHashed; foreach (DataRow row in dt.Rows) { CompareHelper hlpr = new CompareHelper(); keyComparer.GetHashCode64_KeysValues(row, out keysHashed, out valuesHashed); hlpr.KeysHashed = keysHashed; hlpr.ValuesHashed = valuesHashed; hlpr.DataRowObj = row; //Check that the rows in the reference are unique // All the rows should be unique regardless of whether it is the system under test or the result set. if (dict.ContainsKey(keysHashed)) { throw new ResultSetComparerException( string.Format("The {0} data set has some duplicated keys. Check your keys definition or the result set defined in your {1}.", isSystemUnderTest ? "actual" : "expected", isSystemUnderTest ? "system-under-test" : "assertion" ) ); } dict.Add(keysHashed, hlpr); } }
protected ResultSetCompareResult doCompare(DataTable x, DataTable y) { var chrono = DateTime.Now; var columnsCount = Math.Max(y.Columns.Count, x.Columns.Count); if (Settings == null) BuildDefaultSettings(columnsCount); else Settings.ApplyTo(columnsCount); Settings.ConsoleDisplay(); WriteSettingsToDataTableProperties(y, Settings); WriteSettingsToDataTableProperties(x, Settings); CheckSettingsAndDataTable(y, Settings); CheckSettingsAndDataTable(x, Settings); CheckSettingsAndFirstRow(y, Settings); CheckSettingsAndFirstRow(x, Settings); var keyComparer = new DataRowKeysComparer(Settings, x.Columns.Count); CalculateHashValues(x, xDict, keyComparer, false); CalculateHashValues(y, yDict, keyComparer, true); chrono = DateTime.Now; List<CompareHelper> missingRows; { var missingRowKeys = xDict.Keys.Except(yDict.Keys); missingRows = new List<CompareHelper>(missingRowKeys.Count()); foreach (Int64 i in missingRowKeys) { missingRows.Add(xDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Missing rows: {0} [{1}]", missingRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; List<CompareHelper> unexpectedRows; { var unexpectedRowKeys = yDict.Keys.Except(xDict.Keys); unexpectedRows = new List<CompareHelper>(unexpectedRowKeys.Count()); foreach (Int64 i in unexpectedRowKeys) { unexpectedRows.Add(yDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Unexpected rows: {0} [{1}]", unexpectedRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; List<CompareHelper> keyMatchingRows; { var keyMatchingRowKeys = xDict.Keys.Intersect(yDict.Keys); keyMatchingRows = new List<CompareHelper>(keyMatchingRowKeys.Count()); foreach (Int64 i in keyMatchingRowKeys) { keyMatchingRows.Add(xDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Rows with a matching key and not duplicated: {0} [{1}]", keyMatchingRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; var nonMatchingValueRows = new List<DataRow>(); // If all of the columns make up the key, then we already know which rows match and which don't. // So there is no need to continue testing if (Settings.KeysDef != ResultSetComparisonSettings.KeysChoice.All) { foreach (var rxHelper in keyMatchingRows) { var ryHelper = yDict[rxHelper.KeysHashed]; if (ryHelper.ValuesHashed == rxHelper.ValuesHashed) { // quick shortcut. If the hash of the values matches, then there is no further need to test continue; } var rx = rxHelper.DataRowObj; var ry = ryHelper.DataRowObj; for (int i = 0; i < rx.Table.Columns.Count; i++) { if (Settings.IsValue(i)) { //Null management if (rx.IsNull(i) || ry.IsNull(i)) { if (!rx.IsNull(i) || !ry.IsNull(i)) { ry.SetColumnError(i, ry.IsNull(i) ? rx[i].ToString() : "(null)"); if (!nonMatchingValueRows.Contains(ry)) nonMatchingValueRows.Add(ry); } } //(value) management else if (rx[i].ToString() == "(value)" || ry[i].ToString() == "(value)") { if (rx.IsNull(i) || ry.IsNull(i)) { ry.SetColumnError(i, rx[i].ToString()); if (!nonMatchingValueRows.Contains(ry)) nonMatchingValueRows.Add(ry); } } //Not Null management else { ComparerResult result = null; //Numeric if (Settings.IsNumeric(i)) { //Convert to decimal if (Settings.IsRounding(i)) result = numericComparer.Compare(rx[i], ry[i], Settings.GetRounding(i)); else result = numericComparer.Compare(rx[i], ry[i], Settings.GetTolerance(i)); } //Date and Time else if (Settings.IsDateTime(i)) { //Convert to dateTime if (Settings.IsRounding(i)) result = dateTimeComparer.Compare(rx[i], ry[i], Settings.GetRounding(i)); else result = dateTimeComparer.Compare(rx[i], ry[i], Settings.GetTolerance(i)); } //Boolean else if (Settings.IsBoolean(i)) { //Convert to bool result = booleanComparer.Compare(rx[i], ry[i]); } //Text else { result = textComparer.Compare(rx[i], ry[i]); } //If are not equal then we need to set the message in the ColumnError. if (!result.AreEqual) { ry.SetColumnError(i, result.Message); if (!nonMatchingValueRows.Contains(ry)) nonMatchingValueRows.Add(ry); } } } } } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Rows with a matching key but without matching value: {0} [{1}]", nonMatchingValueRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); var duplicatedRows = new List<DataRow>(); // Dummy place holder return ResultSetCompareResult.Build( missingRows.Select(a => a.DataRowObj).ToList(), unexpectedRows.Select(a => a.DataRowObj).ToList(), duplicatedRows, keyMatchingRows.Select(a => a.DataRowObj).ToList(), nonMatchingValueRows ); }
private void BuildRowDictionary(DataTable dt, Dictionary<KeyCollection, CompareHelper> dict, DataRowKeysComparer keyComparer, bool isSystemUnderTest) { dict.Clear(); foreach (DataRow row in dt.Rows) { CompareHelper hlpr = new CompareHelper(); var keys = keyComparer.GetKeys(row); hlpr.Keys = keys; hlpr.DataRowObj = row; //Check that the rows in the reference are unique // All the rows should be unique regardless of whether it is the system under test or the result set. if (dict.ContainsKey(keys)) { throw new ResultSetComparerException( string.Format("The {0} data set has some duplicated keys. Check your keys definition or the result set defined in your {1}. The duplicated hashcode is {2}.\r\nRow to insert:{3}.\r\nRow already inserted:{4}.", isSystemUnderTest ? "actual" : "expected", isSystemUnderTest ? "system-under-test" : "assertion", keys.GetHashCode(), RowToString(row), RowToString(dict[keys].DataRowObj) ) ); } dict.Add(keys, hlpr); } }
protected ResultSetCompareResult doCompare(DataTable x, DataTable y) { var chrono = DateTime.Now; var columnsCount = Math.Max(y.Columns.Count, x.Columns.Count); if (Settings == null) BuildDefaultSettings(columnsCount); else Settings.ApplyTo(columnsCount); Settings.ConsoleDisplay(); WriteSettingsToDataTableProperties(y, Settings); WriteSettingsToDataTableProperties(x, Settings); CheckSettingsAndDataTable(y, Settings); CheckSettingsAndDataTable(x, Settings); CheckSettingsAndFirstRow(y, Settings); CheckSettingsAndFirstRow(x, Settings); var keyComparer = new DataRowKeysComparer(Settings, x.Columns.Count); chrono = DateTime.Now; BuildRowDictionary(x, xDict, keyComparer, false); Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Building first rows dictionary: {0} [{1}]", x.Rows.Count, DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; BuildRowDictionary(y, yDict, keyComparer, true); Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Building second rows dictionary: {0} [{1}]", y.Rows.Count, DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; List<CompareHelper> missingRows; { var missingRowKeys = xDict.Keys.Except(yDict.Keys); missingRows = new List<CompareHelper>(missingRowKeys.Count()); foreach (var i in missingRowKeys) { missingRows.Add(xDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Missing rows: {0} [{1}]", missingRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; List<CompareHelper> unexpectedRows; { var unexpectedRowKeys = yDict.Keys.Except(xDict.Keys); unexpectedRows = new List<CompareHelper>(unexpectedRowKeys.Count()); foreach (var i in unexpectedRowKeys) { unexpectedRows.Add(yDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Unexpected rows: {0} [{1}]", unexpectedRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; List<CompareHelper> keyMatchingRows; { var keyMatchingRowKeys = xDict.Keys.Intersect(yDict.Keys); keyMatchingRows = new List<CompareHelper>(keyMatchingRowKeys.Count()); foreach (var i in keyMatchingRowKeys) { keyMatchingRows.Add(xDict[i]); } } Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Rows with a matching key and not duplicated: {0} [{1}]", keyMatchingRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); chrono = DateTime.Now; var nonMatchingValueRows = new List<DataRow>(); // If all of the columns make up the key, then we already know which rows match and which don't. // So there is no need to continue testing CompareValues(keyMatchingRows, nonMatchingValueRows); Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Rows with a matching key but without matching value: {0} [{1}]", nonMatchingValueRows.Count(), DateTime.Now.Subtract(chrono).ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); var duplicatedRows = new List<DataRow>(); // Dummy place holder return ResultSetCompareResult.Build( missingRows.Select(a => a.DataRowObj).ToList(), unexpectedRows.Select(a => a.DataRowObj).ToList(), duplicatedRows, keyMatchingRows.Select(a => a.DataRowObj).ToList(), nonMatchingValueRows ); }