View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  
22  package org.dbunit.dataset;
23  
24  import static org.assertj.core.api.Assertions.assertThat;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  
27  import java.util.Arrays;
28  import java.util.LinkedList;
29  import java.util.List;
30  import java.util.stream.Collectors;
31  
32  import org.dbunit.database.AmbiguousTableNameException;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * @author Manuel Laflamme
37   * @version $Revision$
38   * @since Feb 22, 2002
39   */
40  public abstract class AbstractDataSetTest extends AbstractTest
41  {
42  
43      protected int[] getExpectedDuplicateRows()
44      {
45          return new int[] {1, 0, 2};
46      }
47  
48      /**
49       * This method exclude BLOB_TABLE and CLOB_TABLE from the specified dataset
50       * because BLOB and CLOB are not supported by all database vendor. It also
51       * excludes tables used to test identity/generated columns, present across
52       * several - not just one - database environments' DDL and not seeded by
53       * the init dataset, in both their uppercase and lowercase forms: unlike
54       * the other vendors here, PostgreSQL folds unquoted identifiers to
55       * lowercase instead of uppercase. TODO : should be refactored into the
56       * various DatabaseEnvironments!
57       */
58      public static IDataSet removeExtraTestTables(final IDataSet dataSet)
59              throws Exception
60      {
61          String[] names = dataSet.getTableNames();
62  
63          // exclude BLOB_TABLE and CLOB_TABLE from test since not supported by
64          // all database vendor
65          final List<String> nameList = new LinkedList<>(Arrays.asList(names));
66          nameList.remove("BLOB_TABLE");
67          nameList.remove("CLOB_TABLE");
68          nameList.remove("SDO_GEOMETRY_TABLE");
69          nameList.remove("XML_TYPE_TABLE");
70          nameList.remove("DBUNIT.BLOB_TABLE");
71          nameList.remove("DBUNIT.CLOB_TABLE");
72          nameList.remove("DBUNIT.SDO_GEOMETRY");
73          nameList.remove("DBUNIT.XML_TYPE_TABLE");
74          /*
75           * this table shows up on MSSQLServer. It is a user table for storing
76           * diagram information that really should be considered a system table.
77           */
78          nameList.remove("DBUNIT.dtproperties");
79          nameList.remove("dtproperties");
80          /*
81           * these noted in mcr.microsoft.com/mssql/server:2019-latest
82           */
83          nameList.remove("MSreplication_options");
84          final List<String> removeList = nameList.stream()
85                  .filter(t -> t.startsWith("spt")).collect(Collectors.toList());
86          nameList.removeAll(removeList);
87          /*
88           * These tables are created specifically for testing identity columns.
89           * They are not seeded by the init dataset, so ignore them here. Also
90           * remove the lowercase form: unlike the other database vendors,
91           * PostgreSQL folds unquoted identifiers to lowercase instead of
92           * uppercase.
93           */
94          nameList.remove("DBUNIT.IDENTITY_TABLE");
95          nameList.remove("IDENTITY_TABLE");
96          nameList.remove("identity_table");
97          nameList.remove("DBUNIT.TEST_IDENTITY_NOT_PK");
98          nameList.remove("TEST_IDENTITY_NOT_PK");
99          nameList.remove("test_identity_not_pk");
100         /*
101          * This table is created specifically for testing a NOT NULL column
102          * with a database default on HSQLDB. It should be ignored on other
103          * platforms.
104          */
105         nameList.remove("DBUNIT.DEFAULT_VALUE_TABLE");
106         nameList.remove("DEFAULT_VALUE_TABLE");
107 
108         names = nameList.toArray(new String[0]);
109 
110         return new FilteredDataSet(names, dataSet);
111     }
112 
113     protected abstract IDataSet createDataSet() throws Exception;
114 
115     protected abstract IDataSet createDuplicateDataSet() throws Exception;
116 
117     /**
118      * Create a dataset with duplicate tables having different char case in name
119      * 
120      * @return
121      */
122     protected abstract IDataSet createMultipleCaseDuplicateDataSet()
123             throws Exception;
124 
125     protected void assertEqualsTableName(final String mesage,
126             final String expected, final String actual)
127     {
128         assertThat(actual).as(mesage).isEqualTo(expected);
129     }
130 
131     @Test
132     void testGetTableNames_withPopulatedDataSet_returnsAllTableNames() throws Exception
133     {
134         final String[] expected = getExpectedNames();
135         assertContainsIgnoreCase("minimal names subset",
136                 super.getExpectedNames(), expected);
137 
138         final IDataSet dataSet = createDataSet();
139         final String[] names = dataSet.getTableNames();
140 
141         assertThat(names).as("table count").hasSize(expected.length);
142         for (int i = 0; i < expected.length; i++)
143         {
144             assertEqualsTableName("name " + i, expected[i], names[i]);
145         }
146     }
147 
148     @Test
149     void testGetTableNamesDefensiveCopy_onMultipleCalls_returnsNewArrayEachTime() throws Exception
150     {
151         final IDataSet dataSet = createDataSet();
152         assertThat(dataSet.getTableNames()).as("Should not be same intance")
153                 .isNotSameAs(dataSet.getTableNames());
154     }
155 
156     @Test
157     void testGetTable_withKnownTableName_returnsTable() throws Exception
158     {
159         final String[] expected = getExpectedNames();
160 
161         final IDataSet dataSet = createDataSet();
162         for (int i = 0; i < expected.length; i++)
163         {
164             final ITable table = dataSet.getTable(expected[i]);
165             assertEqualsTableName("name " + i, expected[i],
166                     table.getTableMetaData().getTableName());
167         }
168     }
169 
170     @Test
171     void testGetUnknownTable_withUnknownTableName_throwsNoSuchTableException() throws Exception
172     {
173         final IDataSet dataSet = createDataSet();
174         assertThrows(NoSuchTableException.class,
175                 () -> dataSet.getTable("UNKNOWN_TABLE"),
176                 "Should throw a NoSuchTableException");
177 
178     }
179 
180     @Test
181     void testGetTableMetaData_withKnownTableName_returnsMetaData() throws Exception
182     {
183         final String[] expected = getExpectedNames();
184 
185         final IDataSet dataSet = createDataSet();
186         for (int i = 0; i < expected.length; i++)
187         {
188             final ITableMetaData metaData =
189                     dataSet.getTableMetaData(expected[i]);
190             assertEqualsTableName("name " + i, expected[i],
191                     metaData.getTableName());
192         }
193     }
194 
195     @Test
196     void testGetUnknownTableMetaData_withUnknownTableName_throwsNoSuchTableException() throws Exception
197     {
198         final IDataSet dataSet = createDataSet();
199         assertThrows(NoSuchTableException.class,
200                 () -> dataSet.getTableMetaData("UNKNOWN_TABLE"),
201                 "Should throw a NoSuchTableException");
202     }
203 
204     @Test
205     void testGetTables_withPopulatedDataSet_returnsAllTables() throws Exception
206     {
207         final String[] expected = getExpectedNames();
208         assertContainsIgnoreCase("minimal names subset",
209                 super.getExpectedNames(), expected);
210 
211         final IDataSet dataSet = createDataSet();
212         final ITable[] tables = dataSet.getTables();
213         assertThat(tables).as("table count").hasSize(expected.length);
214         for (int i = 0; i < expected.length; i++)
215         {
216             assertEqualsTableName("name " + i, expected[i],
217                     tables[i].getTableMetaData().getTableName());
218         }
219     }
220 
221     @Test
222     public void testGetTablesDefensiveCopy_onMultipleCalls_returnsNewArrayEachTime() throws Exception
223     {
224         final IDataSet dataSet = createDataSet();
225         assertThat(dataSet.getTables()).as("Should not be same instance")
226                 .isNotSameAs(dataSet.getTables());
227     }
228 
229     @Test
230     public void testCreateDuplicateDataSet_withDuplicateTableNames_throwsAmbiguousTableNameException() throws Exception
231     {
232         assertThrows(AmbiguousTableNameException.class, () ->
233         /* IDataSet dataSet = */createDuplicateDataSet(),
234                 "Should throw AmbiguousTableNameException in creation phase");
235 
236     }
237 
238     @Test
239     public void testCreateMultipleCaseDuplicateDataSet_withDuplicateCaseVariantNames_throwsAmbiguousTableNameException() throws Exception
240     {
241         assertThrows(AmbiguousTableNameException.class, () ->
242         /* IDataSet dataSet = */createMultipleCaseDuplicateDataSet(),
243                 "Should throw AmbiguousTableNameException in creation phase");
244     }
245 
246     @Test
247     public void testGetCaseInsensitiveTable_withLowercaseTableName_returnsTable() throws Exception
248     {
249         final String[] expectedNames = getExpectedLowerNames();
250 
251         final IDataSet dataSet = createDataSet();
252         for (int i = 0; i < expectedNames.length; i++)
253         {
254             final String expected = expectedNames[i];
255             final ITable table = dataSet.getTable(expected);
256             final String actual = table.getTableMetaData().getTableName();
257 
258             if (!expected.equalsIgnoreCase(actual))
259             {
260                 assertThat(actual).as("name " + i).isEqualTo(expected);
261             }
262         }
263     }
264 
265     @Test
266     public void testGetCaseInsensitiveTableMetaData_withLowercaseTableName_returnsMetaData() throws Exception
267     {
268         final String[] expectedNames = getExpectedLowerNames();
269         final IDataSet dataSet = createDataSet();
270 
271         for (int i = 0; i < expectedNames.length; i++)
272         {
273             final String expected = expectedNames[i];
274             final ITableMetaData metaData = dataSet.getTableMetaData(expected);
275             final String actual = metaData.getTableName();
276 
277             if (!expected.equalsIgnoreCase(actual))
278             {
279                 assertThat(actual).as("name " + i).isEqualTo(expected);
280             }
281         }
282     }
283 
284     @Test
285     void testIterator_withPopulatedDataSet_iteratesAllTablesInOrder() throws Exception
286     {
287         final String[] expected = getExpectedNames();
288         assertContainsIgnoreCase("minimal names subset",
289                 super.getExpectedNames(), expected);
290 
291         int i = 0;
292         final ITableIterator iterator = createDataSet().iterator();
293         while (iterator.next())
294         {
295             assertEqualsTableName("name " + i, expected[i],
296                     iterator.getTableMetaData().getTableName());
297             i++;
298         }
299         assertThat(i).as("table count").isEqualTo(expected.length);
300     }
301 
302     @Test
303     void testReverseIterator_withPopulatedDataSet_iteratesAllTablesInReverseOrder() throws Exception
304     {
305         final String[] expected =
306                 DataSetUtils.reverseStringArray(getExpectedNames());
307         assertContainsIgnoreCase("minimal names subset",
308                 super.getExpectedNames(), expected);
309 
310         int i = 0;
311         final ITableIterator iterator = createDataSet().reverseIterator();
312         while (iterator.next())
313         {
314             assertEqualsTableName("name " + i, expected[i],
315                     iterator.getTableMetaData().getTableName());
316             i++;
317         }
318         assertThat(i).as("table count").isEqualTo(expected.length);
319     }
320 
321     protected ITable[] createDuplicateTables(final boolean multipleCase)
322             throws AmbiguousTableNameException
323     {
324         final ITable table1 = new DefaultTable("DUPLICATE_TABLE");
325         final ITable table2 = new DefaultTable("EMPTY_TABLE");
326         ITable table3;
327         if (!multipleCase)
328         {
329             table3 = new DefaultTable("DUPLICATE_TABLE");
330         } else
331         {
332             table3 = new DefaultTable("duplicate_TABLE");
333         }
334         final ITable[] tables = new ITable[] {table1, table2, table3};
335         return tables;
336     }
337 }