com.google.gwt.emultest.java.util.ArrayDequeTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.emultest.java.util.ArrayDequeTest.java

Source

/*
 * 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);
    }
}