1 package io.atlassian.fugue;
2
3 import org.junit.Rule;
4 import org.junit.Test;
5 import org.junit.rules.ExpectedException;
6
7 import java.util.Iterator;
8 import java.util.NoSuchElementException;
9 import java.util.Objects;
10 import java.util.concurrent.atomic.AtomicBoolean;
11 import java.util.function.Function;
12 import java.util.stream.Stream;
13
14 import static java.util.function.Function.identity;
15 import static java.util.stream.Collectors.toList;
16 import static org.hamcrest.CoreMatchers.instanceOf;
17 import static org.hamcrest.Matchers.emptyIterable;
18 import static org.hamcrest.Matchers.notNullValue;
19 import static org.hamcrest.core.Is.is;
20 import static org.junit.Assert.assertThat;
21
22 public class TryFailureTest {
23
24 @Rule public ExpectedException thrown = ExpectedException.none();
25
26 private final Integer ANOTHER_VALUE = 99;
27
28 private class TestException extends RuntimeException {
29 TestException(final String message) {
30 super(message);
31 }
32
33 @Override public int hashCode() {
34 return Objects.hashCode(getMessage());
35 }
36
37 @Override public boolean equals(Object obj) {
38 if (this == obj) {
39 return true;
40 }
41 if (!(obj instanceof TestException)) {
42 return false;
43 }
44
45 TestException other = (TestException) obj;
46 return Objects.equals(getMessage(), other.getMessage());
47 }
48 }
49
50 private static final String MESSAGE = "known exception message";
51 private final Try<Integer> t = Checked.now(() -> {
52 throw new TestException(MESSAGE);
53 });
54 private final Function<Exception, String> fThrows = x -> {
55 throw new TestException(MESSAGE);
56 };
57
58 private final Function<Exception, Try<Integer>> fTryThrows = x -> {
59 throw new RuntimeException();
60 };
61
62 @Test public void map() {
63 assertThat(t.map(x -> true), is(t));
64 }
65
66 @Test public void isFailure() {
67 assertThat(t.isFailure(), is(true));
68 }
69
70 @Test public void isSuccess() {
71 assertThat(t.isSuccess(), is(false));
72 }
73
74 @Test public void flatMap() {
75 assertThat(t.map(x -> true), is(t));
76 }
77
78 @Test public void recover() {
79 assertThat(t.recover(x -> 0), is(Checked.now(() -> 0)));
80 }
81
82 @Test public void recoverMatchingException() {
83 assertThat(t.recover(TestException.class, x -> 0), is(t.recover(x -> 0)));
84 }
85
86 @Test public void recoverMismatchingException() {
87 assertThat(t.recover(IllegalStateException.class, x -> 0), is(t));
88 }
89
90 @Test public void recoverWith() {
91 assertThat(t.recoverWith(x -> Checked.now(() -> 0)), is(Checked.now(() -> 0)));
92 }
93
94 @Test public void recoverWithMatchingException() {
95 assertThat(t.recoverWith(TestException.class, x -> Checked.now(() -> 0)), is(t.recoverWith(x -> Checked.now(() -> 0))));
96 }
97
98 @Test public void recoverWithMismatchingException() {
99 assertThat(t.recoverWith(IllegalStateException.class, x -> Checked.now(() -> 0)), is(t));
100 }
101
102 @Test public void recoverWithPassedThrowingFunctionThrows() {
103 thrown.expect(RuntimeException.class);
104
105 t.recoverWith(fTryThrows);
106 }
107
108 @Test public void getOrElse() {
109 assertThat(t.getOrElse(() -> 0), is(0));
110 }
111
112 @Test public void fold() {
113 Exception e = t.fold(identity(), v -> {
114 throw new RuntimeException();
115 });
116
117 assertThat(e, instanceOf(TestException.class));
118 assertThat(e.getMessage(), is(MESSAGE));
119 }
120
121 @Test public void foldPassedThrowingExceptionsThrows() {
122 thrown.expect(TestException.class);
123
124 t.fold(fThrows, x -> "x");
125 }
126
127 @Test public void toEither() {
128 final Either<Exception, Integer> e = t.toEither();
129
130 assertThat(e.isLeft(), is(true));
131 assertThat(e.left().get(), instanceOf(TestException.class));
132 assertThat(e.left().get().getMessage(), is(MESSAGE));
133 }
134
135 @Test public void toOption() {
136 assertThat(t.toOption(), is(Option.none()));
137 }
138
139 @Test public void liftingFunctionThatThrowsReturnsFailure() {
140 Try<Integer> result = Checked.<String, Integer, TestException> lift(x -> {
141 throw new TestException(MESSAGE);
142 }).apply("test");
143
144 assertThat(result.isFailure(), is(true));
145
146 final Exception e = result.fold(identity(), x -> {
147 throw new NoSuchElementException();
148 });
149 assertThat(e, instanceOf(TestException.class));
150 assertThat(e.getMessage(), is(MESSAGE));
151 }
152
153 @Test public void toOptional() {
154 assertThat(t.toOption(), is(Option.none()));
155 }
156
157 @Test public void toStream() {
158 final Stream<Integer> stream = t.toStream();
159 assertThat(stream, notNullValue());
160 assertThat(stream.collect(toList()), emptyIterable());
161 }
162
163 @Test public void forEach() {
164 final AtomicBoolean invoked = new AtomicBoolean(false);
165 t.forEach(v -> invoked.set(true));
166
167 assertThat(invoked.get(), is(false));
168 }
169
170 @Test public void orElseSuccessInstance() {
171 Try<Integer> successful = Try.successful(ANOTHER_VALUE);
172 final Try<Integer> orElse = t.orElse(successful);
173 assertThat(orElse, is(successful));
174 }
175
176 @Test public void orElseSuccessSupplier() {
177 Try<Integer> successful = Try.successful(ANOTHER_VALUE);
178 final Try<Integer> orElse = t.orElse(() -> successful);
179 assertThat(orElse, is(successful));
180 }
181
182 @Test public void orElseFailureInstance() {
183 Try<Integer> failure = Try.failure(new TestException("Failure instance"));
184 final Try<Integer> orElse = t.orElse(failure);
185 assertThat(orElse, is(failure));
186 }
187
188 @Test public void orElseFailureSupplier() {
189 Try<Integer> failure = Try.failure(new TestException("Failure instance"));
190 final Try<Integer> orElse = t.orElse(() -> failure);
191 assertThat(orElse, is(failure));
192 }
193
194 @Test public void filterOrElseTrue() {
195 final Try<Integer> filter = t.filterOrElse(value -> true, () -> new TestException("this is a different error"));
196 assertThat(filter, is(t));
197 }
198
199 @Test public void filterOrElseFalseFailure() {
200 final Try<Integer> filter = t.filterOrElse(value -> false, () -> new TestException("this is a different error"));
201 assertThat(filter, is(t));
202 }
203
204 @Test public void iteratorEmpty() {
205 Iterator<Integer> iterator = t.iterator();
206 assertThat(iterator.hasNext(), is(false));
207 }
208
209 }