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    *     http://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       * Returns a mock builder which always returns the specified configuration.
51       *
52       * @param conf the builder's result configuration
53       * @return the mock builder
54       */
55      private ConfigurationBuilder<BaseHierarchicalConfiguration> createBuilderMock(final BaseHierarchicalConfiguration conf) {
56          @SuppressWarnings("unchecked")
57          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = mock(ConfigurationBuilder.class);
58          assertDoesNotThrow(() -> when(builder.getConfiguration()).thenReturn(conf));
59          return builder;
60      }
61  
62      /**
63       * Tests whether the returned configuration correctly wraps the builder.
64       */
65      @Test
66      public void testConfigurationBuilderWrapper() {
67          final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
68          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
69          conf.addProperty("test1", "value1");
70          conf.addProperty("test2", "42");
71          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
72          final HierarchicalConfiguration<?> wrapper = factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
73          assertEquals("value1", wrapper.getString("test1"));
74          assertEquals(42, wrapper.getInt("test2"));
75          assertSame(conf.getNodeModel().getNodeHandler().getRootNode(), wrapper.getNodeModel().getNodeHandler().getRootNode());
76      }
77  
78      /**
79       * Tries to create a wrapper without passing a builder.
80       */
81      @Test
82      public void testCreateBuilderConfigurationWrapperNoBuilder() {
83          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
84          assertThrows(IllegalArgumentException.class, () -> factory.createBuilderConfigurationWrapper(Configuration.class, null));
85      }
86  
87      /**
88       * Tries to create a wrapper without passing an interface class.
89       */
90      @Test
91      public void testCreateBuilderConfigurationWrapperNoClass() {
92          final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
93          final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(new BaseHierarchicalConfiguration());
94          assertThrows(IllegalArgumentException.class, () -> factory.createBuilderConfigurationWrapper(null, builder));
95  
96          verifyNoInteractions(builder);
97      }
98  
99      /**
100      * Tests the default event source support level.
101      */
102     @Test
103     public void testDefaultEventSourceSupport() {
104         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
105         assertEquals(EventSourceSupport.NONE, factory.getEventSourceSupport());
106     }
107 
108     /**
109      * Tests whether EventSource methods can be delegated to the builder.
110      */
111     @Test
112     public void testEventSourceSupportBuilder() throws ConfigurationException {
113         final BasicConfigurationBuilder<PropertiesConfiguration> builder = new BasicConfigurationBuilder<>(PropertiesConfiguration.class);
114         final EventListener<ConfigurationEvent> l1 = new EventListenerTestImpl(null);
115         final EventListener<ConfigurationEvent> l2 = new EventListenerTestImpl(null);
116         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
117         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(Configuration.class, builder);
118 
119         src.addEventListener(ConfigurationEvent.ANY, l1);
120         src.addEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2);
121         assertTrue(src.removeEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2));
122         assertFalse(src.removeEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2));
123         final PropertiesConfiguration config = builder.getConfiguration();
124         final Collection<EventListener<? super ConfigurationEvent>> listeners = config.getEventListeners(ConfigurationEvent.ANY_HIERARCHICAL);
125         assertTrue(listeners.contains(l1));
126         assertFalse(listeners.contains(l2));
127     }
128 
129     /**
130      * Tests the EventSource support level 'dummy'.
131      */
132     @Test
133     public void testEventSourceSupportDummy() {
134         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
135         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
136         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.DUMMY);
137         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
138         src.addEventListener(ConfigurationEvent.ANY, null);
139 
140         verifyNoInteractions(builder);
141     }
142 
143     /**
144      * Tests whether event source support of level builder is possible even for a mock builder.
145      */
146     @Test
147     public void testEventSourceSupportMockBuilder() {
148         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
149         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
150         final EventListenerTestImpl listener = new EventListenerTestImpl(null);
151 
152         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory(EventSourceSupport.BUILDER);
153         final EventSource src = (EventSource) factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
154         src.addEventListener(ConfigurationEvent.ANY, listener);
155 
156         verify(builder).addEventListener(ConfigurationEvent.ANY, listener);
157         verifyNoMoreInteractions(builder);
158     }
159 
160     /**
161      * Tests the factory if support for EventSource is disabled.
162      */
163     @Test
164     public void testEventSourceSupportNone() {
165         final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
166         final ConfigurationBuilder<BaseHierarchicalConfiguration> builder = createBuilderMock(conf);
167         final BuilderConfigurationWrapperFactory factory = new BuilderConfigurationWrapperFactory();
168         final HierarchicalConfiguration<?> wrapper = factory.createBuilderConfigurationWrapper(HierarchicalConfiguration.class, builder);
169         assertFalse(wrapper instanceof EventSource);
170     }
171 }