1. Project Clover database Sat Mar 14 2026 10:11:54 UTC
  2. Package guru.mikelue.foxglove.springframework

File SpringContextObjectFactoryTest.java

 

Code metrics

0
58
31
8
366
284
33
0.57
1.87
3.88
1.06

Classes

Class Line # Actions
SpringContextObjectFactoryTest 43 43 0% 14 0
1.0100%
GenDataCases 234 0 0% 4 4
0.00%
EmptyConfig 258 0 - 0 0
-1.0 -
DataSourceSpringContext 263 0 - 0 0
-1.0 -
SpringProvidingConfig 266 9 0% 9 0
1.0100%
SpringProvidingConfig.RedDataGeneratorProvider 272 1 0% 1 0
1.0100%
SpringProvidingConfig.RedTableFacetProvider 279 1 0% 1 0
1.0100%
FakeDataGenerator 342 4 0% 4 4
0.550%
 

Contributing tests

This file is covered by 11 tests. .

Source view

1    package guru.mikelue.foxglove.springframework;
2   
3    import java.util.List;
4    import java.util.stream.Stream;
5   
6    import javax.sql.DataSource;
7   
8    import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
9    import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
10    import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
11    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
12    import org.springframework.context.annotation.Bean;
13    import org.springframework.context.annotation.Configuration;
14    import org.springframework.context.annotation.Primary;
15   
16    import org.apache.commons.lang3.reflect.MethodUtils;
17    import org.junit.jupiter.api.AfterEach;
18    import org.junit.jupiter.api.BeforeEach;
19    import org.junit.jupiter.api.Test;
20    import org.junit.jupiter.params.ParameterizedTest;
21    import org.junit.jupiter.params.provider.CsvSource;
22    import org.junit.jupiter.params.provider.ValueSource;
23   
24    import guru.mikelue.misc.testlib.AbstractTestBase;
25   
26    import guru.mikelue.foxglove.DataGenerator;
27    import guru.mikelue.foxglove.TableFacet;
28    import guru.mikelue.foxglove.annotation.DataGenContext;
29    import guru.mikelue.foxglove.annotation.DataGeneratorSource;
30    import guru.mikelue.foxglove.annotation.GenData;
31    import guru.mikelue.foxglove.annotation.TableFacetsSource;
32    import guru.mikelue.foxglove.functional.DataGeneratorProvider;
33    import guru.mikelue.foxglove.functional.TableFacetProvider;
34    import guru.mikelue.foxglove.functional.TableFacetsProvider;
35    import guru.mikelue.foxglove.jdbc.JdbcTableFacet;
36    import guru.mikelue.foxglove.setting.DataSettingInfo;
37   
38    import mockit.Mocked;
39    import mockit.Verifications;
40   
41    import static org.assertj.core.api.Assertions.assertThat;
42   
 
