1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.concurrent;
18
19 import static org.easymock.EasyMock.expect;
20 import static org.easymock.EasyMock.replay;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23
24 import java.util.function.Function;
25
26 import org.apache.commons.lang3.AbstractLangTest;
27 import org.easymock.EasyMock;
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30
31 public class MemoizerFunctionTest extends AbstractLangTest {
32
33 private Function<Integer, Integer> function;
34
35 @BeforeEach
36 public void setUpComputableMock() {
37 function = EasyMock.mock(Function.class);
38 }
39
40 @Test
41 public void testDefaultBehaviourNotToRecalculateExecutionExceptions() throws Exception {
42 final Integer input = 1;
43 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function);
44 final IllegalArgumentException interruptedException = new IllegalArgumentException();
45 expect(function.apply(input)).andThrow(interruptedException);
46 replay(function);
47
48 assertThrows(Throwable.class, () -> memoizer.compute(input));
49 assertThrows(IllegalArgumentException.class, () -> memoizer.compute(input));
50 }
51
52 @Test
53 public void testDoesNotRecalculateWhenSetToFalse() throws Exception {
54 final Integer input = 1;
55 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function, false);
56 final IllegalArgumentException interruptedException = new IllegalArgumentException();
57 expect(function.apply(input)).andThrow(interruptedException);
58 replay(function);
59
60 assertThrows(Throwable.class, () -> memoizer.compute(input));
61 assertThrows(IllegalArgumentException.class, () -> memoizer.compute(input));
62 }
63
64 @Test
65 public void testDoesRecalculateWhenSetToTrue() throws Exception {
66 final Integer input = 1;
67 final Integer answer = 3;
68 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function, true);
69 final IllegalArgumentException interruptedException = new IllegalArgumentException();
70 expect(function.apply(input)).andThrow(interruptedException).andReturn(answer);
71 replay(function);
72
73 assertThrows(Throwable.class, () -> memoizer.compute(input));
74 assertEquals(answer, memoizer.compute(input));
75 }
76
77 @Test
78 public void testOnlyCallComputableOnceIfDoesNotThrowException() throws Exception {
79 final Integer input = 1;
80 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function);
81 expect(function.apply(input)).andReturn(input);
82 replay(function);
83
84 assertEquals(input, memoizer.compute(input), "Should call computable first time");
85 assertEquals(input, memoizer.compute(input), "Should not call the computable the second time");
86 }
87
88 @Test
89 public void testWhenComputableThrowsError() throws Exception {
90 final Integer input = 1;
91 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function);
92 final Error error = new Error();
93 expect(function.apply(input)).andThrow(error);
94 replay(function);
95
96 assertThrows(Error.class, () -> memoizer.compute(input));
97 }
98
99 @Test
100 public void testWhenComputableThrowsRuntimeException() throws Exception {
101 final Integer input = 1;
102 final Memoizer<Integer, Integer> memoizer = new Memoizer<>(function);
103 final RuntimeException runtimeException = new RuntimeException("Some runtime exception");
104 expect(function.apply(input)).andThrow(runtimeException);
105 replay(function);
106
107 assertThrows(RuntimeException.class, () -> memoizer.compute(input));
108 }
109 }