blob: 13e5a09991b836a63f918a2102aef94af3830393 [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* 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 com.google.gwt.emultest.java.util;
import static java.util.Arrays.asList;
import com.google.gwt.core.client.JavaScriptException;
import org.apache.commons.collections.TestCollection;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Deque;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Tests ArrayDeque class.
*/
public class ArrayDequeTest extends TestCollection {
public void testAdd() throws Exception {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertTrue(deque.add(o1));
checkDequeSizeAndContent(deque, o1);
assertTrue(deque.add(o2));
checkDequeSizeAndContent(deque, o1, o2);
assertTrue(deque.add(o3));
checkDequeSizeAndContent(deque, o1, o2, o3);
try {
deque.add(null);
fail();
} catch (NullPointerException expected) { }
}
public void testAddAll() throws Exception {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertTrue(deque.addAll(asList(o1, o2)));
checkDequeSizeAndContent(deque, o1, o2);
try {
deque = new ArrayDeque<>();
deque.addAll(asList(o1, null, o2));
fail();
} catch (NullPointerException expected) { }
}
public void testAddFirst() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
deque.addFirst(o1);
checkDequeSizeAndContent(deque, o1);
deque.addFirst(o2);
checkDequeSizeAndContent(deque, o2, o1);
deque.addFirst(o3);
checkDequeSizeAndContent(deque, o3, o2, o1);
try {
deque.addFirst(null);
fail();
} catch (NullPointerException expected) { }
}
public void testAddLast() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
deque.addLast(o1);
checkDequeSizeAndContent(deque, o1);
deque.addLast(o2);
checkDequeSizeAndContent(deque, o1, o2);
deque.addLast(o3);
checkDequeSizeAndContent(deque, o1, o2, o3);
try {
deque.addLast(null);
fail();
} catch (NullPointerException expected) { }
}
public void testConstructorFromCollection() {
assertEquals(0, new ArrayDeque<>(new ArrayList<>()).size());
try {
new ArrayDeque<>(null);
fail();
} catch (NullPointerException expected) {
// expected
} catch (JavaScriptException expected) {
// expected
}
try {
new ArrayDeque<>(asList(new Object(), null, new Object()));
fail();
} catch (NullPointerException expected) { }
Collection<Object> collection = new ArrayList<>(asList(getFullNonNullElements()));
checkDequeSizeAndContent(new ArrayDeque<>(collection), getFullNonNullElements());
}
public void testContains() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertFalse(deque.contains(o3));
assertFalse(deque.contains(null));
assertTrue(deque.add(o1));
assertTrue(deque.add(o2));
assertTrue(deque.add(o1));
assertTrue(deque.add(o3));
assertTrue(deque.contains(o1));
assertTrue(deque.contains(o2));
assertTrue(deque.contains(o3));
assertFalse(deque.contains(null));
deque.clear();
assertTrue(deque.isEmpty());
assertFalse(deque.contains(o1));
assertFalse(deque.contains(o2));
assertFalse(deque.contains(o3));
}
public void testDescendingIterator() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
Iterator<Object> it = deque.descendingIterator();
assertFalse(it.hasNext());
try {
it.next();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
deque.add(o2);
deque.add(o3);
it = deque.descendingIterator();
assertTrue(it.hasNext());
assertEquals(o3, it.next());
assertTrue(it.hasNext());
assertEquals(o2, it.next());
assertTrue(it.hasNext());
assertEquals(o1, it.next());
assertFalse(it.hasNext());
try {
it.next();
fail();
} catch (NoSuchElementException expected) { }
checkDequeSizeAndContent(deque, o1, o2, o3);
deque = new ArrayDeque<>();
deque.add(o1);
deque.add(o2);
deque.add(o3);
it = deque.descendingIterator();
assertTrue(it.hasNext());
assertEquals(o3, it.next());
it.remove();
assertEquals(2, deque.size());
assertTrue(it.hasNext());
assertEquals(o2, it.next());
assertTrue(it.hasNext());
assertEquals(o1, it.next());
it.remove();
checkDequeSizeAndContent(deque, o2);
}
public void testElement() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.element();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.element());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o1, deque.element());
checkDequeSizeAndContent(deque, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
try {
deque.element();
fail();
} catch (NoSuchElementException expected) { }
}
public void testFailFastIterator() {
ArrayDeque<Object> deque = new ArrayDeque<>(asList(getFullNonNullElements()));
Iterator<Object> it = deque.iterator();
it.next();
deque.removeFirst();
try {
it.next();
} catch (ConcurrentModificationException e) {
fail();
}
deque.removeLast();
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.iterator();
it.next();
deque.clear();
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.iterator();
it.next();
deque.addFirst(new Object());
try {
it.next();
} catch (ConcurrentModificationException e) {
fail();
}
deque.addLast(new Object());
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.iterator();
it.next();
it.next();
deque.removeFirst();
try {
it.remove();
} catch (ConcurrentModificationException e) {
fail();
}
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.iterator();
it.next();
it.next();
deque.removeFirst();
deque.removeFirst();
try {
it.remove();
fail();
} catch (ConcurrentModificationException expected) { }
}
public void testFailFastDescendingIterator() {
ArrayDeque<Object> deque = new ArrayDeque<>(asList(getFullNonNullElements()));
Iterator<Object> it = deque.descendingIterator();
it.next();
deque.removeLast();
try {
it.next();
} catch (ConcurrentModificationException e) {
fail();
}
deque.removeFirst();
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.descendingIterator();
it.next();
deque.clear();
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.descendingIterator();
it.next();
deque.addLast(new Object());
try {
it.next();
} catch (ConcurrentModificationException e) {
fail();
}
deque.addFirst(new Object());
try {
it.next();
fail();
} catch (ConcurrentModificationException expected) { }
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.descendingIterator();
it.next();
it.next();
deque.removeLast();
try {
it.remove();
} catch (ConcurrentModificationException e) {
fail();
}
deque = new ArrayDeque<>(asList(getFullNonNullElements()));
it = deque.descendingIterator();
it.next();
it.next();
deque.removeLast();
deque.removeLast();
try {
it.remove();
fail();
} catch (ConcurrentModificationException expected) { }
}
public void testGetFirst() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.getFirst();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.getFirst());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o1, deque.getFirst());
checkDequeSizeAndContent(deque, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
try {
deque.getFirst();
fail();
} catch (NoSuchElementException expected) { }
}
public void testGetLast() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.getLast();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.getLast());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o2, deque.getLast());
checkDequeSizeAndContent(deque, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
try {
deque.getLast();
fail();
} catch (NoSuchElementException expected) { }
}
public void testOffer() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertTrue(deque.offer(o1));
checkDequeSizeAndContent(deque, o1);
assertTrue(deque.offer(o2));
checkDequeSizeAndContent(deque, o1, o2);
assertTrue(deque.offer(o3));
checkDequeSizeAndContent(deque, o1, o2, o3);
try {
deque.offer(null);
fail();
} catch (NullPointerException expected) { }
}
public void testOfferFirst() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertTrue(deque.offerFirst(o1));
checkDequeSizeAndContent(deque, o1);
assertTrue(deque.offerFirst(o2));
checkDequeSizeAndContent(deque, o2, o1);
assertTrue(deque.offerFirst(o3));
checkDequeSizeAndContent(deque, o3, o2, o1);
try {
deque.offerFirst(null);
fail();
} catch (NullPointerException expected) { }
}
public void testOfferLast() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertTrue(deque.offerLast(o1));
checkDequeSizeAndContent(deque, o1);
assertTrue(deque.offerLast(o2));
checkDequeSizeAndContent(deque, o1, o2);
assertTrue(deque.offerLast(o3));
checkDequeSizeAndContent(deque, o1, o2, o3);
try {
deque.offerLast(null);
fail();
} catch (NullPointerException expected) { }
}
public void testPeek() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.peek());
deque.add(o1);
assertEquals(o1, deque.peek());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o1, deque.peek());
checkDequeSizeAndContent(deque, o1, o2);
deque.addFirst(o3);
assertEquals(o3, deque.peek());
checkDequeSizeAndContent(deque, o3, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
assertNull(deque.peek());
}
public void testPeekFirst() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.peekFirst());
deque.add(o1);
assertEquals(o1, deque.peekFirst());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o1, deque.peekFirst());
checkDequeSizeAndContent(deque, o1, o2);
deque.addFirst(o3);
assertEquals(o3, deque.peekFirst());
checkDequeSizeAndContent(deque, o3, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
assertNull(deque.peekFirst());
}
public void testPeekLast() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.peekLast());
deque.add(o1);
assertEquals(o1, deque.peekLast());
checkDequeSizeAndContent(deque, o1);
deque.add(o2);
assertEquals(o2, deque.peekLast());
checkDequeSizeAndContent(deque, o1, o2);
deque.addFirst(o3);
assertEquals(o2, deque.peekLast());
checkDequeSizeAndContent(deque, o3, o1, o2);
deque.clear();
assertTrue(deque.isEmpty());
assertNull(deque.peekLast());
}
public void testPoll() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.poll());
deque.add(o1);
assertEquals(o1, deque.poll());
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertEquals(o1, deque.poll());
checkDequeSizeAndContent(deque, o2);
assertEquals(o2, deque.poll());
assertTrue(deque.isEmpty());
assertNull(deque.poll());
}
public void testPollFirst() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.pollFirst());
assertTrue(deque.isEmpty());
deque.add(o1);
assertEquals(o1, deque.pollFirst());
assertTrue(deque.isEmpty());
assertNull(deque.pollFirst());
deque.add(o1);
deque.add(o2);
assertEquals(o1, deque.pollFirst());
checkDequeSizeAndContent(deque, o2);
assertEquals(o2, deque.pollFirst());
assertTrue(deque.isEmpty());
assertNull(deque.pollFirst());
}
public void testPollLast() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertNull(deque.pollLast());
assertTrue(deque.isEmpty());
deque.add(o1);
assertEquals(o1, deque.pollLast());
assertTrue(deque.isEmpty());
assertNull(deque.pollFirst());
deque.add(o1);
deque.add(o2);
assertEquals(o2, deque.pollLast());
checkDequeSizeAndContent(deque, o1);
assertEquals(o1, deque.pollLast());
assertTrue(deque.isEmpty());
assertNull(deque.pollLast());
}
public void testPop() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.pop();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.pop());
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertEquals(o1, deque.pop());
checkDequeSizeAndContent(deque, o2);
assertEquals(o2, deque.pop());
assertTrue(deque.isEmpty());
try {
deque.pop();
fail();
} catch (NoSuchElementException expected) { }
}
public void testPush() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
deque.push(o1);
checkDequeSizeAndContent(deque, o1);
deque.push(o2);
checkDequeSizeAndContent(deque, o2, o1);
deque.push(o3);
checkDequeSizeAndContent(deque, o3, o2, o1);
try {
deque.push(null);
fail();
} catch (NullPointerException expected) { }
}
public void testRemove() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.remove();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.remove());
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertEquals(o1, deque.remove());
checkDequeSizeAndContent(deque, o2);
assertEquals(o2, deque.removeFirst());
assertTrue(deque.isEmpty());
try {
deque.remove();
fail();
} catch (NoSuchElementException expected) { }
}
public void testRemoveElement() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertFalse(deque.remove(o1));
deque.add(o1);
assertTrue(deque.remove(o1));
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertTrue(deque.remove(o1));
checkDequeSizeAndContent(deque, o2);
assertTrue(deque.remove(o2));
assertTrue(deque.isEmpty());
assertFalse(deque.remove(null));
}
public void testRemoveFirst() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.removeFirst();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.removeFirst());
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertEquals(o1, deque.removeFirst());
checkDequeSizeAndContent(deque, o2);
assertEquals(o2, deque.removeFirst());
assertTrue(deque.isEmpty());
try {
deque.removeFirst();
fail();
} catch (NoSuchElementException expected) { }
}
public void testRemoveFirstOccurrence() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertFalse(deque.removeFirstOccurrence(o1));
deque.add(o1);
assertTrue(deque.removeFirstOccurrence(o1));
assertTrue(deque.isEmpty());
deque = new ArrayDeque<>();
deque.add(o1);
deque.add(o2);
deque.add(o3);
assertTrue(deque.removeFirstOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o3);
deque = new ArrayDeque<>();
deque.add(o1);
deque.add(o2);
deque.add(o3);
deque.add(o1);
deque.add(o2);
deque.add(o3);
assertTrue(deque.removeFirstOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o3, o1, o2, o3);
assertTrue(deque.removeFirstOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o3, o1, o3);
assertTrue(deque.removeFirstOccurrence(o1));
checkDequeSizeAndContent(deque, o3, o1, o3);
assertTrue(deque.removeFirstOccurrence(o1));
checkDequeSizeAndContent(deque, o3, o3);
assertFalse(deque.removeFirstOccurrence(o1));
assertFalse(deque.removeFirstOccurrence(null));
}
public void testRemoveLast() {
Object o1 = new Object();
Object o2 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
try {
deque.removeLast();
fail();
} catch (NoSuchElementException expected) { }
deque.add(o1);
assertEquals(o1, deque.removeLast());
assertTrue(deque.isEmpty());
deque.add(o1);
deque.add(o2);
assertEquals(o2, deque.removeLast());
checkDequeSizeAndContent(deque, o1);
assertEquals(o1, deque.removeLast());
assertEquals(0, deque.size());
try {
deque.removeLast();
fail();
} catch (NoSuchElementException expected) { }
}
public void testRemoveLastOccurrence() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
ArrayDeque<Object> deque = new ArrayDeque<>();
assertFalse(deque.removeLastOccurrence(o1));
deque.add(o1);
assertTrue(deque.removeLastOccurrence(o1));
assertTrue(deque.isEmpty());
deque = new ArrayDeque<>();
deque.add(o1);
deque.add(o2);
deque.add(o3);
assertTrue(deque.removeLastOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o3);
deque = new ArrayDeque<>();
deque.add(o1);
deque.add(o2);
deque.add(o3);
deque.add(o1);
deque.add(o2);
deque.add(o3);
assertTrue(deque.removeLastOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o2, o3, o1, o3);
assertTrue(deque.removeLastOccurrence(o2));
checkDequeSizeAndContent(deque, o1, o3, o1, o3);
assertTrue(deque.removeLastOccurrence(o3));
checkDequeSizeAndContent(deque, o1, o3, o1);
assertTrue(deque.removeLastOccurrence(o3));
checkDequeSizeAndContent(deque, o1, o1);
assertFalse(deque.removeLastOccurrence(o3));
assertFalse(deque.removeLastOccurrence(null));
}
public void testRolloverInvariants() {
ArrayDeque<Integer> deque = new ArrayDeque<>();
assertTrue(deque.add(1));
assertEquals(1, (int) deque.removeFirst());
for (int i = 0; i < 100; i++) {
assertTrue(deque.add(i));
}
assertNotNull(deque.peek());
assertFalse(deque.isEmpty());
Iterator<Integer> it = deque.iterator();
for (int i = 0; i < 100; i++) {
assertTrue(it.hasNext());
assertEquals(i, (int) it.next());
it.remove();
}
assertFalse(it.hasNext());
assertNull(deque.peek());
assertTrue(deque.isEmpty());
}
/**
* Null elements are prohibited in ArrayDeque.
*/
@Override
protected Object[] getFullElements() {
return getFullNonNullElements();
}
@Override
protected Collection makeConfirmedCollection() {
return new ArrayList<>();
}
@Override
protected Collection makeConfirmedFullCollection() {
return new ArrayList<>(asList(getFullElements()));
}
@Override
protected Collection makeCollection() {
return new ArrayDeque<>();
}
private void checkDequeSizeAndContent(Deque<?> deque, Object... expected) {
assertEquals(expected.length, deque.size());
int i = 0;
for (Object e : deque) {
assertEquals(expected[i++], e);
}
assertEquals(expected.length, i);
}
}