Exemple #1
0
        private static int CompareCurrentReadersPKValues(
            DbDataReaderComparer comparer,
            IDataReader expectedData,
            IDataReader actualData,
            bool expectedReaderHasMoreData,
            bool actualReaderHasMoreData)
        {
            int pkCompareResult;

            if (expectedReaderHasMoreData && actualReaderHasMoreData)
            {
                // With both readers having data, compare PK values
                pkCompareResult = comparer.Compare(expectedData, actualData);
            }
            else if (!expectedReaderHasMoreData && !actualReaderHasMoreData)
            {
                // Neither reader has data
                throw new InvalidOperationException("Neither IDataReader instance has data.");
            }
            else if (!expectedReaderHasMoreData)
            {
                // Expected values reader ran out of data
                // (Unexpected actual row in actual values reader)
                pkCompareResult = 1;
            }
            else // !actualReaderHasMoreData
            {
                // Actual values reader ran out of data
                // (Missing a row in actual values reader)
                pkCompareResult = -1;
            }

            return(pkCompareResult);
        }
Exemple #2
0
        private void CompareAndDisposeDataReaders(
            DbDataReaderComparer comparer,
            DataComparerResults dataComparerResults,
            IDataReader actualData,
            IDataReader expectedData,
            IEnumerable <string> additionalColumnNamesToIgnore)
        {
            try
            {
                bool expectedReaderHasMoreData = ReadDataReader(expectedData);
                bool actualReaderHasMoreData   = ReadDataReader(actualData);

                // No data?  Quit now
                if (!actualReaderHasMoreData && !expectedReaderHasMoreData)
                {
                    return;
                }

                Dictionary <string, bool> additionalFieldsToIgnore =
                    GetAdditionalFieldsToIgnoreAsDictionary(additionalColumnNamesToIgnore);

                do
                {
                    // Using primary key values, determine whether readers are on same record, or one is "ahead" of the other
                    int pkCompareResult = CompareCurrentReadersPKValues(
                        comparer,
                        expectedData,
                        actualData,
                        expectedReaderHasMoreData,
                        actualReaderHasMoreData);

                    ProcessComparisonResults(
                        dataComparerResults,
                        pkCompareResult,
                        expectedData,
                        actualData,
                        ref expectedReaderHasMoreData,
                        ref actualReaderHasMoreData,
                        additionalFieldsToIgnore);
                }while ((expectedReaderHasMoreData || actualReaderHasMoreData) &&
                        dataComparerResults.RowDifferences.Count < MaximumDifferences);
            }
            finally
            {
                // Make sure the the data readers are properly disposed
                actualData.Dispose();
                expectedData.Dispose();
            }
        }
Exemple #3
0
        /// <summary>
        /// Compares the contents of two IDataReader instances, ignoring the specified columns, optionally creating DataTables for further inspection of the data.
        /// </summary>
        /// <param name="tableName">The name of the table for which the data comparison was performed.</param>
        /// <param name="expectedData">A <see cref="IDataReader"/> containing the expected data.</param>
        /// <param name="actualData">A <see cref="IDataReader"/> containing the actual data.</param>
        /// <param name="uniqueConstraintFieldNames">An array of the names of the primary key fields to use as the basis for identifying corresponding rows between the two readers.</param>
        /// <param name="isPrimaryKey"></param>
        /// <param name="dataCopyMode">Indicates whether or not a <see cref="DataTable"/> should be created for each <see cref="IDataReader"/> (expected and actual) and the data copied in while processing the readers.</param>
        /// <param name="additionalFieldsToIgnore">Fields to ignore for the current comparison (mismatches in data values will not be counted as failures).</param>
        /// <returns>The results of the comparison.</returns>
        public DataComparerResults Compare(
            string tableName,
            IDataReader expectedData,
            IDataReader actualData,
            string[] uniqueConstraintFieldNames,
            bool isPrimaryKey,
            DataCopyMode dataCopyMode,
            string[] additionalFieldsToIgnore)
        {
            //Initialize an empty array if the parameter is null.
            additionalFieldsToIgnore = additionalFieldsToIgnore ?? new string[0];

            var dataComparerResults = new DataComparerResults {
                TableName = tableName
            };

            this.dataCopyMode = dataCopyMode;

            // Prepare data tables, if necessary
            if (dataCopyMode == DataCopyMode.All || dataCopyMode == DataCopyMode.DifferencesOnly)
            {
                DataTable expectedTable = InitializeDataTable(expectedData, uniqueConstraintFieldNames, isPrimaryKey);
                expectedTable.TableName          = "ExpectedDataTable";
                tablesByReader[expectedData]     = expectedTable;
                dataComparerResults.ExpectedData = expectedTable;

                DataTable actualTable = InitializeDataTable(actualData, uniqueConstraintFieldNames, isPrimaryKey);
                actualTable.TableName          = "ActualDataTable";
                tablesByReader[actualData]     = actualTable;
                dataComparerResults.ActualData = actualTable;
            }

            primaryKeyFields = new List <string>(uniqueConstraintFieldNames);

            InitializeColumnNamesFromReader(dataComparerResults.ColumnNames, actualData);

            VerifyThatAllNonTestColumnsFromExpectedDataArePresent(
                dataComparerResults.TableName,
                dataComparerResults.ColumnNames,
                expectedData,
                additionalFieldsToIgnore);

            // Initialize counts
            rowCountsByReader[expectedData] = 0;
            rowCountsByReader[actualData]   = 0;

            int[] expectedPKOrdinals =
                (from field in uniqueConstraintFieldNames
                 select expectedData.GetOrdinal(field)).ToArray();

            actualPKOrdinals =
                (from field in uniqueConstraintFieldNames
                 select actualData.GetOrdinal(field)).ToArray();

            DbDataReaderComparer comparer = new DbDataReaderComparer(expectedPKOrdinals, actualPKOrdinals);

            CompareAndDisposeDataReaders(comparer, dataComparerResults, actualData, expectedData, additionalFieldsToIgnore);

            // Set counts
            dataComparerResults.ExpectedRowCount = rowCountsByReader[expectedData];
            dataComparerResults.ActualRowCount   = rowCountsByReader[actualData];

            return(dataComparerResults);
        }