43    public class SpringContextObjectFactoryTest extends AbstractTestBase {
44    @Mocked
45    private DataGenContext<TableFacet> mockDataGenContext;
46   
47    private static DataGenContext<TableFacet> dataGenContext =
48    DataGenContext.loadFrom(SpringContextObjectFactoryTest.class);
49   
50    @DataGeneratorSource
51    private DataGenerator<TableFacet> defaultDataGenerator = new FakeDataGenerator();
52   
53    @TableFacetsSource
54    private TableFacet defaultFacet = JdbcTableFacet.builder("TABLE_DEFAULT")
55    .column("col_default").fixed("default")
56    .numberOfRows(3)
57    .build();
58   
 
59  11 toggle public SpringContextObjectFactoryTest() {}
60   
 
61  11 toggle @BeforeEach
62    void setup() {}
63   
 
64  11 toggle @AfterEach
65    void tearDown() {}
66   
67    /**
68    * Tests the fallback to field-defined {@link DataGenerator}.
69    */
 
70  1 toggle @Test
71    void fallbackToDefaultDataGenerator() throws Exception
72    {
73  1 var appContext = new AnnotationConfigApplicationContext(EmptyConfig.class);
74   
75  1 var testedFactory = new SpringContextObjectFactory(
76    appContext, this, getByMethod("defaultMethod"),
77    dataGenContext, "defaultMethod"
78    );
79   
80  1 var testedGenerator = (FakeDataGenerator)testedFactory.getDataGenerator();
81  1 assertThat(testedGenerator.id)
82    .isEqualTo(-1);
83    }
84   
85    /**
86    * Tests the getting of {@link DataGenerator} for various cases.
87    */
 
88  4 toggle @ParameterizedTest
89    @ValueSource(strings = {
90    "defaultMethod",
91    "nameSourceByProvider",
92    "namedSourcesByObject",
93    "typedSources"
94    })
95    void getDataGeneratorBySpring(
96    String methodName
97    ) throws Exception {
98  4 var appContext = new AnnotationConfigApplicationContext(SpringProvidingConfig.class);
99  4 var sampleTestingObject = new Object();
100   
101  4 var testedFactory = new SpringContextObjectFactory(
102    appContext, sampleTestingObject, getByMethod(methodName),
103    mockDataGenContext, methodName
104    );
105   
106    /*
107    * Asserts the generator comes from Spring context
108    */
109  4 var testedGenerator = (FakeDataGenerator)testedFactory.getDataGenerator();
110  4 assertThat(testedGenerator.id)
111    .isEqualTo(1);
112    // :~)
113   
114  4 verifyNoneOfDataGenContextCalled(sampleTestingObject);
115    }
116   
117    /**
118    * Tests the auto-constructed of {@link DataGenerator} by {@link DataSource}.
119    */
 
120  1 toggle @Test
121    void autoDataGeneratorByDataSource() throws Exception
122    {
123  1 var sampleTestingObject = new Object();
124   
125  1 DataGenerator<TableFacet> testedGenerator;
126   
127  1 try (var appContext = new AnnotationConfigApplicationContext(DataSourceSpringContext.class)) {
128  1 var testedFactory = new SpringContextObjectFactory(
129    appContext, sampleTestingObject, getByMethod("defaultMethod"),
130    mockDataGenContext, "defaultMethod"
131    );
132   
133  1 testedGenerator = testedFactory.getDataGenerator();
134    }
135   
136  1 assertThat(testedGenerator)
137    .isNotInstanceOf(FakeDataGenerator.class);
138   
139  1 verifyNoneOfDataGenContextCalled(sampleTestingObject);
140    }
141   
 
142  5 toggle @SuppressWarnings({ "unchecked" })
143    private void verifyNoneOfDataGenContextCalled(Object sampleTestingObject)
144    {
 
145  5 toggle new Verifications() {{
146  5 mockDataGenContext.getDefaultDataGenerator(sampleTestingObject);
147  5 times = 0;
148   
149  5 mockDataGenContext.getTypedDataGenerator(
150    (Class<DataGeneratorProvider<TableFacet>>)any, sampleTestingObject
151    );
152  5 times = 0;
153   
154  5 mockDataGenContext.getNamedDataGenerator(
155    anyString, sampleTestingObject
156    );
157  5 times = 0;
158    }};
159    }
160   
161    /**
162    * Tests the fallback to {@link TableFacet}s defined by testing class.
163    */
 
164  1 toggle @Test
165    void fallbackToDefaultTableFacet() throws Exception
166    {
167  1 var appContext = new AnnotationConfigApplicationContext(EmptyConfig.class);
168   
169  1 var testedFactory = new SpringContextObjectFactory(
170    appContext, this, getByMethod("defaultMethod"),
171    dataGenContext, "defaultMethod"
172    );
173   
174  1 var testedGenerator = testedFactory.getTableFacets();
175  1 assertThat(testedGenerator)
176    .element(0)
177    .extracting(t -> t.getNumberOfRows())
178    .isEqualTo(3);
179    }
180   
181    /**
182    * Tests the getting of {@link TableFacet}s list from Spring's context.
183    */
 
184  4 toggle @SuppressWarnings("unchecked")
185    @ParameterizedTest
186    @CsvSource({
187    "defaultMethod,1",
188    "nameSourceByProvider,4",
189    "namedSourcesByObject,4",
190    "typedSources,1",
191    })
192    void getTableFacetsBySpring(
193    String methodName, int expectedSize
194    ) throws Exception {
195  4 var appContext = new AnnotationConfigApplicationContext(SpringProvidingConfig.class);
196  4 var sampleTestingObject = new Object();
197   
198  4 var testedFactory = new SpringContextObjectFactory(
199    appContext, sampleTestingObject, getByMethod(methodName),
200    mockDataGenContext, methodName
201    );
202   
203  4 var testedFacets = testedFactory.getTableFacets();
204  4 assertThat(testedFacets)
205    .hasSize(expectedSize)
206    .allSatisfy(t -> {
207  10 assertThat(t.getNumberOfRows())
208    .isEqualTo(5);
209    });
210   
 
211  4 toggle new Verifications() {{
212  4 mockDataGenContext.getDefaultTableFacets(sampleTestingObject);
213  4 times = 0;
214   
215  4 mockDataGenContext.getTypedTableFacets(
216    (Class<? extends TableFacetsProvider<TableFacet>>)any, methodName
217    );
218  4 times = 0;
219   
220  4 mockDataGenContext.getNamedTableFacets(anyString, sampleTestingObject);
221  4 times = 0;
222    }};
223    }
224   
 
225  11 toggle private static GenData getByMethod(String methodName)
226    {
227  11 return MethodUtils.getMatchingMethod(
228    GenDataCases.class, methodName
229    )
230    .getAnnotation(GenData.class);
231    }
232    }
233   
 
