1/*
2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @summary Tests counting of streams
27 * @bug 8031187 8067969 8075307
28 */
29
30package org.openjdk.tests.java.util.stream;
31
32import java.util.HashSet;
33import java.util.concurrent.atomic.AtomicInteger;
34import java.util.stream.Collectors;
35import java.util.stream.DoubleStream;
36import java.util.stream.DoubleStreamTestDataProvider;
37import java.util.stream.IntStream;
38import java.util.stream.IntStreamTestDataProvider;
39import java.util.stream.LongStream;
40import java.util.stream.LongStreamTestDataProvider;
41import java.util.stream.OpTestCase;
42import java.util.stream.Stream;
43import java.util.stream.StreamTestDataProvider;
44import java.util.stream.TestData;
45
46import org.testng.annotations.Test;
47
48public class CountTest extends OpTestCase {
49
50    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
51    public void testOps(String name, TestData.OfRef<Integer> data) {
52        long expectedCount = data.size();
53
54        withData(data).
55                terminal(Stream::count).
56                expectedResult(expectedCount).
57                exercise();
58
59        // Test with an unknown sized stream
60        withData(data).
61                terminal(s -> s.filter(e -> true), Stream::count).
62                expectedResult(expectedCount).
63                exercise();
64
65        // Test counting collector
66        withData(data).
67                terminal(s -> s, s -> s.collect(Collectors.counting())).
68                expectedResult(expectedCount).
69                exercise();
70
71        // Test with stateful distinct op that is a barrier or lazy
72        // depending if source is not already distinct and encounter order is
73        // preserved or not
74        expectedCount = data.into(new HashSet<>()).size();
75        withData(data).
76                terminal(Stream::distinct, Stream::count).
77                expectedResult(expectedCount).
78                exercise();
79        withData(data).
80                terminal(s -> s.unordered().distinct(), Stream::count).
81                expectedResult(expectedCount).
82                exercise();
83    }
84
85    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
86    public void testOps(String name, TestData.OfInt data) {
87        long expectedCount = data.size();
88
89        withData(data).
90                terminal(IntStream::count).
91                expectedResult(expectedCount).
92                exercise();
93
94        withData(data).
95                terminal(s -> s.filter(e -> true), IntStream::count).
96                expectedResult(expectedCount).
97                exercise();
98
99        expectedCount = data.into(new HashSet<>()).size();
100        withData(data).
101                terminal(IntStream::distinct, IntStream::count).
102                expectedResult(expectedCount).
103                exercise();
104        withData(data).
105                terminal(s -> s.unordered().distinct(), IntStream::count).
106                expectedResult(expectedCount).
107                exercise();
108    }
109
110    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
111    public void testOps(String name, TestData.OfLong data) {
112        long expectedCount = data.size();
113
114        withData(data).
115                terminal(LongStream::count).
116                expectedResult(expectedCount).
117                exercise();
118
119        withData(data).
120                terminal(s -> s.filter(e -> true), LongStream::count).
121                expectedResult(expectedCount).
122                exercise();
123
124        expectedCount = data.into(new HashSet<>()).size();
125        withData(data).
126                terminal(LongStream::distinct, LongStream::count).
127                expectedResult(expectedCount).
128                exercise();
129        withData(data).
130                terminal(s -> s.unordered().distinct(), LongStream::count).
131                expectedResult(expectedCount).
132                exercise();
133    }
134
135    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
136    public void testOps(String name, TestData.OfDouble data) {
137        long expectedCount = data.size();
138
139        withData(data).
140                terminal(DoubleStream::count).
141                expectedResult(expectedCount).
142                exercise();
143
144        withData(data).
145                terminal(s -> s.filter(e -> true), DoubleStream::count).
146                expectedResult(expectedCount).
147                exercise();
148
149        expectedCount = data.into(new HashSet<>()).size();
150        withData(data).
151                terminal(DoubleStream::distinct, DoubleStream::count).
152                expectedResult(expectedCount).
153                exercise();
154        withData(data).
155                terminal(s -> s.unordered().distinct(), DoubleStream::count).
156                expectedResult(expectedCount).
157                exercise();
158    }
159
160    public void testNoEvaluationForSizedStream() {
161        {
162            AtomicInteger ai = new AtomicInteger();
163            Stream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).count();
164            assertEquals(ai.get(), 0);
165
166            Stream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).parallel().count();
167            assertEquals(ai.get(), 0);
168        }
169
170        {
171            AtomicInteger ai = new AtomicInteger();
172            IntStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).count();
173            assertEquals(ai.get(), 0);
174
175            IntStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).parallel().count();
176            assertEquals(ai.get(), 0);
177        }
178
179        {
180            AtomicInteger ai = new AtomicInteger();
181            LongStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).count();
182            assertEquals(ai.get(), 0);
183
184            LongStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).parallel().count();
185            assertEquals(ai.get(), 0);
186        }
187
188        {
189            AtomicInteger ai = new AtomicInteger();
190            DoubleStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).count();
191            assertEquals(ai.get(), 0);
192
193            DoubleStream.of(1, 2, 3, 4).peek(e -> ai.getAndIncrement()).parallel().count();
194            assertEquals(ai.get(), 0);
195        }
196    }
197}
198