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.collections4.list;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  
22  import java.io.IOException;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.util.Arrays;
26  import java.util.List;
27  
28  import org.junit.jupiter.api.Test;
29  
30  /**
31   * Test case for {@link AbstractLinkedListJava21}.
32   */
33  public class DefaultAbstractLinkedListJava21Test<E> extends AbstractListTest<E> {
34  
35      private static class DefaultAbstractLinkedListJava21<E> extends AbstractLinkedListJava21<E> {
36          DefaultAbstractLinkedListJava21() {
37              init();
38          }
39  
40          /**
41           * Deserializes an instance from an ObjectInputStream.
42           *
43           * @param in The source ObjectInputStream.
44           * @throws IOException            Any of the usual Input/Output related exceptions.
45           * @throws ClassNotFoundException A class of a serialized object cannot be found.
46           */
47          private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
48              in.defaultReadObject();
49              doReadObject(in);
50          }
51  
52          /**
53           * Serializes this object to an ObjectOutputStream.
54           *
55           * @param out the target ObjectOutputStream.
56           * @throws IOException thrown when an I/O errors occur writing to the target stream.
57           */
58          private void writeObject(final ObjectOutputStream out) throws IOException {
59              out.defaultWriteObject();
60              doWriteObject(out);
61          }
62      }
63  
64      protected void checkNodes() {
65          final AbstractLinkedListJava21<E> list = getCollection();
66          for (int i = 0; i < list.size; i++) {
67              assertEquals(list.getNode(i, false).next, list.getNode(i + 1, true));
68              if (i < list.size - 1) {
69                  assertEquals(list.getNode(i + 1, false).previous, list.getNode(i, false));
70              }
71          }
72      }
73  
74      @Override
75      public AbstractLinkedListJava21<E> getCollection() {
76          return (AbstractLinkedListJava21<E>) super.getCollection();
77      }
78  
79      @Override
80      public String getCompatibilityVersion() {
81          return null;
82      }
83  
84      @Override
85      public List<E> makeObject() {
86          return new DefaultAbstractLinkedListJava21<>();
87      }
88  
89      @Override
90      protected boolean skipSerializedCanonicalTests() {
91          return true;
92      }
93  
94      @Test
95      @SuppressWarnings("unchecked")
96      public void testAddNodeAfter() {
97          resetEmpty();
98          final AbstractLinkedListJava21<E> list = getCollection();
99          if (!isAddSupported()) {
100             assertThrows(UnsupportedOperationException.class, () -> list.addFirst(null));
101         }
102         list.addFirst((E) "value1");
103         list.addNodeAfter(list.getNode(0, false), (E) "value2");
104         assertEquals("value1", list.getFirst());
105         assertEquals("value2", list.getLast());
106         list.removeFirst();
107         checkNodes();
108         list.addNodeAfter(list.getNode(0, false), (E) "value3");
109         checkNodes();
110         assertEquals("value2", list.getFirst());
111         assertEquals("value3", list.getLast());
112         list.addNodeAfter(list.getNode(0, false), (E) "value4");
113         checkNodes();
114         assertEquals("value2", list.getFirst());
115         assertEquals("value3", list.getLast());
116         assertEquals("value4", list.get(1));
117         list.addNodeAfter(list.getNode(2, false), (E) "value5");
118         checkNodes();
119         assertEquals("value2", list.getFirst());
120         assertEquals("value4", list.get(1));
121         assertEquals("value3", list.get(2));
122         assertEquals("value5", list.getLast());
123     }
124 
125     @Test
126     @SuppressWarnings("unchecked")
127     public void testGetNode() {
128         resetEmpty();
129         final AbstractLinkedListJava21<E> list = getCollection();
130         // get marker
131         assertEquals(list.getNode(0, true).previous, list.getNode(0, true).next);
132         assertThrows(IndexOutOfBoundsException.class, () -> list.getNode(0, false), "Expecting IndexOutOfBoundsException.");
133         list.addAll(Arrays.asList((E[]) new String[] { "value1", "value2" }));
134         checkNodes();
135         list.addFirst((E) "value0");
136         checkNodes();
137         list.removeNode(list.getNode(1, false));
138         checkNodes();
139         assertThrows(IndexOutOfBoundsException.class, () -> list.getNode(2, false), "Expecting IndexOutOfBoundsException.");
140         assertThrows(IndexOutOfBoundsException.class, () -> list.getNode(-1, false), "Expecting IndexOutOfBoundsException.");
141         assertThrows(IndexOutOfBoundsException.class, () -> list.getNode(3, true), "Expecting IndexOutOfBoundsException.");
142     }
143 
144     @Test
145     @SuppressWarnings("unchecked")
146     public void testRemoveFirst() {
147         resetEmpty();
148         final AbstractLinkedListJava21<E> list = getCollection();
149         if (!isRemoveSupported()) {
150             assertThrows(UnsupportedOperationException.class, list::removeFirst);
151         }
152         list.addAll(Arrays.asList((E[]) new String[] { "value1", "value2" }));
153         assertEquals("value1", list.removeFirst());
154         checkNodes();
155         list.addLast((E) "value3");
156         checkNodes();
157         assertEquals("value2", list.removeFirst());
158         assertEquals("value3", list.removeFirst());
159         checkNodes();
160         list.addLast((E) "value4");
161         checkNodes();
162         assertEquals("value4", list.removeFirst());
163         checkNodes();
164     }
165 
166     @Test
167     @SuppressWarnings("unchecked")
168     public void testRemoveLast() {
169         resetEmpty();
170         final AbstractLinkedListJava21<E> list = getCollection();
171         if (!isRemoveSupported()) {
172             assertThrows(UnsupportedOperationException.class, list::removeLast);
173         }
174 
175         list.addAll(Arrays.asList((E[]) new String[] { "value1", "value2" }));
176         assertEquals("value2", list.removeLast());
177         list.addFirst((E) "value3");
178         checkNodes();
179         assertEquals("value1", list.removeLast());
180         assertEquals("value3", list.removeLast());
181         list.addFirst((E) "value4");
182         checkNodes();
183         assertEquals("value4", list.removeFirst());
184     }
185 
186     @Test
187     @SuppressWarnings("unchecked")
188     public void testRemoveNode() {
189         resetEmpty();
190         if (!isAddSupported() || !isRemoveSupported()) {
191             return;
192         }
193         final AbstractLinkedListJava21<E> list = getCollection();
194 
195         list.addAll(Arrays.asList((E[]) new String[] { "value1", "value2" }));
196         list.removeNode(list.getNode(0, false));
197         checkNodes();
198         assertEquals("value2", list.getFirst());
199         assertEquals("value2", list.getLast());
200         list.addFirst((E) "value1");
201         list.addFirst((E) "value0");
202         checkNodes();
203         list.removeNode(list.getNode(1, false));
204         assertEquals("value0", list.getFirst());
205         assertEquals("value2", list.getLast());
206         checkNodes();
207         list.removeNode(list.getNode(1, false));
208         assertEquals("value0", list.getFirst());
209         assertEquals("value0", list.getLast());
210         checkNodes();
211     }
212 
213     @Test
214     @SuppressWarnings("unchecked")
215     public void testSubList() {
216         final List<E> list = makeObject();
217         list.add((E) "A");
218         list.add((E) "B");
219         list.add((E) "C");
220         list.add((E) "D");
221         list.add((E) "E");
222 
223         assertEquals("[A, B, C, D, E]", list.toString());
224         assertEquals("[A, B, C, D, E]", list.subList(0, 5).toString());
225         assertEquals("[B, C, D, E]", list.subList(1, 5).toString());
226         assertEquals("[C, D, E]", list.subList(2, 5).toString());
227         assertEquals("[D, E]", list.subList(3, 5).toString());
228         assertEquals("[E]", list.subList(4, 5).toString());
229         assertEquals("[]", list.subList(5, 5).toString());
230     }
231 
232     @Test
233     @SuppressWarnings("unchecked")
234     public void testSubListAddBegin() {
235         final List<E> list = makeObject();
236         list.add((E) "A");
237         list.add((E) "B");
238         list.add((E) "C");
239         list.add((E) "D");
240         list.add((E) "E");
241 
242         final List<E> sublist = list.subList(0, 0);
243         sublist.add((E) "a");
244         assertEquals("[a, A, B, C, D, E]", list.toString());
245         assertEquals("[a]", sublist.toString());
246         sublist.add((E) "b");
247         assertEquals("[a, b, A, B, C, D, E]", list.toString());
248         assertEquals("[a, b]", sublist.toString());
249     }
250 
251     @Test
252     @SuppressWarnings("unchecked")
253     public void testSubListAddEnd() {
254         final List<E> list = makeObject();
255         list.add((E) "A");
256         list.add((E) "B");
257         list.add((E) "C");
258         list.add((E) "D");
259         list.add((E) "E");
260 
261         final List<E> sublist = list.subList(5, 5);
262         sublist.add((E) "F");
263         assertEquals("[A, B, C, D, E, F]", list.toString());
264         assertEquals("[F]", sublist.toString());
265         sublist.add((E) "G");
266         assertEquals("[A, B, C, D, E, F, G]", list.toString());
267         assertEquals("[F, G]", sublist.toString());
268     }
269 
270     @Test
271     @SuppressWarnings("unchecked")
272     public void testSubListAddMiddle() {
273         final List<E> list = makeObject();
274         list.add((E) "A");
275         list.add((E) "B");
276         list.add((E) "C");
277         list.add((E) "D");
278         list.add((E) "E");
279 
280         final List<E> sublist = list.subList(1, 3);
281         sublist.add((E) "a");
282         assertEquals("[A, B, C, a, D, E]", list.toString());
283         assertEquals("[B, C, a]", sublist.toString());
284         sublist.add((E) "b");
285         assertEquals("[A, B, C, a, b, D, E]", list.toString());
286         assertEquals("[B, C, a, b]", sublist.toString());
287     }
288 
289     @Test
290     @SuppressWarnings("unchecked")
291     public void testSubListRemove() {
292         final List<E> list = makeObject();
293         list.add((E) "A");
294         list.add((E) "B");
295         list.add((E) "C");
296         list.add((E) "D");
297         list.add((E) "E");
298 
299         final List<E> sublist = list.subList(1, 4);
300         assertEquals("[B, C, D]", sublist.toString());
301         assertEquals("[A, B, C, D, E]", list.toString());
302         sublist.remove("C");
303         assertEquals("[B, D]", sublist.toString());
304         assertEquals("[A, B, D, E]", list.toString());
305         sublist.remove(1);
306         assertEquals("[B]", sublist.toString());
307         assertEquals("[A, B, E]", list.toString());
308         sublist.clear();
309         assertEquals("[]", sublist.toString());
310         assertEquals("[A, E]", list.toString());
311     }
312 }