/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test 8037857
 * @summary tests for stream and spliterator factory methods
 * @run testng StreamAndSpliterator
 */

import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.Spliterators;

import static org.testng.Assert.assertNotNull;

public class StreamAndSpliterator {
    @Test
    public void testStreamNPEs() {
        assertThrowsNPE(() -> Arrays.stream((int[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.stream((long[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.stream((double[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.stream((String[]) null, 0, 0));
    }

    @Test
    public void testStreamAIOBEs() {
        // origin > fence
        assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, 1, 0));

        // bad origin
        assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, -1, 0));

        // bad fence
        assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, 0, 1));
    }


    @Test
    public void testSpliteratorNPEs() {
        assertThrowsNPE(() -> Arrays.spliterator((int[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.spliterator((long[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.spliterator((double[]) null, 0, 0));
        assertThrowsNPE(() -> Arrays.spliterator((String[]) null, 0, 0));
    }

    @Test
    public void testSpliteratorAIOBEs() {
        // origin > fence
        assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, 1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, 1, 0));

        // bad origin
        assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, -1, 0));
        assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, -1, 0));

        // bad fence
        assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, 0, 1));
        assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, 0, 1));
    }


    @Test
    public void testSpliteratorNPEsFromSpliterators() {
        assertThrowsNPE(() -> Spliterators.spliterator((int[]) null, 0, 0, 0));
        assertThrowsNPE(() -> Spliterators.spliterator((long[]) null, 0, 0, 0));
        assertThrowsNPE(() -> Spliterators.spliterator((double[]) null, 0, 0, 0));
        assertThrowsNPE(() -> Spliterators.spliterator((String[]) null, 0, 0, 0));
    }

    @Test
    public void testSpliteratorAIOBEsFromSpliterators() {
        // origin > fence
        assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, 1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, 1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, 1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, 1, 0, 0));

        // bad origin
        assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, -1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, -1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, -1, 0, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, -1, 0, 0));

        // bad fence
        assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, 0, 1, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, 0, 1, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, 0, 1, 0));
        assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, 0, 1, 0));
    }

    void assertThrowsNPE(Runnable r) {
        NullPointerException caught = null;
        try {
            r.run();
        }
        catch (NullPointerException e) {
            caught = e;
        }
        assertNotNull(caught, "NullPointerException not thrown");
    }

    void assertThrowsAIOOB(Runnable r) {
        ArrayIndexOutOfBoundsException caught = null;
        try {
            r.run();
        }
        catch (ArrayIndexOutOfBoundsException e) {
            caught = e;
        }
        assertNotNull(caught, "ArrayIndexOutOfBoundsException not thrown");
    }
}
