Java 11 migration: ambassador async-method-invocation balking bridge builder (#1076)
* Moves ambassador pattern to java 11 * Moves async-method-invocation pattern to java 11 * Moves balking pattern to java 11 * Moves bridge pattern to java 11 * Moves builder pattern to java 11
This commit is contained in:
parent
f0f0143d48
commit
c4418311c6
@ -42,7 +42,7 @@ A remote services represented as a singleton.
|
||||
```java
|
||||
public class RemoteService implements RemoteServiceInterface {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
|
||||
private static RemoteService service = null;
|
||||
|
||||
static synchronized RemoteService getRemoteService() {
|
||||
@ -56,14 +56,14 @@ public class RemoteService implements RemoteServiceInterface {
|
||||
|
||||
@Override
|
||||
public long doRemoteFunction(int value) {
|
||||
|
||||
long waitTime = (long) Math.floor(Math.random() * 1000);
|
||||
|
||||
try {
|
||||
sleep(waitTime);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("Thread sleep interrupted", e)
|
||||
LOGGER.error("Thread sleep interrupted", e);
|
||||
}
|
||||
|
||||
return waitTime >= 200 ? value * 10 : -1;
|
||||
}
|
||||
}
|
||||
@ -137,7 +137,7 @@ public class Client {
|
||||
|
||||
long useService(int value) {
|
||||
long result = serviceAmbassador.doRemoteFunction(value);
|
||||
LOGGER.info("Service result: " + result)
|
||||
LOGGER.info("Service result: " + result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -146,10 +146,14 @@ public class Client {
|
||||
And here are two clients using the service.
|
||||
|
||||
```java
|
||||
Client host1 = new Client();
|
||||
Client host2 = new Client();
|
||||
host1.useService(12);
|
||||
host2.useService(73);
|
||||
public class App {
|
||||
public static void main(String[] args) {
|
||||
Client host1 = new Client();
|
||||
Client host2 = new Client();
|
||||
host1.useService(12);
|
||||
host2.useService(73);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Applicability
|
||||
|
@ -35,7 +35,7 @@ public class Client {
|
||||
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
|
||||
|
||||
long useService(int value) {
|
||||
long result = serviceAmbassador.doRemoteFunction(value);
|
||||
var result = serviceAmbassador.doRemoteFunction(value);
|
||||
LOGGER.info("Service result: " + result);
|
||||
return result;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
|
||||
* A remote legacy application represented by a Singleton implementation.
|
||||
*/
|
||||
public class RemoteService implements RemoteServiceInterface {
|
||||
static final int THRESHOLD = 200;
|
||||
private static final int THRESHOLD = 200;
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
|
||||
private static RemoteService service = null;
|
||||
private final RandomProvider randomProvider;
|
||||
@ -50,7 +50,7 @@ public class RemoteService implements RemoteServiceInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* This constuctor is used for testing purposes only.
|
||||
* This constructor is used for testing purposes only.
|
||||
*/
|
||||
RemoteService(RandomProvider randomProvider) {
|
||||
this.randomProvider = randomProvider;
|
||||
|
@ -48,21 +48,19 @@ public class ServiceAmbassador implements RemoteServiceInterface {
|
||||
}
|
||||
|
||||
private long checkLatency(int value) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long result = RemoteService.getRemoteService().doRemoteFunction(value);
|
||||
long timeTaken = System.currentTimeMillis() - startTime;
|
||||
var startTime = System.currentTimeMillis();
|
||||
var result = RemoteService.getRemoteService().doRemoteFunction(value);
|
||||
var timeTaken = System.currentTimeMillis() - startTime;
|
||||
|
||||
LOGGER.info("Time taken (ms): " + timeTaken);
|
||||
return result;
|
||||
}
|
||||
|
||||
private long safeCall(int value) {
|
||||
|
||||
int retries = 0;
|
||||
long result = FAILURE;
|
||||
var retries = 0;
|
||||
var result = (long) FAILURE;
|
||||
|
||||
for (int i = 0; i < RETRIES; i++) {
|
||||
|
||||
if (retries >= RETRIES) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* Application test
|
||||
*/
|
||||
public class AppTest {
|
||||
class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
void test() {
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
/**
|
||||
* Test for {@link Client}
|
||||
*/
|
||||
public class ClientTest {
|
||||
class ClientTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
void test() {
|
||||
Client client = new Client();
|
||||
long result = client.useService(10);
|
||||
var result = client.useService(10);
|
||||
|
||||
assertTrue(result == 100 || result == RemoteService.FAILURE);
|
||||
}
|
||||
|
@ -23,34 +23,31 @@
|
||||
|
||||
package com.iluwatar.ambassador;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.iluwatar.ambassador.util.RandomProvider;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test for {@link RemoteService}
|
||||
*/
|
||||
public class RemoteServiceTest {
|
||||
class RemoteServiceTest {
|
||||
|
||||
@Test
|
||||
public void testFailedCall() {
|
||||
RemoteService remoteService = new RemoteService(
|
||||
new StaticRandomProvider(0.21));
|
||||
long result = remoteService.doRemoteFunction(10);
|
||||
void testFailedCall() {
|
||||
var remoteService = new RemoteService(new StaticRandomProvider(0.21));
|
||||
var result = remoteService.doRemoteFunction(10);
|
||||
assertEquals(RemoteServiceInterface.FAILURE, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulCall() {
|
||||
RemoteService remoteService = new RemoteService(
|
||||
new StaticRandomProvider(0.2));
|
||||
long result = remoteService.doRemoteFunction(10);
|
||||
void testSuccessfulCall() {
|
||||
var remoteService = new RemoteService(new StaticRandomProvider(0.2));
|
||||
var result = remoteService.doRemoteFunction(10);
|
||||
assertEquals(100, result);
|
||||
}
|
||||
|
||||
private class StaticRandomProvider implements RandomProvider {
|
||||
private static class StaticRandomProvider implements RandomProvider {
|
||||
private double value;
|
||||
|
||||
StaticRandomProvider(double value) {
|
||||
|
@ -30,10 +30,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
/**
|
||||
* Test for {@link ServiceAmbassador}
|
||||
*/
|
||||
public class ServiceAmbassadorTest {
|
||||
class ServiceAmbassadorTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
void test() {
|
||||
long result = new ServiceAmbassador().doRemoteFunction(10);
|
||||
assertTrue(result == 100 || result == RemoteServiceInterface.FAILURE);
|
||||
}
|
||||
|
@ -64,15 +64,14 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
// construct a new executor that will run async tasks
|
||||
AsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
var executor = new ThreadAsyncExecutor();
|
||||
|
||||
// start few async tasks with varying processing times, two last with callback handlers
|
||||
final AsyncResult<Integer> asyncResult1 = executor.startProcess(lazyval(10, 500));
|
||||
final AsyncResult<String> asyncResult2 = executor.startProcess(lazyval("test", 300));
|
||||
final AsyncResult<Long> asyncResult3 = executor.startProcess(lazyval(50L, 700));
|
||||
final AsyncResult<Integer> asyncResult4 =
|
||||
executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
|
||||
final AsyncResult<String> asyncResult5 =
|
||||
final var asyncResult1 = executor.startProcess(lazyval(10, 500));
|
||||
final var asyncResult2 = executor.startProcess(lazyval("test", 300));
|
||||
final var asyncResult3 = executor.startProcess(lazyval(50L, 700));
|
||||
final var asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
|
||||
final var asyncResult5 =
|
||||
executor.startProcess(lazyval("callback", 600), callback("Callback result 5"));
|
||||
|
||||
// emulate processing in the current thread while async tasks are running in their own threads
|
||||
@ -80,9 +79,9 @@ public class App {
|
||||
log("Some hard work done");
|
||||
|
||||
// wait for completion of the tasks
|
||||
final Integer result1 = executor.endProcess(asyncResult1);
|
||||
final String result2 = executor.endProcess(asyncResult2);
|
||||
final Long result3 = executor.endProcess(asyncResult3);
|
||||
final var result1 = executor.endProcess(asyncResult1);
|
||||
final var result2 = executor.endProcess(asyncResult2);
|
||||
final var result3 = executor.endProcess(asyncResult3);
|
||||
asyncResult4.await();
|
||||
asyncResult5.await();
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
|
||||
|
||||
@Override
|
||||
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
|
||||
CompletableResult<T> result = new CompletableResult<>(callback);
|
||||
var result = new CompletableResult<>(callback);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
result.setValue(task.call());
|
||||
|
@ -28,11 +28,9 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* Application test
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
class AppTest {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
void test() throws Exception {
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -24,39 +24,66 @@
|
||||
package com.iluwatar.async.method.invocation;
|
||||
|
||||
import static java.time.Duration.ofMillis;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTimeout;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.internal.verification.VerificationModeFactory.times;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Date: 12/6/15 - 10:49 AM
|
||||
*
|
||||
* @author Jeroen Meulemeester
|
||||
*/
|
||||
public class ThreadAsyncExecutorTest {
|
||||
class ThreadAsyncExecutorTest {
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Optional<Exception>> optionalCaptor;
|
||||
|
||||
@Mock
|
||||
private Callable<Object> task;
|
||||
|
||||
@Mock
|
||||
private AsyncCallback<Object> callback;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)}
|
||||
*/
|
||||
@Test
|
||||
public void testSuccessfulTaskWithoutCallback() throws Exception {
|
||||
void testSuccessfulTaskWithoutCallback() throws Exception {
|
||||
assertTimeout(ofMillis(3000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
|
||||
final Object result = new Object();
|
||||
final Callable<Object> task = mock(Callable.class);
|
||||
final var result = new Object();
|
||||
when(task.call()).thenReturn(result);
|
||||
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(task);
|
||||
final var asyncResult = executor.startProcess(task);
|
||||
assertNotNull(asyncResult);
|
||||
asyncResult.await(); // Prevent timing issues, and wait until the result is available
|
||||
assertTrue(asyncResult.isCompleted());
|
||||
@ -74,17 +101,15 @@ public class ThreadAsyncExecutorTest {
|
||||
* AsyncCallback)}
|
||||
*/
|
||||
@Test
|
||||
public void testSuccessfulTaskWithCallback() throws Exception {
|
||||
void testSuccessfulTaskWithCallback() throws Exception {
|
||||
assertTimeout(ofMillis(3000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
|
||||
final Object result = new Object();
|
||||
final Callable<Object> task = mock(Callable.class);
|
||||
final var result = new Object();
|
||||
when(task.call()).thenReturn(result);
|
||||
|
||||
final AsyncCallback callback = mock(AsyncCallback.class);
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(task, callback);
|
||||
final var asyncResult = executor.startProcess(task, callback);
|
||||
assertNotNull(asyncResult);
|
||||
asyncResult.await(); // Prevent timing issues, and wait until the result is available
|
||||
assertTrue(asyncResult.isCompleted());
|
||||
@ -93,11 +118,9 @@ public class ThreadAsyncExecutorTest {
|
||||
verify(task, times(1)).call();
|
||||
|
||||
// ... same for the callback, we expect our object
|
||||
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
|
||||
ArgumentCaptor.forClass((Class) Optional.class);
|
||||
verify(callback, times(1)).onComplete(eq(result), optionalCaptor.capture());
|
||||
|
||||
final Optional<Exception> optionalException = optionalCaptor.getValue();
|
||||
final var optionalException = optionalCaptor.getValue();
|
||||
assertNotNull(optionalException);
|
||||
assertFalse(optionalException.isPresent());
|
||||
|
||||
@ -111,19 +134,18 @@ public class ThreadAsyncExecutorTest {
|
||||
* task takes a while to execute
|
||||
*/
|
||||
@Test
|
||||
public void testLongRunningTaskWithoutCallback() throws Exception {
|
||||
void testLongRunningTaskWithoutCallback() throws Exception {
|
||||
assertTimeout(ofMillis(5000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
|
||||
final Object result = new Object();
|
||||
final Callable<Object> task = mock(Callable.class);
|
||||
final var result = new Object();
|
||||
when(task.call()).thenAnswer(i -> {
|
||||
Thread.sleep(1500);
|
||||
return result;
|
||||
});
|
||||
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(task);
|
||||
final var asyncResult = executor.startProcess(task);
|
||||
assertNotNull(asyncResult);
|
||||
assertFalse(asyncResult.isCompleted());
|
||||
|
||||
@ -152,20 +174,18 @@ public class ThreadAsyncExecutorTest {
|
||||
* AsyncCallback)} when a task takes a while to execute
|
||||
*/
|
||||
@Test
|
||||
public void testLongRunningTaskWithCallback() throws Exception {
|
||||
void testLongRunningTaskWithCallback() throws Exception {
|
||||
assertTimeout(ofMillis(5000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
|
||||
final Object result = new Object();
|
||||
final Callable<Object> task = mock(Callable.class);
|
||||
final var result = new Object();
|
||||
when(task.call()).thenAnswer(i -> {
|
||||
Thread.sleep(1500);
|
||||
return result;
|
||||
});
|
||||
|
||||
final AsyncCallback<Object> callback = mock(AsyncCallback.class);
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(task, callback);
|
||||
final var asyncResult = executor.startProcess(task, callback);
|
||||
assertNotNull(asyncResult);
|
||||
assertFalse(asyncResult.isCompleted());
|
||||
|
||||
@ -180,12 +200,9 @@ public class ThreadAsyncExecutorTest {
|
||||
|
||||
// Our task should only execute once, but it can take a while ...
|
||||
verify(task, timeout(3000).times(1)).call();
|
||||
|
||||
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
|
||||
ArgumentCaptor.forClass((Class) Optional.class);
|
||||
verify(callback, timeout(3000).times(1)).onComplete(eq(result), optionalCaptor.capture());
|
||||
|
||||
final Optional<Exception> optionalException = optionalCaptor.getValue();
|
||||
final var optionalException = optionalCaptor.getValue();
|
||||
assertNotNull(optionalException);
|
||||
assertFalse(optionalException.isPresent());
|
||||
|
||||
@ -205,19 +222,18 @@ public class ThreadAsyncExecutorTest {
|
||||
* ThreadAsyncExecutor#endProcess(AsyncResult)}
|
||||
*/
|
||||
@Test
|
||||
public void testEndProcess() throws Exception {
|
||||
void testEndProcess() throws Exception {
|
||||
assertTimeout(ofMillis(5000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
|
||||
final Object result = new Object();
|
||||
final Callable<Object> task = mock(Callable.class);
|
||||
final var result = new Object();
|
||||
when(task.call()).thenAnswer(i -> {
|
||||
Thread.sleep(1500);
|
||||
return result;
|
||||
});
|
||||
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(task);
|
||||
final var asyncResult = executor.startProcess(task);
|
||||
assertNotNull(asyncResult);
|
||||
assertFalse(asyncResult.isCompleted());
|
||||
|
||||
@ -243,11 +259,11 @@ public class ThreadAsyncExecutorTest {
|
||||
* the callable is 'null'
|
||||
*/
|
||||
@Test
|
||||
public void testNullTask() throws Exception {
|
||||
void testNullTask() throws Exception {
|
||||
assertTimeout(ofMillis(3000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(null);
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
final var asyncResult = executor.startProcess(null);
|
||||
|
||||
assertNotNull(asyncResult, "The AsyncResult should not be 'null', even though the task was 'null'.");
|
||||
asyncResult.await(); // Prevent timing issues, and wait until the result is available
|
||||
@ -270,26 +286,22 @@ public class ThreadAsyncExecutorTest {
|
||||
* AsyncCallback)} when the callable is 'null', but the asynchronous callback is provided
|
||||
*/
|
||||
@Test
|
||||
public void testNullTaskWithCallback() throws Exception {
|
||||
void testNullTaskWithCallback() throws Exception {
|
||||
assertTimeout(ofMillis(3000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final AsyncCallback<Object> callback = mock(AsyncCallback.class);
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(null, callback);
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
final var asyncResult = executor.startProcess(null, callback);
|
||||
|
||||
assertNotNull(asyncResult, "The AsyncResult should not be 'null', even though the task was 'null'.");
|
||||
asyncResult.await(); // Prevent timing issues, and wait until the result is available
|
||||
assertTrue(asyncResult.isCompleted());
|
||||
|
||||
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
|
||||
ArgumentCaptor.forClass((Class) Optional.class);
|
||||
verify(callback, times(1)).onComplete(Matchers.isNull(), optionalCaptor.capture());
|
||||
|
||||
final Optional<Exception> optionalException = optionalCaptor.getValue();
|
||||
final var optionalException = optionalCaptor.getValue();
|
||||
assertNotNull(optionalException);
|
||||
assertTrue(optionalException.isPresent());
|
||||
|
||||
final Exception exception = optionalException.get();
|
||||
final var exception = optionalException.get();
|
||||
assertNotNull(exception);
|
||||
assertEquals(NullPointerException.class, exception.getClass());
|
||||
|
||||
@ -310,11 +322,11 @@ public class ThreadAsyncExecutorTest {
|
||||
* AsyncCallback)} when both the callable and the asynchronous callback are 'null'
|
||||
*/
|
||||
@Test
|
||||
public void testNullTaskWithNullCallback() throws Exception {
|
||||
void testNullTaskWithNullCallback() throws Exception {
|
||||
assertTimeout(ofMillis(3000), () -> {
|
||||
// Instantiate a new executor and start a new 'null' task ...
|
||||
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
|
||||
final AsyncResult<Object> asyncResult = executor.startProcess(null, null);
|
||||
final var executor = new ThreadAsyncExecutor();
|
||||
final var asyncResult = executor.startProcess(null, null);
|
||||
|
||||
assertNotNull(
|
||||
asyncResult,
|
||||
|
@ -51,8 +51,8 @@ public class App {
|
||||
* @param args the command line arguments - not used
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
final WashingMachine washingMachine = new WashingMachine();
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||
final var washingMachine = new WashingMachine();
|
||||
var executorService = Executors.newFixedThreadPool(3);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
executorService.execute(washingMachine::wash);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class WashingMachine {
|
||||
*/
|
||||
public void wash() {
|
||||
synchronized (this) {
|
||||
WashingMachineState machineState = getWashingMachineState();
|
||||
var machineState = getWashingMachineState();
|
||||
LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), machineState);
|
||||
if (this.washingMachineState == WashingMachineState.WASHING) {
|
||||
LOGGER.error("ERROR: Cannot wash if the machine has been already washing!");
|
||||
|
@ -28,12 +28,11 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* Application test
|
||||
*/
|
||||
public class AppTest {
|
||||
class AppTest {
|
||||
|
||||
@Test
|
||||
public void main() throws Exception {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
void main() {
|
||||
App.main();
|
||||
}
|
||||
|
||||
}
|
@ -31,18 +31,18 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* Tests for {@link WashingMachine}
|
||||
*/
|
||||
public class WashingMachineTest {
|
||||
class WashingMachineTest {
|
||||
|
||||
private FakeDelayProvider fakeDelayProvider = new FakeDelayProvider();
|
||||
private final FakeDelayProvider fakeDelayProvider = new FakeDelayProvider();
|
||||
|
||||
@Test
|
||||
public void wash() {
|
||||
WashingMachine washingMachine = new WashingMachine(fakeDelayProvider);
|
||||
void wash() {
|
||||
var washingMachine = new WashingMachine(fakeDelayProvider);
|
||||
|
||||
washingMachine.wash();
|
||||
washingMachine.wash();
|
||||
|
||||
WashingMachineState machineStateGlobal = washingMachine.getWashingMachineState();
|
||||
var machineStateGlobal = washingMachine.getWashingMachineState();
|
||||
|
||||
fakeDelayProvider.task.run();
|
||||
|
||||
@ -54,13 +54,13 @@ public class WashingMachineTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endOfWashing() {
|
||||
WashingMachine washingMachine = new WashingMachine();
|
||||
void endOfWashing() {
|
||||
var washingMachine = new WashingMachine();
|
||||
washingMachine.wash();
|
||||
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
|
||||
}
|
||||
|
||||
private class FakeDelayProvider implements DelayProvider {
|
||||
private static class FakeDelayProvider implements DelayProvider {
|
||||
private Runnable task;
|
||||
|
||||
@Override
|
||||
|
@ -50,13 +50,13 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
LOGGER.info("The knight receives an enchanted sword.");
|
||||
Sword enchantedSword = new Sword(new SoulEatingEnchantment());
|
||||
var enchantedSword = new Sword(new SoulEatingEnchantment());
|
||||
enchantedSword.wield();
|
||||
enchantedSword.swing();
|
||||
enchantedSword.unwield();
|
||||
|
||||
LOGGER.info("The valkyrie receives an enchanted hammer.");
|
||||
Hammer hammer = new Hammer(new FlyingEnchantment());
|
||||
var hammer = new Hammer(new FlyingEnchantment());
|
||||
hammer.wield();
|
||||
hammer.swing();
|
||||
hammer.unwield();
|
||||
|
@ -26,15 +26,11 @@ package com.iluwatar.bridge;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
class AppTest {
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
void test() {
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,23 @@
|
||||
|
||||
package com.iluwatar.bridge;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for hammer
|
||||
*/
|
||||
public class HammerTest extends WeaponTest {
|
||||
class HammerTest extends WeaponTest {
|
||||
|
||||
/**
|
||||
* Invoke all possible actions on the weapon and check if the actions are executed on the actual
|
||||
* underlying weapon implementation.
|
||||
*/
|
||||
@Test
|
||||
public void testHammer() {
|
||||
final Hammer hammer = spy(new Hammer(mock(FlyingEnchantment.class)));
|
||||
void testHammer() {
|
||||
final var hammer = spy(new Hammer(mock(FlyingEnchantment.class)));
|
||||
testBasicWeaponActions(hammer);
|
||||
}
|
||||
}
|
@ -23,23 +23,23 @@
|
||||
|
||||
package com.iluwatar.bridge;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for sword
|
||||
*/
|
||||
public class SwordTest extends WeaponTest {
|
||||
class SwordTest extends WeaponTest {
|
||||
|
||||
/**
|
||||
* Invoke all possible actions on the weapon and check if the actions are executed on the actual
|
||||
* underlying weapon implementation.
|
||||
*/
|
||||
@Test
|
||||
public void testSword() {
|
||||
final Sword sword = spy(new Sword(mock(FlyingEnchantment.class)));
|
||||
void testSword() {
|
||||
final var sword = spy(new Sword(mock(FlyingEnchantment.class)));
|
||||
testBasicWeaponActions(sword);
|
||||
}
|
||||
}
|
@ -23,8 +23,6 @@
|
||||
|
||||
package com.iluwatar.bridge;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
@ -32,16 +30,15 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
/**
|
||||
* Base class for weapon tests
|
||||
*/
|
||||
public abstract class WeaponTest {
|
||||
abstract class WeaponTest {
|
||||
|
||||
/**
|
||||
* Invoke the basic actions of the given weapon, and test if the underlying enchantment implementation
|
||||
* is invoked
|
||||
*
|
||||
* Invoke the basic actions of the given weapon, and test if the underlying enchantment
|
||||
* implementation is invoked
|
||||
*/
|
||||
protected final void testBasicWeaponActions(final Weapon weapon) {
|
||||
final void testBasicWeaponActions(final Weapon weapon) {
|
||||
assertNotNull(weapon);
|
||||
Enchantment enchantment = weapon.getEnchantment();
|
||||
var enchantment = weapon.getEnchantment();
|
||||
assertNotNull(enchantment);
|
||||
assertNotNull(weapon.getEnchantment());
|
||||
|
||||
|
@ -59,20 +59,22 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
Hero mage =
|
||||
new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK)
|
||||
.withWeapon(Weapon.DAGGER).build();
|
||||
var mage = new Hero.Builder(Profession.MAGE, "Riobard")
|
||||
.withHairColor(HairColor.BLACK)
|
||||
.withWeapon(Weapon.DAGGER)
|
||||
.build();
|
||||
LOGGER.info(mage.toString());
|
||||
|
||||
Hero warrior =
|
||||
new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
|
||||
.withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
|
||||
.build();
|
||||
var warrior = new Hero.Builder(Profession.WARRIOR, "Amberjill")
|
||||
.withHairColor(HairColor.BLOND)
|
||||
.withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
|
||||
.build();
|
||||
LOGGER.info(warrior.toString());
|
||||
|
||||
Hero thief =
|
||||
new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD)
|
||||
.withWeapon(Weapon.BOW).build();
|
||||
var thief = new Hero.Builder(Profession.THIEF, "Desmond")
|
||||
.withHairType(HairType.BALD)
|
||||
.withWeapon(Weapon.BOW)
|
||||
.build();
|
||||
LOGGER.info(thief.toString());
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public enum Armor {
|
||||
|
||||
CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
|
||||
|
||||
private String title;
|
||||
private final String title;
|
||||
|
||||
Armor(String title) {
|
||||
this.title = title;
|
||||
|
@ -31,7 +31,7 @@ public enum HairType {
|
||||
BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY(
|
||||
"long curly");
|
||||
|
||||
private String title;
|
||||
private final String title;
|
||||
|
||||
HairType(String title) {
|
||||
this.title = title;
|
||||
|
@ -71,7 +71,7 @@ public final class Hero {
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
sb.append("This is a ")
|
||||
.append(profession)
|
||||
.append(" named ")
|
||||
|
@ -26,15 +26,11 @@ package com.iluwatar.builder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
class AppTest {
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
void test() {
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,24 +23,24 @@
|
||||
|
||||
package com.iluwatar.builder;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/6/15 - 11:01 PM
|
||||
*
|
||||
* @author Jeroen Meulemeester
|
||||
*/
|
||||
public class HeroTest {
|
||||
class HeroTest {
|
||||
|
||||
/**
|
||||
* Test if we get the expected exception when trying to create a hero without a profession
|
||||
*/
|
||||
@Test
|
||||
public void testMissingProfession() throws Exception {
|
||||
void testMissingProfession() {
|
||||
assertThrows(IllegalArgumentException.class, () -> new Hero.Builder(null, "Sir without a job"));
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class HeroTest {
|
||||
* Test if we get the expected exception when trying to create a hero without a name
|
||||
*/
|
||||
@Test
|
||||
public void testMissingName() throws Exception {
|
||||
void testMissingName() {
|
||||
assertThrows(IllegalArgumentException.class, () -> new Hero.Builder(Profession.THIEF, null));
|
||||
}
|
||||
|
||||
@ -56,10 +56,10 @@ public class HeroTest {
|
||||
* Test if the hero build by the builder has the correct attributes, as requested
|
||||
*/
|
||||
@Test
|
||||
public void testBuildHero() throws Exception {
|
||||
void testBuildHero() {
|
||||
final String heroName = "Sir Lancelot";
|
||||
|
||||
final Hero hero = new Hero.Builder(Profession.WARRIOR, heroName)
|
||||
final var hero = new Hero.Builder(Profession.WARRIOR, heroName)
|
||||
.withArmor(Armor.CHAIN_MAIL)
|
||||
.withWeapon(Weapon.SWORD)
|
||||
.withHairType(HairType.LONG_CURLY)
|
||||
|
Loading…
x
Reference in New Issue
Block a user