package games.strategy.util;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.SwingUtilities;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public final class EventThreadJOptionPaneTest {
@Rule
public final Timeout globalTimeout = new Timeout(5, TimeUnit.SECONDS);
@Spy
private final CountDownLatchHandler latchHandler = new CountDownLatchHandler(true);
@Test
public void testInvokeAndWaitWithSupplier_ShouldRunSupplierOnEDTWhenNotCalledFromEDT() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean runOnEDT = new AtomicBoolean(false);
new Thread(() -> {
EventThreadJOptionPane.invokeAndWait(latchHandler, () -> {
runOnEDT.set(SwingUtilities.isEventDispatchThread());
return Optional.empty();
});
latch.countDown();
}).start();
latch.await();
assertThat(runOnEDT.get(), is(true));
}
@Test
public void testInvokeAndWaitWithSupplier_ShouldNotDeadlockWhenCalledFromEDT() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean run = new AtomicBoolean(false);
SwingUtilities.invokeLater(() -> {
EventThreadJOptionPane.invokeAndWait(latchHandler, () -> {
run.set(true);
return Optional.empty();
});
latch.countDown();
});
latch.await();
assertThat(run.get(), is(true));
}
@Test
public void testInvokeAndWaitWithSupplier_ShouldReturnSupplierResult() {
final Object expectedResult = new Object();
final Object actualResult =
EventThreadJOptionPane.invokeAndWait(latchHandler, () -> Optional.of(expectedResult)).get();
assertThat(actualResult, is(expectedResult));
}
@Test
public void testInvokeAndWaitWithSupplier_ShouldRegisterAndUnregisterLatchWithLatchHandler() {
EventThreadJOptionPane.invokeAndWait(latchHandler, () -> Optional.empty());
verify(latchHandler, times(1)).addShutdownLatch(any(CountDownLatch.class));
verify(latchHandler, times(1)).removeShutdownLatch(any(CountDownLatch.class));
}
@Test
public void testInvokeAndWaitWithSupplier_ShouldRunSuccessfullyWhenLatchHandlerIsNull() {
final Object expectedResult = new Object();
final Object actualResult = EventThreadJOptionPane.invokeAndWait(null, () -> Optional.of(expectedResult)).get();
assertThat(actualResult, is(expectedResult));
}
@Test
public void testInvokeAndWaitWithIntSupplier_ShouldReturnIntSupplierResult() {
final int expectedResult = 42;
final int actualResult = EventThreadJOptionPane.invokeAndWait(latchHandler, () -> expectedResult);
assertThat(actualResult, is(expectedResult));
}
}