1 package guru.mikelue.jdut.example;
2
3 import java.sql.Date;
4 import java.sql.SQLException;
5 import java.time.LocalDate;
6 import java.util.HashMap;
7 import java.util.Map;
8 import java.util.function.Supplier;
9
10 import org.apache.commons.lang3.RandomUtils;
11 import org.junit.jupiter.api.AfterEach;
12 import org.junit.jupiter.api.BeforeAll;
13 import org.junit.jupiter.api.BeforeEach;
14 import org.junit.jupiter.api.Test;
15 import org.junit.jupiter.api.TestInfo;
16
17 import guru.mikelue.jdut.DataConductor;
18 import guru.mikelue.jdut.annotation.IfDatabaseVendor;
19 import guru.mikelue.jdut.assertion.ResultSetAssert;
20 import guru.mikelue.jdut.datagrain.DataGrain;
21 import guru.mikelue.jdut.jdbc.JdbcTemplateFactory;
22 import guru.mikelue.jdut.jdbc.function.DbResultSet;
23 import guru.mikelue.jdut.operation.DefaultOperatorFactory;
24 import guru.mikelue.jdut.operation.DefaultOperators;
25 import guru.mikelue.jdut.operation.OperatorFactory;
26 import guru.mikelue.jdut.test.AbstractDataSourceTestBase;
27 import guru.mikelue.jdut.vendor.DatabaseVendor;
28
29 import static org.junit.jupiter.api.Assertions.*;
30
31
32
33
34 @IfDatabaseVendor(match=DatabaseVendor.H2)
35 public class JdbcExampleTest extends AbstractDataSourceTestBase {
36 private static ExampleDao testedDao;
37 private static DataConductor dataConductor;
38 private static OperatorFactory operatorFactory;
39
40 private final String INSERT_ARTIST_NAME = "Miles Davis";
41 private final String UPDATE_ARTIST_NAME = "John Coltrane";
42 private final String REMOVE_ARTIST_NAME = "Blue Mountain";
43
44 private DataGrain dataGrainForUpdate;
45
46 private DataGrain dataGrain_1ForListing;
47 private DataGrain dataGrain_2ForListing;
48
49 private Map<String, Runnable> setupFunctions = new HashMap<>();
50 private Map<String, Runnable> tearDownFunctions = new HashMap<>();
51
52 public JdbcExampleTest()
53 {
54 setupFunctions.put("updateArtistName", this::setupUpdateArtistName);
55 tearDownFunctions.put("updateArtistName", this::tearDownUpdateArtistName);
56
57 setupFunctions.put("countAlbumsByType", this::setupCountAlbumsByType);
58 tearDownFunctions.put("countAlbumsByType", this::tearDownCountAlbumsByType);
59
60 setupFunctions.put("removeArtistByName", this::setupRemoveArtistByName);
61
62 tearDownFunctions.put("addArtist", this::tearDownAddArtist);
63 }
64
65 @BeforeAll
66 void setupDatabaseSchema()
67 {
68 SchemaSetup.buildSchema(getDataSource());
69
70 testedDao = new ExampleDao(getDataSource());
71
72 dataConductor = new DataConductor(getDataSource());
73 operatorFactory = DefaultOperatorFactory.build(getDataSource());
74 }
75
76 @BeforeEach
77 void setupTest(TestInfo testInfo)
78 {
79 runByMethodName(testInfo, setupFunctions);
80 }
81 @AfterEach
82 void tearDownTest(TestInfo testInfo)
83 {
84 runByMethodName(testInfo, tearDownFunctions);
85 }
86
87 private void runByMethodName(TestInfo testInfo, Map<String, Runnable> funcs)
88 {
89 Runnable r = funcs.get(
90 testInfo.getTestMethod().get().getName()
91 );
92
93 if (r != null) {
94 r.run();
95 }
96 }
97
98 @Test
99 void addArtist() throws SQLException
100 {
101 testedDao.addArtist(INSERT_ARTIST_NAME);
102
103 JdbcTemplateFactory.buildRunnable(
104 () -> getDataSource().getConnection(),
105 conn -> DbResultSet.buildRunnable(
106 conn,
107 "SELECT COUNT(*) FROM ex_artist WHERE at_name = '" + INSERT_ARTIST_NAME + "'",
108 rs -> new ResultSetAssert(rs)
109 .assertNextTrue()
110 .assertInt(1, 1)
111 ).runJdbc()
112 ).runJdbc();
113 }
114 private void tearDownAddArtist()
115 {
116 dataConductor.conduct(
117 DataGrain.build(
118 builder ->
119 builder.name("ex_artist").keys("at_name"),
120 rowsBuilder -> rowsBuilder
121 .addFields(rowsBuilder.newField("at_name", INSERT_ARTIST_NAME))
122 ),
123 operatorFactory.get(DefaultOperators.DELETE)
124 );
125 }
126
127
128
129
130 @Test
131 void updateArtistName() throws SQLException
132 {
133 testedDao.updateArtistName(1001, UPDATE_ARTIST_NAME);
134
135 JdbcTemplateFactory.buildRunnable(
136 () -> getDataSource().getConnection(),
137 conn -> DbResultSet.buildRunnable(
138 conn,
139 "SELECT COUNT(*) FROM ex_artist WHERE at_name = '" + UPDATE_ARTIST_NAME + "'",
140 rs -> new ResultSetAssert(rs)
141 .assertNextTrue()
142 .assertInt(1, 1)
143 ).runJdbc()
144 ).runJdbc();
145 }
146 private void setupUpdateArtistName()
147 {
148 dataGrainForUpdate = DataGrain.build(
149 builder ->
150 builder.name("ex_artist"),
151 rowsBuilder -> rowsBuilder
152 .implicitColumns("at_id", "at_name")
153 .addValues(
154 1001, "Dizzy Gillespie"
155 )
156 );
157
158 dataConductor.conduct(
159 dataGrainForUpdate,
160 operatorFactory.get(DefaultOperators.REFRESH)
161 );
162 }
163 private void tearDownUpdateArtistName()
164 {
165 dataConductor.conduct(
166 dataGrainForUpdate,
167 operatorFactory.get(DefaultOperators.DELETE)
168 );
169 }
170
171 @Test
172 void removeArtistByName() throws SQLException
173 {
174 testedDao.removeArtistByName(REMOVE_ARTIST_NAME);
175
176 JdbcTemplateFactory.buildRunnable(
177 () -> getDataSource().getConnection(),
178 conn -> DbResultSet.buildRunnable(
179 conn,
180 "SELECT COUNT(*) FROM ex_artist WHERE at_name = '" + REMOVE_ARTIST_NAME + "'",
181 rs -> new ResultSetAssert(rs)
182 .assertNextTrue()
183 .assertInt(1, 0)
184 ).runJdbc()
185 ).runJdbc();
186 }
187 private void setupRemoveArtistByName()
188 {
189 dataConductor.conduct(
190 DataGrain.build(
191 builder -> builder.name("ex_artist"),
192 rowsBuilder -> rowsBuilder
193 .addFields(
194 rowsBuilder.newField("at_name", REMOVE_ARTIST_NAME)
195 )
196 ),
197 operatorFactory.get(DefaultOperators.INSERT)
198 );
199 }
200
201 @Test
202 void countAlbumsByType() throws SQLException
203 {
204 assertEquals(
205 2,
206 testedDao.countAlbumsByType(1)
207 );
208 }
209 private void setupCountAlbumsByType()
210 {
211 int idOfArtistForListing = 9081;
212
213
214
215
216 Supplier<Date> randomDate = JdbcExampleTest::randomDate;
217 Supplier<Integer> randomDuration = JdbcExampleTest::randomDuration;
218
219
220
221
222
223 dataConductor.conduct(
224 dataGrain_1ForListing = DataGrain.build(
225 builder -> builder.name("ex_artist"),
226 rowsBuilder -> rowsBuilder
227 .implicitColumns("at_id", "at_name")
228 .addValues(idOfArtistForListing, "Sonny Rollins")
229 ),
230 operatorFactory.get(DefaultOperators.INSERT)
231 );
232
233
234
235
236 dataConductor.conduct(
237 dataGrain_2ForListing = DataGrain.build(
238 builder -> builder.name("ex_album"),
239 rowsBuilder -> rowsBuilder
240 .implicitColumns(
241 "ab_id", "ab_name", "ab_release_date", "ab_duration_seconds", "ab_type", "ab_at_id"
242 )
243 .addValues(
244 4051, "No. 1", randomDate, randomDuration,
245 1,
246 idOfArtistForListing
247 )
248 .addValues(
249 4052, "No. 2", randomDate, randomDuration,
250 2,
251 idOfArtistForListing
252 )
253 .addValues(
254 4053, "No. 3", randomDate, randomDuration,
255 3,
256 idOfArtistForListing
257 )
258 .addValues(
259 4054, "No. 4", randomDate, randomDuration,
260 1,
261 idOfArtistForListing
262 )
263 ),
264 operatorFactory.get(DefaultOperators.INSERT)
265 );
266
267 }
268 private void tearDownCountAlbumsByType()
269 {
270 dataConductor.conduct(
271 dataGrain_2ForListing,
272 operatorFactory.get(DefaultOperators.DELETE)
273 );
274 dataConductor.conduct(
275 dataGrain_1ForListing,
276 operatorFactory.get(DefaultOperators.DELETE)
277 );
278 }
279
280 private static Date randomDate()
281 {
282 return Date.valueOf(
283 LocalDate.of(
284 RandomUtils.nextInt(1950, 1961),
285 RandomUtils.nextInt(1, 13),
286 RandomUtils.nextInt(1, 26)
287 )
288 );
289 }
290
291 private static int randomDuration()
292 {
293 return RandomUtils.nextInt(1800, 10801);
294 }
295 }