1 package io.atlassian.fugue;
2
3 import static io.atlassian.fugue.Either.left;
4 import static io.atlassian.fugue.Either.right;
5 import static io.atlassian.fugue.EitherRightProjectionTest.reverseToEither;
6 import static io.atlassian.fugue.Option.none;
7 import static io.atlassian.fugue.Option.some;
8 import static io.atlassian.fugue.UtilityFunctions.addOne;
9 import static io.atlassian.fugue.UtilityFunctions.reverse;
10 import static java.util.stream.Collectors.toList;
11 import static org.hamcrest.Matchers.contains;
12 import static org.hamcrest.Matchers.empty;
13 import static org.hamcrest.Matchers.is;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertThat;
16 import static org.junit.Assert.fail;
17
18 import java.util.Optional;
19 import java.util.concurrent.atomic.AtomicBoolean;
20 import java.util.function.Function;
21
22 import org.hamcrest.Matchers;
23 import org.junit.Test;
24
25 public class EitherRightBiasTest {
26 private final Either<String, Integer> l = left("heyaa!");
27 private final Either<String, Integer> r = right(12);
28
29 @Test public void mapRight() {
30 assertThat(Either.<String, Integer> right(3).map(addOne), is(Either.<String, Integer> right(4)));
31 }
32
33 @Test public void mapLeft() {
34 assertThat(Either.<String, Integer> left("foo").map(addOne), is(Either.<String, Integer> left("foo")));
35 }
36
37 @Test public void flatMapRight() {
38 assertThat(Either.<Integer, String> right("!foo").flatMap(reverseToEither), is(Either.<Integer, String> right("oof!")));
39 }
40
41 @Test public void flatMapLeft() {
42 assertThat(Either.<Integer, String> left(5).flatMap(reverseToEither), is(Either.<Integer, String> left(5)));
43 }
44
45 @Test public void leftMapRight() {
46 assertThat(Either.<Integer, String> right("foo").leftMap(addOne), is(Either.<Integer, String> right("foo")));
47 }
48
49 @Test public void leftMapLeft() {
50 assertThat(Either.<Integer, String> left(3).leftMap(addOne), is(Either.<Integer, String> left(4)));
51 }
52
53 @Test public void getOrRight() {
54 assertThat(r.getOr(Suppliers.ofInstance(1)), is(12));
55 }
56
57 @Test public void getOrLeft() {
58 assertThat(l.getOr(Suppliers.ofInstance(1)), is(1));
59 }
60
61 @Test public void getOrElseSupplierRight() {
62 @SuppressWarnings("deprecation")
63 final Integer orElse = r.getOrElse(Suppliers.ofInstance(1));
64 assertThat(orElse, is(12));
65 }
66
67 @Test public void getOrElseSupplierLeft() {
68 @SuppressWarnings("deprecation")
69 final Integer orElse = l.getOrElse(Suppliers.ofInstance(1));
70 assertThat(orElse, is(1));
71 }
72
73 @Test public void getOrElseRight() {
74 assertThat(r.getOrElse(1), is(12));
75 }
76
77 @Test public void getOrElseLeft() {
78 assertThat(l.getOrElse(1), is(1));
79 }
80
81 @Test public void getOrNullRight() {
82 assertThat(r.getOrNull(), is(12));
83 }
84
85 @Test public void getOrNullLeft() {
86 assertNull(l.getOrNull());
87 }
88
89 @Test public void getOrErrorRight() {
90 assertThat(r.getOrError(Suppliers.ofInstance("Error message")), is(12));
91 }
92
93 @Test(expected = AssertionError.class) public void getOrErrorLeft() {
94 l.getOrError(Suppliers.ofInstance("Error message"));
95 }
96
97 @Test public void getOrErrorLeftMessage() {
98 try {
99 l.getOrError(Suppliers.ofInstance("Error message"));
100 } catch (final Error e) {
101 assertThat(e.getMessage(), is("Error message"));
102 return;
103 }
104
105 fail("No error thrown");
106 }
107
108 @Test public void getOrThrowRight() {
109 assertThat(r.getOrThrow(Suppliers.ofInstance(new RuntimeException("Run Error"))), is(12));
110 }
111
112 private class CustomException extends RuntimeException {
113 private static final long serialVersionUID = -633224822465345980L;
114 }
115
116 @Test(expected = CustomException.class) public void getOrThrowLeft() {
117 l.getOrThrow(Suppliers.ofInstance(new CustomException()));
118 }
119
120 @Test public void existsRight() {
121 assertThat(r.exists(x -> x == 12), is(true));
122 assertThat(r.exists(x -> x == 11), is(false));
123 }
124
125 @Test public void existsLeft() {
126 assertThat(l.exists(x -> x == 12), is(false));
127 }
128
129 @Test public void forallRight() {
130 assertThat(r.forall(x -> x == 12), is(true));
131 assertThat(r.forall(x -> x == 11), is(false));
132 }
133
134 @Test public void forallLeft() {
135 assertThat(l.forall(x -> x == 12), is(true));
136 }
137
138 @Test public void foreachRight() {
139 final AtomicBoolean called = new AtomicBoolean(false);
140 @SuppressWarnings("deprecation")
141 final Effect<Integer> effect = integer -> called.set(true);
142
143 r.forEach(effect);
144
145 assertThat(called.get(), is(true));
146 }
147
148 @Test public void foreachLeft() {
149 final AtomicBoolean called = new AtomicBoolean(false);
150 @SuppressWarnings("deprecation")
151 final Effect<Integer> effect = integer -> called.set(true);
152
153 l.forEach(effect);
154
155 assertThat(called.get(), is(false));
156 }
157
158 @Test public void filterRight() {
159 assertThat(r.filter(x -> x == 12), is(some(r)));
160 assertThat(r.filter(x -> x == 11), is(Option.<Either<String, Integer>> none()));
161 }
162
163 @Test public void filterLeft() {
164 assertThat(l.filter(x -> x == 12), is(Option.<Either<String, Integer>> none()));
165 }
166
167 @Test public void orElseRightInstance() {
168 assertThat(r.orElse(Either.<String, Integer> right(44)), is(r));
169 }
170
171 @Test public void orElseLeftInstance() {
172 assertThat(l.orElse(Either.<String, Integer> right(44)), is(Either.<String, Integer> right(44)));
173 assertThat(l.orElse(Either.<String, Integer> left("left")), is(Either.<String, Integer> left("left")));
174 }
175
176 @Test public void orElseRightSupplier() {
177 assertThat(r.orElse(Suppliers.ofInstance(Either.<String, Integer> right(44))), is(r));
178 }
179
180 @Test public void orElseLeftSupplier() {
181 assertThat(l.orElse(Suppliers.ofInstance(Either.<String, Integer> right(44))), is(Either.<String, Integer> right(44)));
182 assertThat(l.orElse(Suppliers.ofInstance(Either.<String, Integer> left("left"))), is(Either.<String, Integer> left("left")));
183 }
184
185 @Test public void orElseChild() {
186 class Parent {}
187 class Child extends Parent {}
188
189 final Parent p = new Parent();
190 final Parent pp = right(p).orElse(Suppliers.ofInstance(Either.<Integer, Child> right(new Child()))).getOrNull();
191 assertThat(pp, is(p));
192 }
193
194 @Test public void rightOr_valueIsARight_returnsRightValue() {
195 assertThat(r.rightOr(Functions.constant(99)), is(12));
196 }
197
198 @Test public void rightOr_valueIsALeft_returnsLeftTransformerResult() {
199 assertThat(l.rightOr(Functions.constant(99)), is(99));
200 }
201
202 @Test public void leftOr_valueIsALeft_returnsLeftValue() {
203 assertThat(l.leftOr(Functions.constant("s")), is("heyaa!"));
204 }
205
206 @Test public void leftOr_valueIsARight_returnsRightTransformerResult() {
207 assertThat(r.leftOr(Functions.constant("s")), is("s"));
208 }
209
210 @Test public void flatMapSubTypesOnLeft() {
211 class ErrorType {}
212 class AnotherErrorType extends ErrorType {}
213
214 final AnotherErrorType anotherErrorType = new AnotherErrorType();
215 final Either<AnotherErrorType, Long> l = Either.left(anotherErrorType);
216
217 final Either<ErrorType, Long> longEither = Either.<ErrorType, Integer> right(1).flatMap(input -> l);
218
219 final ErrorType errorType = longEither.left().get();
220
221 assertThat(errorType, Matchers.<ErrorType> is(anotherErrorType));
222 }
223
224 @Test public void flatMapWithUpcastAndSubtypesOnLeft() {
225 class ErrorType {}
226 class MyErrorType extends ErrorType {}
227 class AnotherErrorType extends ErrorType {}
228
229 final AnotherErrorType anotherErrorType = new AnotherErrorType();
230
231 final Either<MyErrorType, Boolean> l = Either.right(true);
232 final Either<AnotherErrorType, Long> l2 = Either.left(anotherErrorType);
233
234 final Either<ErrorType, Long> either = Eithers.<ErrorType, MyErrorType, Boolean> upcastLeft(l).flatMap(input -> l2);
235
236 final ErrorType errorType = either.left().get();
237
238 assertThat(errorType, Matchers.<ErrorType> is(anotherErrorType));
239 }
240
241 @Test public void toOptionRight() {
242 assertThat(r.toOption(), is(some(12)));
243 }
244
245 @Test public void toOptionLeft() {
246 assertThat(l.toOption(), is(none()));
247 }
248
249 @Test public void toStreamRight() {
250 assertThat(r.toStream().collect(toList()), contains(12));
251 }
252
253 @Test public void toStreamLeft() {
254 assertThat(l.toStream().collect(toList()), empty());
255 }
256
257 @Test public void toOptionalRight() {
258 assertThat(r.toOptional(), is(Optional.of(12)));
259 }
260
261 @Test public void toOptionalLeft() {
262 assertThat(l.toOptional(), is(Optional.empty()));
263 }
264
265 @Test public void sequenceDefined() {
266 final Either<String, Integer> e = right(98);
267 assertThat(r.sequence(e).right().get(), is(98));
268 }
269
270 @Test public void sequenceNotDefined() {
271 final Either<String, Integer> e = left("bar");
272 assertThat(l.sequence(e).left().get(), is("heyaa!"));
273 }
274
275 @Test public void apDefinedRight() {
276 final Either<String, Function<Integer, String>> func = right(reverse.compose(Object::toString));
277 assertThat(r.ap(func).right().get(), is("21"));
278 }
279
280 @Test public void apDefinedLeft() {
281 final Either<String, Function<Integer, String>> func = left("woo");
282 assertThat(r.ap(func).left().get(), is("woo"));
283 }
284
285 @Test public void apNotDefinedRight() {
286 final Either<String, Function<Integer, String>> func = right(reverse.compose(Object::toString));
287 assertThat(l.ap(func).left().get(), is("heyaa!"));
288 }
289
290 @Test public void apNotDefinedLeft() {
291 final Either<String, Function<Integer, String>> func = left("woo");
292 assertThat(l.ap(func).left().get(), is("woo"));
293 }
294
295 }