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.io;
18  
19  import static org.junit.jupiter.api.Assertions.assertIterableEquals;
20  import static org.junit.jupiter.api.Assertions.assertNull;
21  import static org.junit.jupiter.api.Assertions.assertSame;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.mockito.Mockito.mock;
24  import static org.mockito.Mockito.verify;
25  import static org.mockito.Mockito.verifyNoMoreInteractions;
26  import static org.mockito.Mockito.when;
27  
28  import java.net.URL;
29  import java.util.Arrays;
30  import java.util.Collection;
31  import java.util.LinkedList;
32  
33  import org.apache.commons.configuration2.ConfigurationAssert;
34  import org.junit.jupiter.api.BeforeAll;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Test class for {@code CombinedLocationStrategy}.
39   */
40  public class TestCombinedLocationStrategy {
41      /** A test locator. */
42      private static FileLocator locator;
43  
44      /** A URL indicating a successful locate() operation. */
45      private static URL locateURL;
46  
47      @BeforeAll
48      public static void setUpOnce() throws Exception {
49          locator = FileLocatorUtils.fileLocator().fileName("testFile.tst").create();
50          locateURL = ConfigurationAssert.getTestURL("test.xml");
51      }
52  
53      /** A mock for the file system. */
54      private FileSystem fileSystem;
55  
56      /** An array with mock sub strategies. */
57      private FileLocationStrategy[] subStrategies;
58  
59      /**
60       * Checks whether the passed in combined strategy contains the expected sub strategies.
61       *
62       * @param strategy the combined strategy to check
63       */
64      private void checkSubStrategies(final CombinedLocationStrategy strategy) {
65          final Collection<FileLocationStrategy> subs = strategy.getSubStrategies();
66          assertIterableEquals(Arrays.asList(getSubStrategies()), subs);
67      }
68  
69      /**
70       * Helper method for creating a combined strategy with the mock sub strategies.
71       *
72       * @return the newly created combined strategy
73       */
74      private CombinedLocationStrategy createCombinedStrategy() {
75          return new CombinedLocationStrategy(Arrays.asList(getSubStrategies()));
76      }
77  
78      /**
79       * Returns the mock file system. It is created on demand.
80       *
81       * @return the mock file system
82       */
83      private FileSystem getFileSystem() {
84          if (fileSystem == null) {
85              fileSystem = mock(FileSystem.class);
86          }
87          return fileSystem;
88      }
89  
90      /**
91       * Returns an array with mock objects for sub strategies.
92       *
93       * @return the array with mock strategies
94       */
95      private FileLocationStrategy[] getSubStrategies() {
96          if (subStrategies == null) {
97              subStrategies = new FileLocationStrategy[2];
98              for (int i = 0; i < subStrategies.length; i++) {
99                  subStrategies[i] = mock(FileLocationStrategy.class);
100             }
101         }
102         return subStrategies;
103     }
104 
105     /**
106      * Tests that the collection with sub strategies cannot be modified.
107      */
108     @Test
109     public void testGetSubStrategiesModify() {
110         final CombinedLocationStrategy strategy = createCombinedStrategy();
111         final Collection<FileLocationStrategy> strategies = strategy.getSubStrategies();
112         assertThrows(UnsupportedOperationException.class, strategies::clear);
113     }
114 
115     /**
116      * Tries to create an instance containing a null element.
117      */
118     @Test
119     public void testInitCollectionWithNullEntries() {
120         final Collection<FileLocationStrategy> col = new LinkedList<>(Arrays.asList(getSubStrategies()));
121         col.add(null);
122         assertThrows(IllegalArgumentException.class, () -> new CombinedLocationStrategy(col));
123     }
124 
125     /**
126      * Tests whether a defensive copy of the collection with sub strategies is made.
127      */
128     @Test
129     public void testInitDefensiveCopy() {
130         final Collection<FileLocationStrategy> col = new LinkedList<>(Arrays.asList(getSubStrategies()));
131         final CombinedLocationStrategy strategy = new CombinedLocationStrategy(col);
132         col.add(mock(FileLocationStrategy.class));
133         checkSubStrategies(strategy);
134     }
135 
136     /**
137      * Tries to create an instance with a null collection.
138      */
139     @Test
140     public void testInitNullCollection() {
141         assertThrows(IllegalArgumentException.class, () -> new CombinedLocationStrategy(null));
142     }
143 
144     /**
145      * Tests a failed locate() operation.
146      */
147     @Test
148     public void testLocateFailed() {
149         when(getSubStrategies()[0].locate(getFileSystem(), locator)).thenReturn(null);
150         when(getSubStrategies()[1].locate(getFileSystem(), locator)).thenReturn(null);
151 
152         final CombinedLocationStrategy strategy = createCombinedStrategy();
153         assertNull(strategy.locate(getFileSystem(), locator));
154 
155         verify(getSubStrategies()[0]).locate(getFileSystem(), locator);
156         verify(getSubStrategies()[1]).locate(getFileSystem(), locator);
157         verifyNoMoreSubCategoryInteractions();
158     }
159 
160     /**
161      * Tests a successful locate() operation if the first sub strategy can locate the file.
162      */
163     @Test
164     public void testLocateSuccessFirstSubStrategy() {
165         when(getSubStrategies()[0].locate(getFileSystem(), locator)).thenReturn(locateURL);
166 
167         final CombinedLocationStrategy strategy = createCombinedStrategy();
168         assertSame(locateURL, strategy.locate(getFileSystem(), locator));
169 
170         verify(getSubStrategies()[0]).locate(getFileSystem(), locator);
171         verifyNoMoreSubCategoryInteractions();
172     }
173 
174     /**
175      * Tests a successful locate() operation if the 2nd sub strategy can locate the file.
176      */
177     @Test
178     public void testLocateSuccessSecondSubStrategy() {
179         when(getSubStrategies()[0].locate(getFileSystem(), locator)).thenReturn(null);
180         when(getSubStrategies()[1].locate(getFileSystem(), locator)).thenReturn(locateURL);
181 
182         final CombinedLocationStrategy strategy = createCombinedStrategy();
183         assertSame(locateURL, strategy.locate(getFileSystem(), locator));
184 
185         verify(getSubStrategies()[0]).locate(getFileSystem(), locator);
186         verify(getSubStrategies()[1]).locate(getFileSystem(), locator);
187         verifyNoMoreSubCategoryInteractions();
188     }
189 
190     /**
191      * Helper method for verifying that no more interactions have been performed on the sub categories.
192      */
193     private void verifyNoMoreSubCategoryInteractions() {
194         verifyNoMoreInteractions((Object[]) getSubStrategies());
195     }
196 }