aboutsummaryrefslogtreecommitdiff
path: root/extensions/proto/src/main/java/com/google/common/truth/extensions/proto/IterableOfProtosUsingCorrespondence.java
blob: 5a49369af58b3b6a3e297449b8a62dc13550a48a (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
/*
 * 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.extensions.proto;

import com.google.common.base.Function;
import com.google.common.truth.Ordered;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.protobuf.Message;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Comparison methods, which enforce the rules set in prior calls to {@link
 * IterableOfProtosFluentAssertion}.
 */
public interface IterableOfProtosUsingCorrespondence<M extends Message> {

  /**
   * Specifies a way to pair up unexpected and missing elements in the message when an assertion
   * fails. For example:
   *
   * <pre>{@code
   * assertThat(actualFoos)
   *     .ignoringRepeatedFieldOrder()
   *     .ignoringFields(Foo.BAR_FIELD_NUMBER)
   *     .displayingDiffsPairedBy(Foo::getId)
   *     .containsExactlyElementsIn(expectedFoos);
   * }</pre>
   *
   * <p>On assertions where it makes sense to do so, the elements are paired as follows: they are
   * keyed by {@code keyFunction}, and if an unexpected element and a missing element have the same
   * non-null key then the they are paired up. (Elements with null keys are not paired.) The failure
   * message will show paired elements together, and a diff will be shown.
   *
   * <p>The expected elements given in the assertion should be uniquely keyed by {@code
   * keyFunction}. If multiple missing elements have the same key then the pairing will be skipped.
   *
   * <p>Useful key functions will have the property that key equality is less strict than the
   * already specified equality rules; i.e. given {@code actual} and {@code expected} values with
   * keys {@code actualKey} and {@code expectedKey}, if {@code actual} and {@code expected} compare
   * equal given the rest of the directives such as {@code ignoringRepeatedFieldOrder} and {@code
   * ignoringFields}, then it is guaranteed that {@code actualKey} is equal to {@code expectedKey},
   * but there are cases where {@code actualKey} is equal to {@code expectedKey} but the direct
   * comparison fails.
   *
   * <p>Note that calling this method makes no difference to whether a test passes or fails, it just
   * improves the message if it fails.
   */
  IterableOfProtosUsingCorrespondence<M> displayingDiffsPairedBy(
      Function<? super M, ?> keyFunction);

  /**
   * Checks that the subject contains at least one element that corresponds to the given expected
   * element.
   */
  void contains(@Nullable M expected);

  /** Checks that none of the actual elements correspond to the given element. */
  void doesNotContain(@Nullable M excluded);

  /**
   * Checks that subject contains exactly elements that correspond to the expected elements, i.e.
   * that there is a 1:1 mapping between the actual elements and the expected elements where each
   * pair of elements correspond.
   *
   * <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.
   *
   * <p>To test that the iterable contains the same elements as an array, prefer {@link
   * #containsExactlyElementsIn(Message[])}. It makes clear that the given array is a list of
   * elements, not an element itself.
   */
  @CanIgnoreReturnValue
  Ordered containsExactly(/*@Nullable*/ M... expected);

  /**
   * Checks that subject contains exactly elements that correspond to the expected elements, i.e.
   * that there is a 1:1 mapping between the actual elements and the expected elements where each
   * pair of elements correspond.
   *
   * <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
  Ordered containsExactlyElementsIn(Iterable<? extends M> expected);

  /**
   * Checks that subject contains exactly elements that correspond to the expected elements, i.e.
   * that there is a 1:1 mapping between the actual elements and the expected elements where each
   * pair of elements correspond.
   *
   * <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
  Ordered containsExactlyElementsIn(M[] expected);

  /**
   * Checks that the subject contains elements that corresponds to all of the expected elements,
   * i.e. that there is a 1:1 mapping between any subset of the actual elements and the expected
   * elements where each pair of elements correspond.
   *
   * <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 elements must appear in the given order within the
   * subject, but they are not required to be consecutive.
   */
  @CanIgnoreReturnValue
  Ordered containsAtLeast(@Nullable M first, @Nullable M second, /*@Nullable*/ M... rest);

  /**
   * Checks that the subject contains elements that corresponds to all of the expected elements,
   * i.e. that there is a 1:1 mapping between any subset of the actual elements and the expected
   * elements where each pair of elements correspond.
   *
   * <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 elements must appear in the given order within the
   * subject, but they are not required to be consecutive.
   */
  @CanIgnoreReturnValue
  Ordered containsAtLeastElementsIn(Iterable<? extends M> expected);

  /**
   * Checks that the subject contains elements that corresponds to all of the expected elements,
   * i.e. that there is a 1:1 mapping between any subset of the actual elements and the expected
   * elements where each pair of elements correspond.
   *
   * <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 elements must appear in the given order within the
   * subject, but they are not required to be consecutive.
   */
  @CanIgnoreReturnValue
  Ordered containsAtLeastElementsIn(M[] expected);

  /**
   * Checks that the subject contains at least one element that corresponds to at least one of the
   * expected elements.
   */
  void containsAnyOf(@Nullable M first, @Nullable M second, /*@Nullable*/ M... rest);

  /**
   * Checks that the subject contains at least one element that corresponds to at least one of the
   * expected elements.
   */
  void containsAnyIn(Iterable<? extends M> expected);

  /**
   * Checks that the subject contains at least one element that corresponds to at least one of the
   * expected elements.
   */
  void containsAnyIn(M[] expected);

  /**
   * Checks that the subject contains no elements that correspond to any of the given elements.
   * (Duplicates are irrelevant to this test, which fails if any of the subject elements correspond
   * to any of the given elements.)
   */
  void containsNoneOf(
      @Nullable M firstExcluded, @Nullable M secondExcluded, /*@Nullable*/ M... restOfExcluded);

  /**
   * Checks that the subject contains no elements that correspond to any of the given elements.
   * (Duplicates are irrelevant to this test, which fails if any of the subject elements correspond
   * to any of the given elements.)
   */
  void containsNoneIn(Iterable<? extends M> excluded);

  /**
   * Checks that the subject contains no elements that correspond to any of the given elements.
   * (Duplicates are irrelevant to this test, which fails if any of the subject elements correspond
   * to any of the given elements.)
   */
  void containsNoneIn(M[] excluded);
}