1. Project Clover database Wed Nov 12 2025 05:07:35 UTC
  2. Package guru.mikelue.foxglove.springframework

File SpringContextObjectFactoryTest.java

 

Code metrics

0
58
31
8
365
284
33
0.57
1.87
3.88
1.06

Classes

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