aboutsummaryrefslogtreecommitdiff
path: root/extensions/java8/src/main/java/com/google/common/truth/IntStreamSubject.java
blob: 45699bce8b198163c0e88eb37aa74af531d4134c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright (c) 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.common.truth;

import static java.util.stream.Collectors.toCollection;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Propositions for {@link IntStream} subjects.
 *
 * <p><b>Note:</b> the wrapped stream will be drained immediately into a private collection to
 * provide more readable failure messages. You should not use this class if you intend to leave the
 * stream un-consumed or if the stream is <i>very</i> large or infinite.
 *
 * <p>If you intend to make multiple assertions on the same stream of data you should instead first
 * collect the contents of the stream into a collection, and then assert directly on that.
 *
 * <p>For very large or infinite streams you may want to first {@linkplain Stream#limit limit} the
 * stream before asserting on it.
 *
 * @author Kurt Alfred Kluever
 */
@SuppressWarnings("deprecation") // TODO(b/134064106): design an alternative to no-arg check()
public final class IntStreamSubject extends Subject {

  private final List<?> actualList;

  private IntStreamSubject(FailureMetadata failureMetadata, @Nullable IntStream stream) {
    super(failureMetadata, stream);
    this.actualList =
        (stream == null) ? null : stream.boxed().collect(toCollection(ArrayList::new));
  }

  @Override
  protected String actualCustomStringRepresentation() {
    return String.valueOf(actualList);
  }

  public static Factory<IntStreamSubject, IntStream> intStreams() {
    return IntStreamSubject::new;
  }

  /** Fails if the subject is not empty. */
  public void isEmpty() {
    check().that(actualList).isEmpty();
  }

  /** Fails if the subject is empty. */
  public void isNotEmpty() {
    check().that(actualList).isNotEmpty();
  }

  /**
   * Fails if the subject does not have the given size.
   *
   * <p>If you'd like to check that your stream contains more than {@link Integer#MAX_VALUE}
   * elements, use {@code assertThat(stream.count()).isEqualTo(...)}.
   */
  public void hasSize(int expectedSize) {
    check().that(actualList).hasSize(expectedSize);
  }

  /** Fails if the subject does not contain the given element. */
  public void contains(int element) {
    check().that(actualList).contains(element);
  }

  /** Fails if the subject contains the given element. */
  public void doesNotContain(int element) {
    check().that(actualList).doesNotContain(element);
  }

  /** Fails if the subject contains duplicate elements. */
  public void containsNoDuplicates() {
    check().that(actualList).containsNoDuplicates();
  }

  /** Fails if the subject does not contain at least one of the given elements. */
  @SuppressWarnings("GoodTime") // false positive; b/122617528
  public void containsAnyOf(int first, int second, int... rest) {
    check().that(actualList).containsAnyOf(first, second, box(rest));
  }

  /** Fails if the subject does not contain at least one of the given elements. */
  public void containsAnyIn(Iterable<?> expected) {
    check().that(actualList).containsAnyIn(expected);
  }

  /**
   * Fails if the subject does not contain all of the given elements. If an element appears more
   * than once in the given elements, then it must appear at least that number of times in the
   * actual elements.
   *
   * <p>To also test that the contents appear in the given order, make a call to {@code inOrder()}
   * on the object returned by this method. The expected elements must appear in the given order
   * within the actual elements, but they are not required to be consecutive.
   */
  @SuppressWarnings("GoodTime") // false positive; b/122617528
  @CanIgnoreReturnValue
  public Ordered containsAtLeast(int first, int second, int... rest) {
    return check().that(actualList).containsAtLeast(first, second, box(rest));
  }

  /**
   * Fails if the subject does not contain all of the given elements. If an element appears more
   * than once in the given elements, then it must appear at least that number of times in the
   * actual elements.
   *
   * <p>To also test that the contents appear in the given order, make a call to {@code inOrder()}
   * on the object returned by this method. The expected elements must appear in the given order
   * within the actual elements, but they are not required to be consecutive.
   */
  @CanIgnoreReturnValue
  public Ordered containsAtLeastElementsIn(Iterable<?> expected) {
    return check().that(actualList).containsAtLeastElementsIn(expected);
  }

  /**
   * Fails if the subject does not contain exactly the given elements.
   *
   * <p>Multiplicity is respected. For example, an object duplicated exactly 3 times in the
   * parameters asserts that the object must likewise be duplicated exactly 3 times in the subject.
   *
   * <p>To also test that the contents appear in the given order, make a call to {@code inOrder()}
   * on the object returned by this method.
   */
  @CanIgnoreReturnValue
  public Ordered containsExactly(int... varargs) {
    return check().that(actualList).containsExactlyElementsIn(box(varargs));
  }

  /**
   * Fails if the subject does not contain exactly the given elements.
   *
   * <p>Multiplicity is respected. For example, an object duplicated exactly 3 times in the
   * parameters asserts that the object must likewise be duplicated exactly 3 times in the subject.
   *
   * <p>To also test that the contents appear in the given order, make a call to {@code inOrder()}
   * on the object returned by this method.
   */
  @CanIgnoreReturnValue
  public Ordered containsExactlyElementsIn(Iterable<?> expected) {
    return check().that(actualList).containsExactlyElementsIn(expected);
  }

  /**
   * Fails if the subject contains any of the given elements. (Duplicates are irrelevant to this
   * test, which fails if any of the actual elements equal any of the excluded.)
   */
  @SuppressWarnings("GoodTime") // false positive; b/122617528
  public void containsNoneOf(int first, int second, int... rest) {
    check().that(actualList).containsNoneOf(first, second, box(rest));
  }

  /**
   * Fails if the subject contains any of the given elements. (Duplicates are irrelevant to this
   * test, which fails if any of the actual elements equal any of the excluded.)
   */
  public void containsNoneIn(Iterable<?> excluded) {
    check().that(actualList).containsNoneIn(excluded);
  }

  /**
   * Fails if the subject is not strictly ordered, according to the natural ordering of its
   * elements. Strictly ordered means that each element in the stream is <i>strictly</i> greater
   * than the element that preceded it.
   *
   * @throws ClassCastException if any pair of elements is not mutually Comparable
   * @throws NullPointerException if any element is null
   */
  public void isInStrictOrder() {
    check().that(actualList).isInStrictOrder();
  }

  /**
   * Fails if the subject is not strictly ordered, according to the given comparator. Strictly
   * ordered means that each element in the stream is <i>strictly</i> greater than the element that
   * preceded it.
   *
   * @throws ClassCastException if any pair of elements is not mutually Comparable
   */
  public void isInStrictOrder(Comparator<? super Integer> comparator) {
    check().that(actualList).isInStrictOrder(comparator);
  }

  /**
   * Fails if the subject is not ordered, according to the natural ordering of its elements. Ordered
   * means that each element in the stream is greater than or equal to the element that preceded it.
   *
   * @throws ClassCastException if any pair of elements is not mutually Comparable
   * @throws NullPointerException if any element is null
   */
  public void isInOrder() {
    check().that(actualList).isInOrder();
  }

  /**
   * Fails if the subject is not ordered, according to the given comparator. Ordered means that each
   * element in the stream is greater than or equal to the element that preceded it.
   *
   * @throws ClassCastException if any pair of elements is not mutually Comparable
   */
  public void isInOrder(Comparator<? super Integer> comparator) {
    check().that(actualList).isInOrder(comparator);
  }

  private static Object[] box(int[] rest) {
    return IntStream.of(rest).boxed().toArray(Integer[]::new);
  }

  // TODO(user): Do we want to override + deprecate isEqualTo/isNotEqualTo?

  // TODO(user): Do we want to support comparingElementsUsing() on StreamSubject?
}