View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.builder;
18  
19  import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertSame;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  import static org.mockito.Mockito.mock;
26  import static org.mockito.Mockito.verify;
27  import static org.mockito.Mockito.verifyNoInteractions;
28  import static org.mockito.Mockito.verifyNoMoreInteractions;
29  import static org.mockito.Mockito.when;
30  
31  import java.util.Collection;
32  
33  import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
34  import org.apache.commons.configuration2.Configuration;
35  import org.apache.commons.configuration2.HierarchicalConfiguration;
36  import org.apache.commons.configuration2.PropertiesConfiguration;
37  import org.apache.commons.configuration2.builder.BuilderConfigurationWrapperFactory.EventSourceSupport;
38  import org.apache.commons.configuration2.event.ConfigurationEvent;
39  import org.apache.commons.configuration2.event.EventListener;
40  import org.apache.commons.configuration2.event.EventListenerTestImpl;
41  import org.apache.commons.configuration2.event.EventSource;
42  import org.apache.commons.configuration2.ex.ConfigurationException;
43  import org.junit.jupiter.api.Test;
44  
45  /**
46   * Test class for {@code BuilderConfigurationWrapperFactory}.
47   */
48  public class TestBuilderConfigurationWrapperFactory {
49  
50      /**
51       * Returns a mock builder which always returns the specified configuration.
52       *
53       * @param conf the builder's result configuration
54       * @return the mock builder
55       */
56      private ConfigurationBuilder<BaseHierarchicalConfiguration> createBuilderMock(final BaseHierarchicalConfiguration conf) {
57          @SuppressWarnings("unchecked")
58          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = mock(ConfigurationBuilder.class);
59          assertDoesNotThrow(() -> when(builder.getConfiguration()).thenReturn(conf));
60          return builder;
61      }
62  
63      /**
64       * Tests whether the returned configuration correctly wraps the builder.
65       */
66      @Test
67      void testConfigurationBuilderWrapper() {
68          final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
69          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
70          conf.addProperty("test1", "value1");
71          conf.addProperty("test2", "42");
72          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
73          final HierarchicalConfiguration<?> wrapper = factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
74          assertEquals("value1", wrapper.getString("test1"));
75          assertEquals(42, wrapper.getInt("test2"));
76          assertSame(conf.getNodeModel().getNodeHandler().getRootNode(), wrapper.getNodeModel().getNodeHandler().getRootNode());
77      }
78  
79      /**
80       * Tries to create a wrapper without passing a builder.
81       */
82      @Test
83      void testCreateBuilderConfigurationWrapperNoBuilder() {
84          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
85          assertThrows(IllegalArgumentException.class, () -> factory.createBuilderConfigurationWrapper(Configuration.class, null));
86      }
87  
88      /**
89       * Tries to create a wrapper without passing an interface class.
90       */
91      @Test
92      void testCreateBuilderConfigurationWrapperNoClass() {
93          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
94          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(new BaseHierarchicalConfiguration());
95          assertThrows(IllegalArgumentException.class, () -> factory.createBuilderConfigurationWrapper(null, builder));
96  
97          verifyNoInteractions(builder);
98      }
99  
100     /**
101      * Tests the default event source support level.
102      */
103     @Test
104     void testDefaultEventSourceSupport() {
105         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
106         assertEquals(EventSourceSupport.NONE, factory.getEventSourceSupport());
107     }
108 
109     /**
110      * Tests whether EventSource methods can be delegated to the builder.
111      */
112     @Test
113     void testEventSourceSupportBuilder() throws ConfigurationException {
114         final BasicConfigurationBuilder<PropertiesConfiguration> builder = new BasicConfigurationBuilder<>(PropertiesConfiguration.class);
115         final EventListener<ConfigurationEvent> l1 = new EventListenerTestImpl(null);
116         final EventListener<ConfigurationEvent> l2 = new EventListenerTestImpl(null);
117         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
118         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(Configuration.class, builder);
119 
120         src.addEventListener(ConfigurationEvent.ANY, l1);
121         src.addEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2);
122         assertTrue(src.removeEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2));
123         assertFalse(src.removeEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2));
124         final PropertiesConfiguration config = builder.getConfiguration();
125         final Collection<EventListener<? super ConfigurationEvent>> listeners = config.getEventListeners(ConfigurationEvent.ANY_HIERARCHICAL);
126         assertTrue(listeners.contains(l1));
127         assertFalse(listeners.contains(l2));
128     }
129 
130     /**
131      * Tests the EventSource support level 'dummy'.
132      */
133     @Test
134     void testEventSourceSupportDummy() {
135         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
136         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
137         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.DUMMY);
138         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
139         src.addEventListener(ConfigurationEvent.ANY, null);
140 
141         verifyNoInteractions(builder);
142     }
143 
144     /**
145      * Tests whether event source support of level builder is possible even for a mock builder.
146      */
147     @Test
148     void testEventSourceSupportMockBuilder() {
149         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
150         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
151         final EventListenerTestImpl listener = new EventListenerTestImpl(null);
152 
153         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
154         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
155         src.addEventListener(ConfigurationEvent.ANY, listener);
156 
157         verify(builder).addEventListener(ConfigurationEvent.ANY, listener);
158         verifyNoMoreInteractions(builder);
159     }
160 
161     /**
162      * Tests the factory if support for EventSource is disabled.
163      */
164     @Test
165     void testEventSourceSupportNone() {
166         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
167         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
168         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
169         final HierarchicalConfiguration<?> wrapper = factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
170         assertFalse(wrapper instanceof EventSource);
171     }
172 }