1/*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect.testing.testers;
18
19import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
20import static com.google.common.collect.testing.features.CollectionSize.ZERO;
21
22import com.google.common.annotations.GwtCompatible;
23import com.google.common.annotations.GwtIncompatible;
24import com.google.common.collect.testing.AbstractCollectionTester;
25import com.google.common.collect.testing.Helpers;
26import com.google.common.collect.testing.WrongType;
27import com.google.common.collect.testing.features.CollectionFeature;
28import com.google.common.collect.testing.features.CollectionSize;
29
30import java.lang.reflect.Method;
31import java.util.Arrays;
32import java.util.Collection;
33import java.util.List;
34
35/**
36 * A generic JUnit test which tests {@code toArray()} operations on a
37 * collection. Can't be invoked directly; please see
38 * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
39 *
40 * @author Kevin Bourrillion
41 * @author Chris Povirk
42 */
43@GwtCompatible(emulated = true)
44public class CollectionToArrayTester<E> extends AbstractCollectionTester<E> {
45  public void testToArray_noArgs() {
46    Object[] array = collection.toArray();
47    expectArrayContentsAnyOrder(createSamplesArray(), array);
48  }
49
50  /**
51   * {@link Collection#toArray(Object[])} says: "Note that
52   * <tt>toArray(new Object[0])</tt> is identical in function to
53   * <tt>toArray()</tt>."
54   *
55   * <p>For maximum effect, the collection under test should be created from an
56   * element array of a type other than {@code Object[]}.
57   */
58  public void testToArray_isPlainObjectArray() {
59    Object[] array = collection.toArray();
60    assertEquals(Object[].class, array.getClass());
61  }
62
63  public void testToArray_emptyArray() {
64    E[] empty = getSubjectGenerator().createArray(0);
65    E[] array = collection.toArray(empty);
66    assertEquals("toArray(emptyT[]) should return an array of type T",
67        empty.getClass(), array.getClass());
68    assertEquals("toArray(emptyT[]).length:", getNumElements(), array.length);
69    expectArrayContentsAnyOrder(createSamplesArray(), array);
70  }
71
72  @CollectionFeature.Require(KNOWN_ORDER)
73  public void testToArray_emptyArray_ordered() {
74    E[] empty = getSubjectGenerator().createArray(0);
75    E[] array = collection.toArray(empty);
76    assertEquals("toArray(emptyT[]) should return an array of type T",
77        empty.getClass(), array.getClass());
78    assertEquals("toArray(emptyT[]).length:", getNumElements(), array.length);
79    expectArrayContentsInOrder(getOrderedElements(), array);
80  }
81
82  public void testToArray_emptyArrayOfObject() {
83    Object[] in = new Object[0];
84    Object[] array = collection.toArray(in);
85    assertEquals("toArray(emptyObject[]) should return an array of type Object",
86        Object[].class, array.getClass());
87    assertEquals("toArray(emptyObject[]).length",
88        getNumElements(), array.length);
89    expectArrayContentsAnyOrder(createSamplesArray(), array);
90  }
91
92  public void testToArray_rightSizedArray() {
93    E[] array = getSubjectGenerator().createArray(getNumElements());
94    assertSame("toArray(sameSizeE[]) should return the given array",
95        array, collection.toArray(array));
96    expectArrayContentsAnyOrder(createSamplesArray(), array);
97  }
98
99  @CollectionFeature.Require(KNOWN_ORDER)
100  public void testToArray_rightSizedArray_ordered() {
101    E[] array = getSubjectGenerator().createArray(getNumElements());
102    assertSame("toArray(sameSizeE[]) should return the given array",
103        array, collection.toArray(array));
104    expectArrayContentsInOrder(getOrderedElements(), array);
105  }
106
107  public void testToArray_rightSizedArrayOfObject() {
108    Object[] array = new Object[getNumElements()];
109    assertSame("toArray(sameSizeObject[]) should return the given array",
110        array, collection.toArray(array));
111    expectArrayContentsAnyOrder(createSamplesArray(), array);
112  }
113
114  @CollectionFeature.Require(KNOWN_ORDER)
115  public void testToArray_rightSizedArrayOfObject_ordered() {
116    Object[] array = new Object[getNumElements()];
117    assertSame("toArray(sameSizeObject[]) should return the given array",
118        array, collection.toArray(array));
119    expectArrayContentsInOrder(getOrderedElements(), array);
120  }
121
122  public void testToArray_oversizedArray() {
123    E[] array = getSubjectGenerator().createArray(getNumElements() + 2);
124    array[getNumElements()] = samples.e3;
125    array[getNumElements() + 1] = samples.e3;
126    assertSame("toArray(overSizedE[]) should return the given array",
127        array, collection.toArray(array));
128
129    List<E> subArray = Arrays.asList(array).subList(0, getNumElements());
130    E[] expectedSubArray = createSamplesArray();
131    for (int i = 0; i < getNumElements(); i++) {
132      assertTrue(
133          "toArray(overSizedE[]) should contain element " + expectedSubArray[i],
134          subArray.contains(expectedSubArray[i]));
135    }
136    assertNull("The array element "
137        + "immediately following the end of the collection should be nulled",
138        array[getNumElements()]);
139    // array[getNumElements() + 1] might or might not have been nulled
140  }
141
142  @CollectionFeature.Require(KNOWN_ORDER)
143  public void testToArray_oversizedArray_ordered() {
144    E[] array = getSubjectGenerator().createArray(getNumElements() + 2);
145    array[getNumElements()] = samples.e3;
146    array[getNumElements() + 1] = samples.e3;
147    assertSame("toArray(overSizedE[]) should return the given array",
148        array, collection.toArray(array));
149
150    List<E> expected = getOrderedElements();
151    for (int i = 0; i < getNumElements(); i++) {
152      assertEquals(expected.get(i), array[i]);
153    }
154    assertNull("The array element "
155        + "immediately following the end of the collection should be nulled",
156        array[getNumElements()]);
157    // array[getNumElements() + 1] might or might not have been nulled
158  }
159
160  @CollectionSize.Require(absent = ZERO)
161  public void testToArray_emptyArrayOfWrongTypeForNonEmptyCollection() {
162    try {
163      WrongType[] array = new WrongType[0];
164      collection.toArray(array);
165      fail("toArray(notAssignableTo[]) should throw");
166    } catch (ArrayStoreException expected) {
167    }
168  }
169
170  @CollectionSize.Require(ZERO)
171  public void testToArray_emptyArrayOfWrongTypeForEmptyCollection() {
172    WrongType[] array = new WrongType[0];
173    assertSame(
174        "toArray(sameSizeNotAssignableTo[]) should return the given array",
175        array, collection.toArray(array));
176  }
177
178  private void expectArrayContentsAnyOrder(Object[] expected, Object[] actual) {
179    Helpers.assertEqualIgnoringOrder(
180        Arrays.asList(expected), Arrays.asList(actual));
181  }
182
183  private void expectArrayContentsInOrder(List<E> expected, Object[] actual) {
184    assertEquals("toArray() ordered contents: ",
185        expected, Arrays.asList(actual));
186  }
187
188  /**
189   * Returns the {@link Method} instance for
190   * {@link #testToArray_isPlainObjectArray()} so that tests of
191   * {@link Arrays#asList(Object[])} can suppress it with {@code
192   * FeatureSpecificTestSuiteBuilder.suppressing()} until <a
193   * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6260652">Sun bug
194   * 6260652</a> is fixed.
195   */
196  @GwtIncompatible("reflection")
197  public static Method getToArrayIsPlainObjectArrayMethod() {
198    return Helpers.getMethod(CollectionToArrayTester.class, "testToArray_isPlainObjectArray");
199  }
200}
201