234    class GenDataCases {
 
235  0 toggle @GenData
236    void defaultMethod() {}
237   
 
238  0 toggle @GenData(
239    generatorName = "redDataGenerator",
240    facetsNames = { "redTableFacet", "tableFacetOfList", "tableFacetOfArray", "tableFacetOfStream" }
241    )
242    void nameSourceByProvider() {}
243   
 
244  0 toggle @GenData(
245    generatorName = "blueDataGenerator",
246    facetsNames = { "blueTableFacet", "tableFacetOfList", "tableFacetOfArray", "tableFacetOfStream" }
247    )
248    void namedSourcesByObject() {}
249   
 
250  0 toggle @GenData(
251    generator = SpringProvidingConfig.RedDataGeneratorProvider.class,
252    facets = { SpringProvidingConfig.RedTableFacetProvider.class }
253    )
254    void typedSources() {}
255    }
256   
257    @Configuration
 
258    class EmptyConfig {}
259   
260    @JdbcTest
261    @AutoConfigureTestDatabase(replace = Replace.NONE)
262    @Configuration
 
263    class DataSourceSpringContext {}
264   
265    @Configuration
 
266    class SpringProvidingConfig {
267    static TableFacet sampleFacet = JdbcTableFacet.builder("TABLE_SAMPLE")
268    .column("col_sample").fixed("sample")
269    .numberOfRows(5)
270    .build();
271   
 
272    static class RedDataGeneratorProvider implements DataGeneratorProvider<TableFacet> {
 
273  2 toggle @Override
274    public DataGenerator<TableFacet> get()
275    {
276  2 return new FakeDataGenerator(1);
277    }
278    }
 
279    static class RedTableFacetProvider implements TableFacetProvider<TableFacet> {
 
280  2 toggle @Override
281    public TableFacet getOne()
282    {
283  2 return sampleFacet;
284    }
285    }
286   
 
287  8 toggle @Primary @Bean
288    TableFacetProvider<TableFacet> defaultTableFacets()
289    {
290  8 return () -> sampleFacet;
291    }
292   
 
293  8 toggle @Primary @Bean
294    DataGeneratorProvider<?> dataGeneratorProvider()
295    {
296  8 return () -> new FakeDataGenerator(1);
297    }
298   
 
299  8 toggle @Bean("redDataGenerator")
300    RedDataGeneratorProvider redDataGeneratorProvider()
301    {
302  8 return new RedDataGeneratorProvider();
303    }
304   
 
305  8 toggle @Bean("blueDataGenerator")
306    DataGenerator<?> blueDataGenerator()
307    {
308  8 return new FakeDataGenerator(1);
309    }
310   
 
311  8 toggle @Bean("redTableFacet")
312    RedTableFacetProvider redTableFacet()
313    {
314  8 return new RedTableFacetProvider();
315    }
316   
 
317  8 toggle @Bean("blueTableFacet")
318    TableFacet blueTableFacet()
319    {
320  8 return sampleFacet;
321    }
322   
 
323  8 toggle @Bean("tableFacetOfArray")
324    TableFacet[] tableFacetOfArray()
325    {
326  8 return new TableFacet[] { sampleFacet };
327    }
328   
 
329  8 toggle @Bean("tableFacetOfList")
330    List<TableFacet> tableFacetOfList()
331    {
332  8 return List.of(sampleFacet);
333    }
334   
 
335  8 toggle @Bean("tableFacetOfStream")
336    Stream<TableFacet> tableFacetOfStream()
337    {
338  8 return Stream.of(sampleFacet);
339    }
340    }
341   
 
342    class FakeDataGenerator implements DataGenerator<TableFacet> {
343    final int id;
344   
 
345  11 toggle FakeDataGenerator()
346    {
347  11 this(-1);
348    }
349   
 
350  22 toggle FakeDataGenerator(int id)
351    {
352  22 this.id = id;
353    }
354   
 
355  0 toggle @Override
356    public FakeDataGenerator withSetting(DataSettingInfo setting)
357    {
358  0 throw new UnsupportedOperationException("Unimplemented method 'withSetting'");
359    }
360   
 
361  0 toggle @Override
362    public int generate(List<TableFacet> tables)
363    {
364  0 throw new UnsupportedOperationException("Unimplemented method 'generate'");
365    }
366    }