/* * Copyright 2003-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.nodeEditor.cells.collections; import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; /** * User: shatalin * Date: 18/05/16 */ public abstract class AbstractContainerTest<T> { protected abstract Container<T> createContainer(); protected abstract T createItem(); // // Testing .size() .isEmpty() // @Test public void emptyContainerSize() { Container<T> container = createContainer(); Assert.assertTrue(container.size() == 0); } @Test public void emptyContainerIsEmpty() { Container<T> container = createContainer(); Assert.assertTrue(container.isEmpty()); } @Test public void nonEmptyContainerSize() { Container<T> container = createContainer(); container.add(createItem()); container.add(createItem()); Assert.assertTrue(container.size() == 2); } @Test public void nonEmptyContainerIsEmpty() { Container<T> container = createContainer(); container.add(createItem()); Assert.assertFalse(container.isEmpty()); } @Test public void decreaseContainerSize() { Container<T> container = createContainer(); T first = createItem(); T second = createItem(); container.add(first); container.add(second); Assert.assertTrue(container.size() == 2); container.remove(first); Assert.assertTrue(container.size() == 1); Assert.assertFalse(container.isEmpty()); container.remove(second); Assert.assertTrue(container.size() == 0); Assert.assertTrue(container.isEmpty()); } // // Testing .add() & iterators // @Test public void addThenIterate() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 10); compareIterators(list.iterator(), container.iterator()); } @Test public void addThenIterateNullAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 11); compareIterators(list.iterator(), container.iterator(null, true)); } @Test public void addThenReverseIterateNullAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 12); Collections.reverse(list); compareIterators(list.iterator(), container.iterator(null, false)); } // // Testing .add() & .addBefore() // @Test public void addExisting() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 3); try { container.add(list.get(0)); Assert.fail("Should throw NoSuchElementException exception"); } catch (IllegalArgumentException e) { // It's ok } compareIterators(list.iterator(), container.iterator()); } @Test public void addBeforeExisting() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 4); try { container.addBefore(list.get(list.size() - 1), null); Assert.fail("Should throw NoSuchElementException exception"); } catch (IllegalArgumentException e) { // It's ok } compareIterators(list.iterator(), container.iterator()); } // // Testing .addBefore() // @Test public void addBeforeThenIterate() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 3); T toInsert = createItem(); int index = list.size() - 2; T anchor = list.get(index); list.add(index, toInsert); container.addBefore(toInsert, anchor); compareIterators(list.iterator(), container.iterator()); } @Test public void addBeforeNull() { Container<T> container = createContainer(); T item = createItem(); container.add(item); Assert.assertEquals(item, container.getFirst()); Assert.assertEquals(item, container.getLast()); T toInsert = createItem(); container.addBefore(toInsert, null); Assert.assertEquals(item, container.getFirst()); Assert.assertEquals(toInsert, container.getLast()); } @Test public void addBeforeNullEmptyContainer() { Container<T> container = createContainer(); T toInsert = createItem(); container.addBefore(toInsert, null); Assert.assertEquals(toInsert, container.getFirst()); Assert.assertEquals(toInsert, container.getLast()); } @Test public void addBeforeFirst() { Container<T> container = createContainer(); T item = createItem(); container.add(item); Assert.assertEquals(item, container.getFirst()); Assert.assertEquals(item, container.getLast()); T toInsert = createItem(); container.addBefore(toInsert, item); Assert.assertEquals(toInsert, container.getFirst()); Assert.assertEquals(item, container.getLast()); } @Test public void addBeforeNonExistingAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 4); T toInsert = createItem(); try { container.addBefore(toInsert, createItem()); Assert.fail("Should throw NoSuchElementException exception"); } catch (NoSuchElementException ex) { // It's ok } compareIterators(list.iterator(), container.iterator()); } // // Testing .remove() // @Test public void remove() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 6); T removed = list.remove(list.size() - 4); container.remove(removed); compareIterators(list.iterator(), container.iterator()); } @Test public void removeFirst() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 7); T removed = list.remove(0); container.remove(removed); Assert.assertEquals(list.get(0), container.getFirst()); compareIterators(list.iterator(), container.iterator()); } @Test public void removeLast() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 8); T removed = list.remove(list.size() - 1); container.remove(removed); Assert.assertEquals(list.get(list.size() - 1), container.getLast()); compareIterators(list.iterator(), container.iterator()); } @Test public void removeNonExisting() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 9); try { container.remove(createItem()); Assert.fail("Should throw NoSuchElementException exception"); } catch (NoSuchElementException e) { // It's ok } compareIterators(list.iterator(), container.iterator()); } // // Testing .contains() // @Test public void containsTrue() { Container<T> container = createContainer(); T item = createItem(); container.add(item); Assert.assertTrue(container.contains(item)); } @Test public void containsFalse() { Container<T> container = createContainer(); T item = createItem(); container.add(item); Assert.assertFalse(container.contains(createItem())); } // // Testing .iterator() / .iterator(T anchor, boolean forward) // @Test public void emptyIterator() { Container<T> container = createContainer(); Iterator<T> iterator = container.iterator(); Assert.assertFalse(iterator.hasNext()); iterator = container.iterator(null, true); Assert.assertFalse(iterator.hasNext()); iterator = container.iterator(null, false); Assert.assertFalse(iterator.hasNext()); } @Test public void concurrentModificationOnIterator() { Container<T> container = createContainer(); container.add(createItem()); container.add(createItem()); Iterator<T> it = container.iterator(); Assert.assertTrue(it.hasNext()); it.next(); container.add(createItem()); try { it.hasNext(); Assert.fail("Should throw ConcurrentModificationException exception"); } catch (ConcurrentModificationException e) { // It's ok } try { it.next(); Assert.fail("Should throw ConcurrentModificationException exception"); } catch (ConcurrentModificationException e) { // It's ok } } @Test public void concurrentModificationOnIteratorWithAnchor() { Container<T> container = createContainer(); T anchor = createItem(); container.add(anchor); container.add(createItem()); container.add(createItem()); Iterator<T> it = container.iterator(anchor, true); Assert.assertTrue(it.hasNext()); it.next(); container.add(createItem()); try { it.hasNext(); Assert.fail("Should throw ConcurrentModificationException exception"); } catch (ConcurrentModificationException e) { // It's ok } try { it.next(); Assert.fail("Should throw ConcurrentModificationException exception"); } catch (ConcurrentModificationException e) { // It's ok } } // // Testing .iterator(T anchor, boolean forward) // @Test public void forwardIteratorNullAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 30); compareIterators(list.iterator(), container.iterator(null, true)); } @Test public void reverseIteratorNullAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 31); Collections.reverse(list); compareIterators(list.iterator(), container.iterator(null, false)); } @Test public void forwardIteratorWithAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); container.add(createItem()); container.add(createItem()); T anchor = createItem(); container.add(anchor); fill(list, container, 32); compareIterators(list.iterator(), container.iterator(anchor, true)); } @Test public void reverseIteratorWithAnchor() { List<T> list = new ArrayList<>(); Container<T> container = createContainer(); fill(list, container, 33); T anchor = createItem(); container.add(anchor); container.add(createItem()); container.add(createItem()); container.add(createItem()); Collections.reverse(list); compareIterators(list.iterator(), container.iterator(anchor, false)); } // // Testing .getFirst() .getLast() // @Test public void getFirstOnEmptyContainer() { Container<T> container = createContainer(); try { container.getFirst(); Assert.fail("Should throw NoSuchElementException exception"); } catch (NoSuchElementException e) { // It's ok } } @Test public void getLastOnEmptyContainer() { Container<T> container = createContainer(); try { container.getLast(); Assert.fail("Should throw NoSuchElementException exception"); } catch (NoSuchElementException e) { // It's ok } } @Test public void firstLastOnAddRemove() { Container<T> container = createContainer(); T first = createItem(); container.add(first); Assert.assertEquals(first, container.getFirst()); Assert.assertEquals(first, container.getLast()); T second = createItem(); container.add(second); Assert.assertEquals(first, container.getFirst()); Assert.assertEquals(second, container.getLast()); container.remove(second); Assert.assertEquals(first, container.getFirst()); Assert.assertEquals(first, container.getLast()); container.add(second); container.remove(first); Assert.assertEquals(second, container.getFirst()); Assert.assertEquals(second, container.getLast()); } private void fill(List<T> list, Container<T> container, int counter) { for (int i = 0; i < counter; i++) { T next = createItem(); list.add(next); container.add(next); } } private void compareIterators(Iterator<T> expected, Iterator<T> actual) { while (expected.hasNext()) { T nextExpected = expected.next(); Assert.assertTrue(actual.hasNext()); T nextActual = actual.next(); Assert.assertEquals(nextExpected, nextActual); } Assert.assertFalse(actual.hasNext()); } }