001: /*
002: *
003: * The DbUnit Database Testing Framework
004: * Copyright (C)2002-2004, DbUnit.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: */
021:
022: package org.dbunit;
023:
024: import org.slf4j.Logger;
025: import org.slf4j.LoggerFactory;
026:
027: import junit.framework.Assert;
028: import org.dbunit.dataset.*;
029: import org.dbunit.dataset.datatype.DataType;
030: import org.dbunit.dataset.datatype.UnknownDataType;
031:
032: import java.util.Arrays;
033: import java.util.Comparator;
034:
035: /**
036: * @author Manuel Laflamme
037: * @version $Revision: 564 $
038: * @since Mar 22, 2002
039: */
040: public class Assertion {
041:
042: /**
043: * Logger for this class
044: */
045: private static final Logger logger = LoggerFactory
046: .getLogger(Assertion.class);
047:
048: private static final ColumnComparator COLUMN_COMPARATOR = new ColumnComparator();
049:
050: private Assertion() {
051: }
052:
053: /**
054: * Asserts that the two specified dataset are equals. This method ignore
055: * the tables order.
056: */
057: public static void assertEquals(IDataSet expectedDataSet,
058: IDataSet actualDataSet) throws DatabaseUnitException {
059: logger
060: .debug(
061: "assertEquals(expectedDataSet={}, actualDataSet={}) - start",
062: expectedDataSet, actualDataSet);
063:
064: // do not continue if same instance
065: if (expectedDataSet == actualDataSet) {
066: return;
067: }
068:
069: String[] expectedNames = getSortedUpperTableNames(expectedDataSet);
070: String[] actualNames = getSortedUpperTableNames(actualDataSet);
071:
072: // tables count
073: Assert.assertEquals("table count", expectedNames.length,
074: actualNames.length);
075:
076: // table names in no specific order
077: for (int i = 0; i < expectedNames.length; i++) {
078: if (!actualNames[i].equals(expectedNames[i])) {
079: Assert.fail("expected tables "
080: + Arrays.asList(expectedNames) + " but was "
081: + Arrays.asList(actualNames));
082: }
083:
084: }
085:
086: // tables
087: for (int i = 0; i < expectedNames.length; i++) {
088: String name = expectedNames[i];
089: assertEquals(expectedDataSet.getTable(name), actualDataSet
090: .getTable(name));
091: }
092:
093: }
094:
095: /**
096: * Asserts that the two specified tables are equals. This method ignore the
097: * table names, the columns order, the columns data type and which columns
098: * are composing the primary keys.
099: */
100: public static void assertEquals(ITable expectedTable,
101: ITable actualTable) throws DatabaseUnitException {
102: logger
103: .debug(
104: "assertEquals(expectedTable={}, actualTable={}) - start",
105: expectedTable, actualTable);
106:
107: // Do not continue if same instance
108: if (expectedTable == actualTable) {
109: return;
110: }
111:
112: ITableMetaData expectedMetaData = expectedTable
113: .getTableMetaData();
114: ITableMetaData actualMetaData = actualTable.getTableMetaData();
115: String expectedTableName = expectedMetaData.getTableName();
116:
117: // // verify table name
118: // Assert.assertEquals("table name", expectedMetaData.getTableName(),
119: // actualMetaData.getTableName());
120:
121: // Verify columns
122: Column[] expectedColumns = getSortedColumns(expectedMetaData);
123: Column[] actualColumns = getSortedColumns(actualMetaData);
124: Assert.assertEquals("column count (table=" + expectedTableName
125: + ")", expectedColumns.length, actualColumns.length);
126:
127: for (int i = 0; i < expectedColumns.length; i++) {
128: String expectedName = expectedColumns[i].getColumnName();
129: String actualName = actualColumns[i].getColumnName();
130: if (!expectedName.equalsIgnoreCase(actualName)) {
131: Assert.fail("expected columns "
132: + getColumnNamesAsString(expectedColumns)
133: + " but was "
134: + getColumnNamesAsString(actualColumns)
135: + " (table=" + expectedTableName + ")");
136: }
137: }
138:
139: // Verify row count
140: Assert.assertEquals("row count (table=" + expectedTableName
141: + ")", expectedTable.getRowCount(), actualTable
142: .getRowCount());
143:
144: // values as strings
145: for (int i = 0; i < expectedTable.getRowCount(); i++) {
146: for (int j = 0; j < expectedColumns.length; j++) {
147: Column expectedColumn = expectedColumns[j];
148: Column actualColumn = actualColumns[j];
149:
150: String columnName = expectedColumn.getColumnName();
151: Object expectedValue = expectedTable.getValue(i,
152: columnName);
153: Object actualValue = actualTable
154: .getValue(i, columnName);
155:
156: DataType dataType = getComparisonDataType(
157: expectedTableName, expectedColumn, actualColumn);
158: if (dataType.compare(expectedValue, actualValue) != 0) {
159: Assert.fail("value (table=" + expectedTableName
160: + ", " + "row=" + i + ", col=" + columnName
161: + "): expected:<" + expectedValue
162: + "> but was:<" + actualValue + ">");
163: }
164: }
165: }
166: }
167:
168: static DataType getComparisonDataType(String tableName,
169: Column expectedColumn, Column actualColumn) {
170: logger
171: .debug(
172: "getComparisonDataType(tableName={}, expectedColumn={}, actualColumn={}) - start",
173: new Object[] { tableName, expectedColumn,
174: actualColumn });
175:
176: DataType expectedDataType = expectedColumn.getDataType();
177: DataType actualDataType = actualColumn.getDataType();
178:
179: // The two columns have different data type
180: if (!expectedDataType.getClass().isInstance(actualDataType)) {
181: // Expected column data type is unknown, use actual column data type
182: if (expectedDataType instanceof UnknownDataType) {
183: return actualDataType;
184: }
185:
186: // Actual column data type is unknown, use expected column data type
187: if (actualDataType instanceof UnknownDataType) {
188: return expectedDataType;
189: }
190:
191: // Impossible to determine which data type to use
192: Assert.fail("Incompatible data types: " + expectedDataType
193: + ", " + actualDataType + " (table=" + tableName
194: + ", col=" + expectedColumn.getColumnName() + ")");
195: }
196: // // Both columns have unknown data type, use string comparison
197: // else if (expectedDataType instanceof UnknownDataType)
198: // {
199: // return DataType.LONGVARCHAR;
200: // }
201:
202: // Both columns have same data type, return any one of them
203: return expectedDataType;
204: }
205:
206: private static Column[] getSortedColumns(ITableMetaData metaData)
207: throws DataSetException {
208: logger.debug("getSortedColumns(metaData={}) - start", metaData);
209:
210: Column[] columns = metaData.getColumns();
211: Column[] sortColumns = new Column[columns.length];
212: System.arraycopy(columns, 0, sortColumns, 0, columns.length);
213: Arrays.sort(sortColumns, COLUMN_COMPARATOR);
214: return sortColumns;
215: }
216:
217: private static String getColumnNamesAsString(Column[] columns) {
218: logger.debug("getColumnNamesAsString(columns={}) - start",
219: columns);
220:
221: String[] names = new String[columns.length];
222: for (int i = 0; i < columns.length; i++) {
223: Column column = columns[i];
224: names[i] = column.getColumnName();
225: }
226: return Arrays.asList(names).toString();
227: }
228:
229: private static String[] getSortedUpperTableNames(IDataSet dataSet)
230: throws DataSetException {
231: logger.debug("getSortedUpperTableNames(dataSet={}) - start",
232: dataSet);
233:
234: String[] names = dataSet.getTableNames();
235: for (int i = 0; i < names.length; i++) {
236: names[i] = names[i].toUpperCase();
237: }
238: Arrays.sort(names);
239: return names;
240: }
241:
242: ////////////////////////////////////////////////////////////////////////////
243: // ColumnComparator class
244:
245: private static class ColumnComparator implements Comparator {
246:
247: /**
248: * Logger for this class
249: */
250: private static final Logger logger = LoggerFactory
251: .getLogger(ColumnComparator.class);
252:
253: public int compare(Object o1, Object o2) {
254: logger.debug("compare(o1={}, o2={}) - start", o1, o2);
255:
256: Column column1 = (Column) o1;
257: Column column2 = (Column) o2;
258:
259: String columnName1 = column1.getColumnName();
260: String columnName2 = column2.getColumnName();
261: return columnName1.compareToIgnoreCase(columnName2);
262: }
263: }
264: }
|