Java 11 migrate remaining p (#1122)
* Moves partial-response to Java 11 * Moves pipeline to Java 11 * Moves poison-pill to Java 11 * Moves priority-queue to Java 11 * Moves private-class-data to Java 11 * Moves producer-consumer to Java 11 * Moves promise to Java 11 * Moves property to Java 11 * Moves prototype to Java 11 * Moves proxy to Java 11 * Corrects checkstyle errors * Fixes build for pipeline pattern
This commit is contained in:
parent
1401accb4f
commit
428efc7d53
@ -24,6 +24,11 @@
|
||||
package com.iluwatar.masterworker;
|
||||
|
||||
import com.iluwatar.masterworker.system.ArrayTransposeMasterWorker;
|
||||
import com.iluwatar.masterworker.system.MasterWorker;
|
||||
import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
|
||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
|
||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -26,6 +26,23 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
|
@ -71,8 +71,8 @@ public final class App {
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
File applicationFile =
|
||||
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
var classLoader = App.class.getClassLoader();
|
||||
var applicationFile = new File(classLoader.getResource("sample-ui/login.html").getPath());
|
||||
|
||||
// should work for unix like OS (mac, unix etc...)
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
|
@ -67,8 +67,8 @@ public final class App {
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
File applicationFile =
|
||||
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
var classLoader = App.class.getClassLoader();
|
||||
var applicationFile = new File(classLoader.getResource("sample-ui/login.html").getPath());
|
||||
|
||||
// Should work for unix like OS (mac, unix etc...)
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
|
@ -23,14 +23,14 @@
|
||||
|
||||
package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.iluwatar.pageobject.pages.AlbumListPage;
|
||||
import com.iluwatar.pageobject.pages.AlbumPage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Album Selection and Album Listing
|
||||
*/
|
||||
@ -45,7 +45,7 @@ public class AlbumListPageTest {
|
||||
|
||||
@Test
|
||||
public void testSelectAlbum() {
|
||||
AlbumPage albumPage = albumListPage.selectAlbum("21");
|
||||
var albumPage = albumListPage.selectAlbum("21");
|
||||
albumPage.navigateToPage();
|
||||
assertTrue(albumPage.isAt());
|
||||
}
|
||||
|
@ -23,14 +23,14 @@
|
||||
|
||||
package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.iluwatar.pageobject.pages.AlbumListPage;
|
||||
import com.iluwatar.pageobject.pages.AlbumPage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Album Page Operations
|
||||
*/
|
||||
@ -46,7 +46,7 @@ public class AlbumPageTest {
|
||||
@Test
|
||||
public void testSaveAlbum() {
|
||||
|
||||
AlbumPage albumPageAfterChanges = albumPage
|
||||
var albumPageAfterChanges = albumPage
|
||||
.changeAlbumTitle("25")
|
||||
.changeArtist("Adele Laurie Blue Adkins")
|
||||
.changeAlbumYear(2015)
|
||||
@ -60,7 +60,7 @@ public class AlbumPageTest {
|
||||
|
||||
@Test
|
||||
public void testCancelChanges() {
|
||||
AlbumListPage albumListPage = albumPage.cancelChanges();
|
||||
var albumListPage = albumPage.cancelChanges();
|
||||
albumListPage.navigateToPage();
|
||||
assertTrue(albumListPage.isAt());
|
||||
}
|
||||
|
@ -23,14 +23,14 @@
|
||||
|
||||
package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.iluwatar.pageobject.pages.AlbumListPage;
|
||||
import com.iluwatar.pageobject.pages.LoginPage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Login Page Object
|
||||
*/
|
||||
@ -45,7 +45,7 @@ public class LoginPageTest {
|
||||
|
||||
@Test
|
||||
public void testLogin() {
|
||||
AlbumListPage albumListPage = loginPage
|
||||
var albumListPage = loginPage
|
||||
.enterUsername("admin")
|
||||
.enterPassword("password")
|
||||
.login();
|
||||
|
@ -26,7 +26,6 @@ package com.iluwatar.pageobject.pages;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@ -79,8 +78,8 @@ public class AlbumListPage extends Page {
|
||||
*/
|
||||
public AlbumPage selectAlbum(String albumTitle) {
|
||||
// uses XPath to find list of html anchor tags with the class album in it
|
||||
List<HtmlAnchor> albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
|
||||
for (HtmlAnchor anchor : albumLinks) {
|
||||
var albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
|
||||
for (var anchor : albumLinks) {
|
||||
if (anchor.getTextContent().equals(albumTitle)) {
|
||||
try {
|
||||
anchor.click();
|
||||
|
@ -30,7 +30,6 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -83,7 +82,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumTitle(String albumTitle) {
|
||||
HtmlTextInput albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
|
||||
var albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
|
||||
albumTitleInputTextField.setText(albumTitle);
|
||||
return this;
|
||||
}
|
||||
@ -96,7 +95,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeArtist(String artist) {
|
||||
HtmlTextInput artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
|
||||
var artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
|
||||
artistInputTextField.setText(artist);
|
||||
return this;
|
||||
}
|
||||
@ -109,8 +108,8 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumYear(int year) {
|
||||
HtmlSelect albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
|
||||
HtmlOption yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
|
||||
var albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
|
||||
var yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
|
||||
albumYearSelectOption.setSelectedAttribute(yearOption, true);
|
||||
return this;
|
||||
}
|
||||
@ -123,7 +122,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumRating(String albumRating) {
|
||||
HtmlTextInput albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
|
||||
var albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
|
||||
albumRatingInputTextField.setText(albumRating);
|
||||
return this;
|
||||
}
|
||||
@ -135,7 +134,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
|
||||
HtmlNumberInput numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
var numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
|
||||
return this;
|
||||
}
|
||||
@ -147,7 +146,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumListPage}
|
||||
*/
|
||||
public AlbumListPage cancelChanges() {
|
||||
HtmlSubmitInput cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
|
||||
var cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
|
||||
try {
|
||||
cancelButton.click();
|
||||
} catch (IOException e) {
|
||||
@ -163,7 +162,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage saveChanges() {
|
||||
HtmlSubmitInput saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
|
||||
var saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
|
||||
try {
|
||||
saveButton.click();
|
||||
} catch (IOException e) {
|
||||
|
@ -79,7 +79,7 @@ public class LoginPage extends Page {
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
public LoginPage enterUsername(String username) {
|
||||
HtmlTextInput usernameInputTextField = (HtmlTextInput) page.getElementById("username");
|
||||
var usernameInputTextField = (HtmlTextInput) page.getElementById("username");
|
||||
usernameInputTextField.setText(username);
|
||||
return this;
|
||||
}
|
||||
@ -92,7 +92,7 @@ public class LoginPage extends Page {
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
public LoginPage enterPassword(String password) {
|
||||
HtmlPasswordInput passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
|
||||
var passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
|
||||
passwordInputPasswordField.setText(password);
|
||||
return this;
|
||||
}
|
||||
@ -101,11 +101,11 @@ public class LoginPage extends Page {
|
||||
/**
|
||||
* Clicking on the login button to 'login'
|
||||
*
|
||||
* @return {@link AlbumListPage}
|
||||
* - this is the page that user gets navigated to once successfully logged in
|
||||
* @return {@link AlbumListPage} - this is the page that user gets navigated to once successfully
|
||||
* logged in
|
||||
*/
|
||||
public AlbumListPage login() {
|
||||
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
|
||||
var loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
|
||||
try {
|
||||
loginButton.click();
|
||||
} catch (IOException e) {
|
||||
|
@ -31,8 +31,7 @@ import com.gargoylesoftware.htmlunit.WebClient;
|
||||
public abstract class Page {
|
||||
|
||||
/**
|
||||
* Application Under Test path
|
||||
* This directory location is where html web pages are located
|
||||
* Application Under Test path This directory location is where html web pages are located
|
||||
*/
|
||||
public static final String AUT_PATH = "src/main/resources/sample-ui/";
|
||||
|
||||
|
@ -81,8 +81,8 @@ public class AlbumListPage extends Page {
|
||||
*/
|
||||
public AlbumPage selectAlbum(String albumTitle) {
|
||||
// uses XPath to find list of html anchor tags with the class album in it
|
||||
List<HtmlAnchor> albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
|
||||
for (HtmlAnchor anchor : albumLinks) {
|
||||
var albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
|
||||
for (var anchor : albumLinks) {
|
||||
if (anchor.getTextContent().equals(albumTitle)) {
|
||||
try {
|
||||
anchor.click();
|
||||
|
@ -25,7 +25,6 @@ package com.iluwatar.pageobject;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlNumberInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlOption;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
@ -85,7 +84,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumTitle(String albumTitle) {
|
||||
HtmlTextInput albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
|
||||
var albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
|
||||
albumTitleInputTextField.setText(albumTitle);
|
||||
return this;
|
||||
}
|
||||
@ -98,7 +97,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeArtist(String artist) {
|
||||
HtmlTextInput artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
|
||||
var artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
|
||||
artistInputTextField.setText(artist);
|
||||
return this;
|
||||
}
|
||||
@ -111,8 +110,8 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumYear(int year) {
|
||||
HtmlSelect albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
|
||||
HtmlOption yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
|
||||
var albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
|
||||
var yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
|
||||
albumYearSelectOption.setSelectedAttribute(yearOption, true);
|
||||
return this;
|
||||
}
|
||||
@ -125,7 +124,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeAlbumRating(String albumRating) {
|
||||
HtmlTextInput albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
|
||||
var albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
|
||||
albumRatingInputTextField.setText(albumRating);
|
||||
return this;
|
||||
}
|
||||
@ -137,8 +136,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
|
||||
HtmlNumberInput numberOfSongsNumberField =
|
||||
(HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
var numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
|
||||
return this;
|
||||
}
|
||||
@ -150,7 +148,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumListPage}
|
||||
*/
|
||||
public AlbumListPage cancelChanges() {
|
||||
HtmlSubmitInput cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
|
||||
var cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
|
||||
try {
|
||||
cancelButton.click();
|
||||
} catch (IOException e) {
|
||||
@ -166,7 +164,7 @@ public class AlbumPage extends Page {
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage saveChanges() {
|
||||
HtmlSubmitInput saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
|
||||
var saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
|
||||
try {
|
||||
saveButton.click();
|
||||
} catch (IOException e) {
|
||||
|
@ -82,7 +82,7 @@ public class LoginPage extends Page {
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
public LoginPage enterUsername(String username) {
|
||||
HtmlTextInput usernameInputTextField = (HtmlTextInput) page.getElementById("username");
|
||||
var usernameInputTextField = (HtmlTextInput) page.getElementById("username");
|
||||
usernameInputTextField.setText(username);
|
||||
return this;
|
||||
}
|
||||
@ -95,8 +95,7 @@ public class LoginPage extends Page {
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
public LoginPage enterPassword(String password) {
|
||||
HtmlPasswordInput passwordInputPasswordField =
|
||||
(HtmlPasswordInput) page.getElementById("password");
|
||||
var passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
|
||||
passwordInputPasswordField.setText(password);
|
||||
return this;
|
||||
}
|
||||
@ -109,7 +108,7 @@ public class LoginPage extends Page {
|
||||
* logged in
|
||||
*/
|
||||
public AlbumListPage login() {
|
||||
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
|
||||
var loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
|
||||
try {
|
||||
loginButton.click();
|
||||
} catch (IOException e) {
|
||||
|
@ -23,14 +23,12 @@
|
||||
|
||||
package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.iluwatar.pageobject.AlbumListPage;
|
||||
import com.iluwatar.pageobject.AlbumPage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Album Selection and Album Listing
|
||||
*/
|
||||
@ -45,7 +43,7 @@ public class AlbumListPageTest {
|
||||
|
||||
@Test
|
||||
public void testSelectAlbum() {
|
||||
AlbumPage albumPage = albumListPage.selectAlbum("21");
|
||||
var albumPage = albumListPage.selectAlbum("21");
|
||||
albumPage.navigateToPage();
|
||||
assertTrue(albumPage.isAt());
|
||||
}
|
||||
|
@ -25,11 +25,10 @@ package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
|
||||
/**
|
||||
* Test Album Page Operations
|
||||
*/
|
||||
@ -45,7 +44,7 @@ public class AlbumPageTest {
|
||||
@Test
|
||||
public void testSaveAlbum() {
|
||||
|
||||
AlbumPage albumPageAfterChanges = albumPage
|
||||
var albumPageAfterChanges = albumPage
|
||||
.changeAlbumTitle("25")
|
||||
.changeArtist("Adele Laurie Blue Adkins")
|
||||
.changeAlbumYear(2015)
|
||||
@ -59,7 +58,7 @@ public class AlbumPageTest {
|
||||
|
||||
@Test
|
||||
public void testCancelChanges() {
|
||||
AlbumListPage albumListPage = albumPage.cancelChanges();
|
||||
var albumListPage = albumPage.cancelChanges();
|
||||
albumListPage.navigateToPage();
|
||||
assertTrue(albumListPage.isAt());
|
||||
}
|
||||
|
@ -25,11 +25,10 @@ package com.iluwatar.pageobject;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
|
||||
/**
|
||||
* Test Login Page Object
|
||||
*/
|
||||
@ -44,7 +43,7 @@ public class LoginPageTest {
|
||||
|
||||
@Test
|
||||
public void testLogin() {
|
||||
AlbumListPage albumListPage = loginPage
|
||||
var albumListPage = loginPage
|
||||
.enterUsername("admin")
|
||||
.enterPassword("password")
|
||||
.login();
|
||||
|
@ -44,30 +44,31 @@ public class App {
|
||||
* @param args program argument.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map<Integer, Video> videos = Map.of(
|
||||
var videos = Map.of(
|
||||
1, new Video(1, "Avatar", 178, "epic science fiction film",
|
||||
"James Cameron", "English"),
|
||||
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
|
||||
"Hideaki Anno", "Japanese"),
|
||||
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
|
||||
"Christopher Nolan", "English"));
|
||||
VideoResource videoResource = new VideoResource(new FieldJsonMapper(), videos);
|
||||
"Christopher Nolan", "English")
|
||||
);
|
||||
var videoResource = new VideoResource(new FieldJsonMapper(), videos);
|
||||
|
||||
|
||||
LOGGER.info("Retrieving full response from server:-");
|
||||
LOGGER.info("Get all video information:");
|
||||
String videoDetails = videoResource.getDetails(1);
|
||||
var videoDetails = videoResource.getDetails(1);
|
||||
LOGGER.info(videoDetails);
|
||||
|
||||
LOGGER.info("----------------------------------------------------------");
|
||||
|
||||
LOGGER.info("Retrieving partial response from server:-");
|
||||
LOGGER.info("Get video @id, @title, @director:");
|
||||
String specificFieldsDetails = videoResource.getDetails(3, "id", "title", "director");
|
||||
var specificFieldsDetails = videoResource.getDetails(3, "id", "title", "director");
|
||||
LOGGER.info(specificFieldsDetails);
|
||||
|
||||
LOGGER.info("Get video @id, @length:");
|
||||
String videoLength = videoResource.getDetails(3, "id", "length");
|
||||
var videoLength = videoResource.getDetails(3, "id", "length");
|
||||
LOGGER.info(videoLength);
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,16 @@ public class FieldJsonMapper {
|
||||
* @return json of required fields from video
|
||||
*/
|
||||
public String toJson(Video video, String[] fields) throws Exception {
|
||||
StringBuilder json = new StringBuilder().append("{");
|
||||
var json = new StringBuilder().append("{");
|
||||
|
||||
for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
|
||||
var i = 0;
|
||||
var fieldsLength = fields.length;
|
||||
while (i < fieldsLength) {
|
||||
json.append(getString(video, Video.class.getDeclaredField(fields[i])));
|
||||
if (i != fieldsLength - 1) {
|
||||
json.append(",");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
json.append("}");
|
||||
return json.toString();
|
||||
@ -52,7 +55,7 @@ public class FieldJsonMapper {
|
||||
|
||||
private String getString(Video video, Field declaredField) throws IllegalAccessException {
|
||||
declaredField.setAccessible(true);
|
||||
Object value = declaredField.get(video);
|
||||
var value = declaredField.get(video);
|
||||
if (declaredField.get(video) instanceof Integer) {
|
||||
return "\"" + declaredField.getName() + "\"" + ": " + value;
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ public class AppTest {
|
||||
|
||||
@Test
|
||||
public void main() throws Exception {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
|
||||
}
|
@ -23,11 +23,11 @@
|
||||
|
||||
package com.iluwatar.partialresponse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* tests {@link FieldJsonMapper}.
|
||||
*/
|
||||
@ -41,12 +41,15 @@ public class FieldJsonMapperTest {
|
||||
|
||||
@Test
|
||||
public void shouldReturnJsonForSpecifiedFieldsInVideo() throws Exception {
|
||||
String[] fields = new String[]{"id", "title", "length"};
|
||||
Video video = new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|", "Hideaki Anno", "Japanese");
|
||||
var fields = new String[]{"id", "title", "length"};
|
||||
var video = new Video(
|
||||
2, "Godzilla Resurgence", 120,
|
||||
"Action & drama movie|", "Hideaki Anno", "Japanese"
|
||||
);
|
||||
|
||||
String jsonFieldResponse = mapper.toJson(video, fields);
|
||||
var jsonFieldResponse = mapper.toJson(video, fields);
|
||||
|
||||
String expectedDetails = "{\"id\": 2,\"title\": \"Godzilla Resurgence\",\"length\": 120}";
|
||||
var expectedDetails = "{\"id\": 2,\"title\": \"Godzilla Resurgence\",\"length\": 120}";
|
||||
assertEquals(expectedDetails, jsonFieldResponse);
|
||||
}
|
||||
}
|
@ -23,19 +23,18 @@
|
||||
|
||||
package com.iluwatar.partialresponse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* tests {@link VideoResource}.
|
||||
*/
|
||||
@ -48,33 +47,33 @@ public class VideoResourceTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Map<Integer, Video> videos = Map.of(
|
||||
1, new Video(1, "Avatar", 178, "epic science fiction film",
|
||||
"James Cameron", "English"),
|
||||
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
|
||||
"Hideaki Anno", "Japanese"),
|
||||
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
|
||||
"Christopher Nolan", "English"));
|
||||
var videos = Map.of(
|
||||
1, new Video(1, "Avatar", 178, "epic science fiction film",
|
||||
"James Cameron", "English"),
|
||||
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
|
||||
"Hideaki Anno", "Japanese"),
|
||||
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
|
||||
"Christopher Nolan", "English"));
|
||||
resource = new VideoResource(fieldJsonMapper, videos);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGiveVideoDetailsById() throws Exception {
|
||||
String actualDetails = resource.getDetails(1);
|
||||
var actualDetails = resource.getDetails(1);
|
||||
|
||||
String expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178,\"description\": "
|
||||
var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178,\"description\": "
|
||||
+ "\"epic science fiction film\",\"director\": \"James Cameron\",\"language\": \"English\",}";
|
||||
assertEquals(expectedDetails, actualDetails);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGiveSpecifiedFieldsInformationOfVideo() throws Exception {
|
||||
String[] fields = new String[]{"id", "title", "length"};
|
||||
var fields = new String[]{"id", "title", "length"};
|
||||
|
||||
String expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}";
|
||||
var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}";
|
||||
when(fieldJsonMapper.toJson(any(Video.class), eq(fields))).thenReturn(expectedDetails);
|
||||
|
||||
String actualFieldsDetails = resource.getDetails(2, fields);
|
||||
var actualFieldsDetails = resource.getDetails(2, fields);
|
||||
|
||||
assertEquals(expectedDetails, actualFieldsDetails);
|
||||
}
|
||||
|
@ -36,11 +36,12 @@ class ConvertToCharArrayHandler implements Handler<String, char[]> {
|
||||
|
||||
@Override
|
||||
public char[] process(String input) {
|
||||
char[] characters = input.toCharArray();
|
||||
LOGGER
|
||||
.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
ConvertToCharArrayHandler.class, input, String.class, Arrays
|
||||
.toString(characters), Character[].class));
|
||||
var characters = input.toCharArray();
|
||||
var string = Arrays.toString(characters);
|
||||
LOGGER.info(
|
||||
String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
ConvertToCharArrayHandler.class, input, String.class, string, Character[].class)
|
||||
);
|
||||
|
||||
return characters;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
import java.util.function.IntPredicate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -36,18 +37,14 @@ class RemoveAlphabetsHandler implements Handler<String, String> {
|
||||
|
||||
@Override
|
||||
public String process(String input) {
|
||||
StringBuilder inputWithoutAlphabets = new StringBuilder();
|
||||
var inputWithoutAlphabets = new StringBuilder();
|
||||
var isAlphabetic = (IntPredicate) Character::isAlphabetic;
|
||||
input.chars()
|
||||
.filter(isAlphabetic.negate())
|
||||
.mapToObj(x -> (char) x)
|
||||
.forEachOrdered(inputWithoutAlphabets::append);
|
||||
|
||||
for (int index = 0; index < input.length(); index++) {
|
||||
char currentCharacter = input.charAt(index);
|
||||
if (Character.isAlphabetic(currentCharacter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inputWithoutAlphabets.append(currentCharacter);
|
||||
}
|
||||
|
||||
String inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
|
||||
var inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
|
||||
LOGGER.info(
|
||||
String.format(
|
||||
"Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
import java.util.function.IntPredicate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -36,21 +37,20 @@ class RemoveDigitsHandler implements Handler<String, String> {
|
||||
|
||||
@Override
|
||||
public String process(String input) {
|
||||
StringBuilder inputWithoutDigits = new StringBuilder();
|
||||
var inputWithoutDigits = new StringBuilder();
|
||||
var isDigit = (IntPredicate) Character::isDigit;
|
||||
input.chars()
|
||||
.filter(isDigit.negate())
|
||||
.mapToObj(x -> (char) x)
|
||||
.forEachOrdered(inputWithoutDigits::append);
|
||||
|
||||
for (int index = 0; index < input.length(); index++) {
|
||||
char currentCharacter = input.charAt(index);
|
||||
if (Character.isDigit(currentCharacter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inputWithoutDigits.append(currentCharacter);
|
||||
}
|
||||
|
||||
String inputWithoutDigitsStr = inputWithoutDigits.toString();
|
||||
LOGGER
|
||||
.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class));
|
||||
var inputWithoutDigitsStr = inputWithoutDigits.toString();
|
||||
LOGGER.info(
|
||||
String.format(
|
||||
"Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class
|
||||
)
|
||||
);
|
||||
|
||||
return inputWithoutDigitsStr;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,10 @@
|
||||
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test for {@link Pipeline}
|
||||
*/
|
||||
@ -34,12 +34,12 @@ public class PipelineTest {
|
||||
|
||||
@Test
|
||||
public void testAddHandlersToPipeline() {
|
||||
Pipeline<String, char[]> filters = new Pipeline<>(new RemoveAlphabetsHandler())
|
||||
var filters = new Pipeline<>(new RemoveAlphabetsHandler())
|
||||
.addHandler(new RemoveDigitsHandler())
|
||||
.addHandler(new ConvertToCharArrayHandler());
|
||||
|
||||
assertArrayEquals(
|
||||
new char[] {'#', '!', '(', '&', '%', '#', '!'},
|
||||
new char[]{'#', '!', '(', '&', '%', '#', '!'},
|
||||
filters.execute("#H!E(L&L0O%THE3R#34E!")
|
||||
);
|
||||
}
|
||||
|
@ -42,26 +42,18 @@ public class App {
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
MessageQueue queue = new SimpleMessageQueue(10000);
|
||||
var queue = new SimpleMessageQueue(10000);
|
||||
|
||||
final Producer producer = new Producer("PRODUCER_1", queue);
|
||||
final Consumer consumer = new Consumer("CONSUMER_1", queue);
|
||||
final var producer = new Producer("PRODUCER_1", queue);
|
||||
final var consumer = new Consumer("CONSUMER_1", queue);
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
consumer.consume();
|
||||
}
|
||||
}.start();
|
||||
new Thread(consumer::consume).start();
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
producer.send("hand shake");
|
||||
producer.send("some very important information");
|
||||
producer.send("bye!");
|
||||
producer.stop();
|
||||
}
|
||||
}.start();
|
||||
new Thread(() -> {
|
||||
producer.send("hand shake");
|
||||
producer.send("some very important information");
|
||||
producer.send("bye!");
|
||||
producer.stop();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
@ -47,22 +47,20 @@ public class Consumer {
|
||||
*/
|
||||
public void consume() {
|
||||
while (true) {
|
||||
Message msg;
|
||||
try {
|
||||
msg = queue.take();
|
||||
var msg = queue.take();
|
||||
if (Message.POISON_PILL.equals(msg)) {
|
||||
LOGGER.info("Consumer {} receive request to terminate.", name);
|
||||
break;
|
||||
}
|
||||
var sender = msg.getHeader(Headers.SENDER);
|
||||
var body = msg.getBody();
|
||||
LOGGER.info("Message [{}] from [{}] received by [{}]", body, sender, name);
|
||||
} catch (InterruptedException e) {
|
||||
// allow thread to exit
|
||||
LOGGER.error("Exception caught.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
String sender = msg.getHeader(Headers.SENDER);
|
||||
String body = msg.getBody();
|
||||
LOGGER.info("Message [{}] from [{}] received by [{}]", body, sender, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class Producer {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Producer %s was stopped and fail to deliver requested message [%s].", body, name));
|
||||
}
|
||||
Message msg = new SimpleMessage();
|
||||
var msg = new SimpleMessage();
|
||||
msg.addHeader(Headers.DATE, new Date().toString());
|
||||
msg.addHeader(Headers.SENDER, name);
|
||||
msg.setBody(body);
|
||||
|
@ -26,15 +26,12 @@ package com.iluwatar.poison.pill;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,20 +23,19 @@
|
||||
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 9:45 PM
|
||||
*
|
||||
@ -58,15 +57,15 @@ public class ConsumerTest {
|
||||
|
||||
@Test
|
||||
public void testConsume() throws Exception {
|
||||
final Message[] messages = new Message[]{
|
||||
final var messages = List.of(
|
||||
createMessage("you", "Hello!"),
|
||||
createMessage("me", "Hi!"),
|
||||
Message.POISON_PILL,
|
||||
createMessage("late_for_the_party", "Hello? Anyone here?"),
|
||||
};
|
||||
createMessage("late_for_the_party", "Hello? Anyone here?")
|
||||
);
|
||||
|
||||
final MessageQueue queue = new SimpleMessageQueue(messages.length);
|
||||
for (final Message message : messages) {
|
||||
final var queue = new SimpleMessageQueue(messages.size());
|
||||
for (final var message : messages) {
|
||||
queue.put(message);
|
||||
}
|
||||
|
||||
@ -85,7 +84,7 @@ public class ConsumerTest {
|
||||
* @return The message instance
|
||||
*/
|
||||
private static Message createMessage(final String sender, final String message) {
|
||||
final SimpleMessage msg = new SimpleMessage();
|
||||
final var msg = new SimpleMessage();
|
||||
msg.addHeader(Message.Headers.SENDER, sender);
|
||||
msg.addHeader(Message.Headers.DATE, LocalDateTime.now().toString());
|
||||
msg.setBody(message);
|
||||
@ -106,7 +105,7 @@ public class ConsumerTest {
|
||||
}
|
||||
|
||||
public boolean logContains(String message) {
|
||||
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
|
||||
return log.stream().map(ILoggingEvent::getFormattedMessage).anyMatch(message::equals);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.iluwatar.poison.pill.Message.Headers;
|
||||
import static com.iluwatar.poison.pill.Message.POISON_PILL;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 10:30 PM
|
||||
*
|
||||
|
@ -23,9 +23,6 @@
|
||||
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
@ -35,6 +32,9 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 10:32 PM
|
||||
*
|
||||
@ -44,16 +44,16 @@ public class ProducerTest {
|
||||
|
||||
@Test
|
||||
public void testSend() throws Exception {
|
||||
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
|
||||
final Producer producer = new Producer("producer", publishPoint);
|
||||
final var publishPoint = mock(MqPublishPoint.class);
|
||||
final var producer = new Producer("producer", publishPoint);
|
||||
verifyZeroInteractions(publishPoint);
|
||||
|
||||
producer.send("Hello!");
|
||||
|
||||
final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
final var messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
verify(publishPoint).put(messageCaptor.capture());
|
||||
|
||||
final Message message = messageCaptor.getValue();
|
||||
final var message = messageCaptor.getValue();
|
||||
assertNotNull(message);
|
||||
assertEquals("producer", message.getHeader(Message.Headers.SENDER));
|
||||
assertNotNull(message.getHeader(Message.Headers.DATE));
|
||||
@ -64,8 +64,8 @@ public class ProducerTest {
|
||||
|
||||
@Test
|
||||
public void testStop() throws Exception {
|
||||
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
|
||||
final Producer producer = new Producer("producer", publishPoint);
|
||||
final var publishPoint = mock(MqPublishPoint.class);
|
||||
final var producer = new Producer("producer", publishPoint);
|
||||
verifyZeroInteractions(publishPoint);
|
||||
|
||||
producer.stop();
|
||||
@ -78,7 +78,7 @@ public class ProducerTest {
|
||||
assertNotNull(e);
|
||||
assertNotNull(e.getMessage());
|
||||
assertEquals("Producer Hello! was stopped and fail to deliver requested message [producer].",
|
||||
e.getMessage());
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
verifyNoMoreInteractions(publishPoint);
|
||||
|
@ -23,16 +23,14 @@
|
||||
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 10:25 PM
|
||||
*
|
||||
@ -42,11 +40,11 @@ public class SimpleMessageTest {
|
||||
|
||||
@Test
|
||||
public void testGetHeaders() {
|
||||
final SimpleMessage message = new SimpleMessage();
|
||||
final var message = new SimpleMessage();
|
||||
assertNotNull(message.getHeaders());
|
||||
assertTrue(message.getHeaders().isEmpty());
|
||||
|
||||
final String senderName = "test";
|
||||
final var senderName = "test";
|
||||
message.addHeader(Message.Headers.SENDER, senderName);
|
||||
assertNotNull(message.getHeaders());
|
||||
assertFalse(message.getHeaders().isEmpty());
|
||||
@ -55,8 +53,8 @@ public class SimpleMessageTest {
|
||||
|
||||
@Test
|
||||
public void testUnModifiableHeaders() {
|
||||
final SimpleMessage message = new SimpleMessage();
|
||||
final Map<Message.Headers, String> headers = message.getHeaders();
|
||||
final var message = new SimpleMessage();
|
||||
final var headers = message.getHeaders();
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
headers.put(Message.Headers.SENDER, "test");
|
||||
});
|
||||
|
@ -37,22 +37,22 @@ public class Application {
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
QueueManager queueManager = new QueueManager(100);
|
||||
var queueManager = new QueueManager(100);
|
||||
|
||||
// push some message to queue
|
||||
// Low Priority message
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
queueManager.publishMessage(new Message("Low Message Priority", 0));
|
||||
}
|
||||
|
||||
// High Priority message
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
queueManager.publishMessage(new Message("High Message Priority", 1));
|
||||
}
|
||||
|
||||
|
||||
// run worker
|
||||
Worker worker = new Worker(queueManager);
|
||||
var worker = new Worker(queueManager);
|
||||
worker.run();
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
return null;
|
||||
}
|
||||
|
||||
final T root = queue[0];
|
||||
final var root = queue[0];
|
||||
queue[0] = queue[size - 1];
|
||||
size--;
|
||||
maxHeapifyDown();
|
||||
@ -83,10 +83,10 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
|
||||
|
||||
private void maxHeapifyDown() {
|
||||
int index = 0;
|
||||
var index = 0;
|
||||
while (hasLeftChild(index)) {
|
||||
|
||||
int smallerIndex = leftChildIndex(index);
|
||||
var smallerIndex = leftChildIndex(index);
|
||||
|
||||
if (hasRightChild(index) && right(index).compareTo(left(index)) > 0) {
|
||||
smallerIndex = rightChildIndex(index);
|
||||
@ -106,7 +106,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
}
|
||||
|
||||
private void maxHeapifyUp() {
|
||||
int index = size - 1;
|
||||
var index = size - 1;
|
||||
while (hasParent(index) && parent(index).compareTo(queue[index]) < 0) {
|
||||
swap(parentIndex(index), index);
|
||||
index = parentIndex(index);
|
||||
@ -154,7 +154,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
}
|
||||
|
||||
private void swap(int fpos, int tpos) {
|
||||
T tmp = queue[fpos];
|
||||
var tmp = queue[fpos];
|
||||
queue[fpos] = queue[tpos];
|
||||
queue[tpos] = tmp;
|
||||
}
|
||||
@ -170,7 +170,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
* For debug .. print current state of queue
|
||||
*/
|
||||
public void print() {
|
||||
for (int i = 0; i <= size / 2; i++) {
|
||||
for (var i = 0; i <= size / 2; i++) {
|
||||
LOGGER.info(" PARENT : " + queue[i] + " LEFT CHILD : "
|
||||
+ left(i) + " RIGHT CHILD :" + right(i));
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class QueueManager {
|
||||
private final PriorityMessageQueue<Message> messagePriorityMessageQueue;
|
||||
|
||||
public QueueManager(int initialCapacity) {
|
||||
messagePriorityMessageQueue = new PriorityMessageQueue<Message>(new Message[initialCapacity]);
|
||||
messagePriorityMessageQueue = new PriorityMessageQueue<>(new Message[initialCapacity]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ public class Worker {
|
||||
@SuppressWarnings("squid:S2189")
|
||||
public void run() throws Exception {
|
||||
while (true) {
|
||||
Message message = queueManager.receiveMessage();
|
||||
var message = queueManager.receiveMessage();
|
||||
if (message == null) {
|
||||
LOGGER.info("No Message ... waiting");
|
||||
Thread.sleep(200);
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
package com.iluwatar.priority.queue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for order of messages
|
||||
*/
|
||||
@ -36,25 +36,25 @@ public class PriorityMessageQueueTest {
|
||||
|
||||
@Test
|
||||
public void remove() {
|
||||
PriorityMessageQueue<String> stringPriorityMessageQueue = new PriorityMessageQueue<>(new String[2]);
|
||||
String pushMessage = "test";
|
||||
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new String[2]);
|
||||
var pushMessage = "test";
|
||||
stringPriorityMessageQueue.add(pushMessage);
|
||||
assertEquals(stringPriorityMessageQueue.remove(), pushMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void add() {
|
||||
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
stringPriorityMessageQueue.add(1);
|
||||
stringPriorityMessageQueue.add(5);
|
||||
stringPriorityMessageQueue.add(10);
|
||||
stringPriorityMessageQueue.add(3);
|
||||
assertTrue(stringPriorityMessageQueue.remove() == 10);
|
||||
assertEquals(10, (int) stringPriorityMessageQueue.remove());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEmpty() {
|
||||
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
assertTrue(stringPriorityMessageQueue.isEmpty());
|
||||
stringPriorityMessageQueue.add(1);
|
||||
stringPriorityMessageQueue.remove();
|
||||
@ -63,12 +63,12 @@ public class PriorityMessageQueueTest {
|
||||
|
||||
@Test
|
||||
public void testEnsureSize() {
|
||||
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
|
||||
assertTrue(stringPriorityMessageQueue.isEmpty());
|
||||
stringPriorityMessageQueue.add(1);
|
||||
stringPriorityMessageQueue.add(2);
|
||||
stringPriorityMessageQueue.add(2);
|
||||
stringPriorityMessageQueue.add(3);
|
||||
assertTrue(stringPriorityMessageQueue.remove() == 3);
|
||||
assertEquals(3, (int) stringPriorityMessageQueue.remove());
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@
|
||||
|
||||
package com.iluwatar.priority.queue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Check queue manager
|
||||
*/
|
||||
@ -34,21 +34,21 @@ public class QueueManagerTest {
|
||||
|
||||
@Test
|
||||
public void publishMessage() {
|
||||
QueueManager queueManager = new QueueManager(2);
|
||||
Message testMessage = new Message("Test Message", 1);
|
||||
var queueManager = new QueueManager(2);
|
||||
var testMessage = new Message("Test Message", 1);
|
||||
queueManager.publishMessage(testMessage);
|
||||
Message recivedMessage = queueManager.receiveMessage();
|
||||
var recivedMessage = queueManager.receiveMessage();
|
||||
assertEquals(testMessage, recivedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveMessage() {
|
||||
QueueManager queueManager = new QueueManager(2);
|
||||
Message testMessage1 = new Message("Test Message 1", 1);
|
||||
var queueManager = new QueueManager(2);
|
||||
var testMessage1 = new Message("Test Message 1", 1);
|
||||
queueManager.publishMessage(testMessage1);
|
||||
Message testMessage2 = new Message("Test Message 2", 2);
|
||||
var testMessage2 = new Message("Test Message 2", 2);
|
||||
queueManager.publishMessage(testMessage2);
|
||||
Message recivedMessage = queueManager.receiveMessage();
|
||||
var recivedMessage = queueManager.receiveMessage();
|
||||
assertEquals(testMessage2, recivedMessage);
|
||||
}
|
||||
}
|
@ -46,13 +46,13 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// stew is mutable
|
||||
Stew stew = new Stew(1, 2, 3, 4);
|
||||
var stew = new Stew(1, 2, 3, 4);
|
||||
stew.mix();
|
||||
stew.taste();
|
||||
stew.mix();
|
||||
|
||||
// immutable stew protected with Private Class Data pattern
|
||||
ImmutableStew immutableStew = new ImmutableStew(2, 4, 3, 6);
|
||||
var immutableStew = new ImmutableStew(2, 4, 3, 6);
|
||||
immutableStew.mix();
|
||||
}
|
||||
}
|
||||
|
@ -26,15 +26,12 @@ package com.iluwatar.privateclassdata;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
package com.iluwatar.privateclassdata;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.iluwatar.privateclassdata.utils.InMemoryAppender;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 10:46 PM
|
||||
*
|
||||
@ -54,10 +54,10 @@ public class ImmutableStewTest {
|
||||
*/
|
||||
@Test
|
||||
public void testMix() {
|
||||
final Stew stew = new Stew(1, 2, 3, 4);
|
||||
final String expectedMessage = "Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers";
|
||||
var stew = new Stew(1, 2, 3, 4);
|
||||
var expectedMessage = "Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers";
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
stew.mix();
|
||||
assertEquals(expectedMessage, appender.getLastMessage());
|
||||
}
|
||||
@ -70,15 +70,17 @@ public class ImmutableStewTest {
|
||||
*/
|
||||
@Test
|
||||
public void testDrink() {
|
||||
final Stew stew = new Stew(1, 2, 3, 4);
|
||||
final var stew = new Stew(1, 2, 3, 4);
|
||||
stew.mix();
|
||||
|
||||
assertEquals("Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers", appender.getLastMessage());
|
||||
assertEquals("Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers", appender
|
||||
.getLastMessage());
|
||||
|
||||
stew.taste();
|
||||
assertEquals("Tasting the stew", appender.getLastMessage());
|
||||
assertEquals("Tasting the stew", appender.getLastMessage());
|
||||
|
||||
stew.mix();
|
||||
assertEquals("Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers", appender.getLastMessage());
|
||||
assertEquals("Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers", appender
|
||||
.getLastMessage());
|
||||
}
|
||||
}
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
package com.iluwatar.privateclassdata;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.iluwatar.privateclassdata.utils.InMemoryAppender;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 10:46 PM
|
||||
*
|
||||
@ -54,11 +54,11 @@ public class StewTest {
|
||||
*/
|
||||
@Test
|
||||
public void testMix() {
|
||||
final ImmutableStew stew = new ImmutableStew(1, 2, 3, 4);
|
||||
final String expectedMessage = "Mixing the immutable stew we find: 1 potatoes, "
|
||||
final var stew = new ImmutableStew(1, 2, 3, 4);
|
||||
final var expectedMessage = "Mixing the immutable stew we find: 1 potatoes, "
|
||||
+ "2 carrots, 3 meat and 4 peppers";
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
stew.mix();
|
||||
assertEquals(expectedMessage, appender.getLastMessage());
|
||||
}
|
||||
|
@ -26,10 +26,9 @@ package com.iluwatar.privateclassdata.utils;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* InMemory Log Appender Util.
|
||||
|
@ -26,20 +26,18 @@ package com.iluwatar.producer.consumer;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces
|
||||
* coupling between Producer and Consumer by separating Identification of work with
|
||||
* Execution of Work.
|
||||
* coupling between Producer and Consumer by separating Identification of work with Execution of
|
||||
* Work.
|
||||
*
|
||||
* <p>In producer consumer design pattern a shared queue is used to control the flow and this
|
||||
* separation allows you to code producer and consumer separately. It also addresses the issue
|
||||
* of different timing require to produce item or consuming item. by using producer consumer
|
||||
* pattern both Producer and Consumer Thread can work with different speed.
|
||||
*
|
||||
* separation allows you to code producer and consumer separately. It also addresses the issue of
|
||||
* different timing require to produce item or consuming item. by using producer consumer pattern
|
||||
* both Producer and Consumer Thread can work with different speed.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
@ -47,18 +45,17 @@ public class App {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args
|
||||
* command line args
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
ItemQueue queue = new ItemQueue();
|
||||
var queue = new ItemQueue();
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(5);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
var executorService = Executors.newFixedThreadPool(5);
|
||||
for (var i = 0; i < 2; i++) {
|
||||
|
||||
final Producer producer = new Producer("Producer_" + i, queue);
|
||||
final var producer = new Producer("Producer_" + i, queue);
|
||||
executorService.submit(() -> {
|
||||
while (true) {
|
||||
producer.produce();
|
||||
@ -66,8 +63,8 @@ public class App {
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final Consumer consumer = new Consumer("Consumer_" + i, queue);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
final var consumer = new Consumer("Consumer_" + i, queue);
|
||||
executorService.submit(() -> {
|
||||
while (true) {
|
||||
consumer.consume();
|
||||
|
@ -46,10 +46,9 @@ public class Consumer {
|
||||
* Consume item from the queue.
|
||||
*/
|
||||
public void consume() throws InterruptedException {
|
||||
|
||||
Item item = queue.take();
|
||||
var item = queue.take();
|
||||
LOGGER.info("Consumer [{}] consume item [{}] produced by [{}]", name,
|
||||
item.getId(), item.getProducer());
|
||||
item.getId(), item.getProducer());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import java.util.Random;
|
||||
* to queue.
|
||||
*/
|
||||
public class Producer {
|
||||
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private final ItemQueue queue;
|
||||
@ -49,7 +49,7 @@ public class Producer {
|
||||
*/
|
||||
public void produce() throws InterruptedException {
|
||||
|
||||
Item item = new Item(name, itemId++);
|
||||
var item = new Item(name, itemId++);
|
||||
queue.put(item);
|
||||
Thread.sleep(RANDOM.nextInt(2000));
|
||||
}
|
||||
|
@ -26,16 +26,13 @@ package com.iluwatar.producer.consumer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
public void test() {
|
||||
App.main(new String[]{});
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
package com.iluwatar.producer.consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/27/15 - 11:01 PM
|
||||
*
|
||||
@ -41,15 +41,15 @@ public class ConsumerTest {
|
||||
|
||||
@Test
|
||||
public void testConsume() throws Exception {
|
||||
final ItemQueue queue = spy(new ItemQueue());
|
||||
for (int id = 0; id < ITEM_COUNT; id++) {
|
||||
final var queue = spy(new ItemQueue());
|
||||
for (var id = 0; id < ITEM_COUNT; id++) {
|
||||
queue.put(new Item("producer", id));
|
||||
}
|
||||
|
||||
reset(queue); // Don't count the preparation above as interactions with the queue
|
||||
final Consumer consumer = new Consumer("consumer", queue);
|
||||
final var consumer = new Consumer("consumer", queue);
|
||||
|
||||
for (int id = 0; id < ITEM_COUNT; id++) {
|
||||
for (var id = 0; id < ITEM_COUNT; id++) {
|
||||
consumer.consume();
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
package com.iluwatar.producer.consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static java.time.Duration.ofMillis;
|
||||
import static org.junit.jupiter.api.Assertions.assertTimeout;
|
||||
import static org.mockito.Matchers.any;
|
||||
@ -32,6 +30,8 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/28/15 - 12:12 AM
|
||||
*
|
||||
@ -42,8 +42,8 @@ public class ProducerTest {
|
||||
@Test
|
||||
public void testProduce() {
|
||||
assertTimeout(ofMillis(6000), () -> {
|
||||
final ItemQueue queue = mock(ItemQueue.class);
|
||||
final Producer producer = new Producer("producer", queue);
|
||||
final var queue = mock(ItemQueue.class);
|
||||
final var producer = new Producer("producer", queue);
|
||||
|
||||
producer.produce();
|
||||
verify(queue).put(any(Item.class));
|
||||
|
@ -29,19 +29,18 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The Promise object is used for asynchronous computations. A Promise represents an operation
|
||||
* that hasn't completed yet, but is expected in the future.
|
||||
* The Promise object is used for asynchronous computations. A Promise represents an operation that
|
||||
* hasn't completed yet, but is expected in the future.
|
||||
*
|
||||
* <p>A Promise represents a proxy for a value not necessarily known when the promise is created. It
|
||||
* allows you to associate dependent promises to an asynchronous action's eventual success value or
|
||||
* failure reason. This lets asynchronous methods return values like synchronous methods: instead
|
||||
* of the final value, the asynchronous method returns a promise of having a value at some point
|
||||
* in the future.
|
||||
* <p>A Promise represents a proxy for a value not necessarily known when the promise is created.
|
||||
* It allows you to associate dependent promises to an asynchronous action's eventual success value
|
||||
* or failure reason. This lets asynchronous methods return values like synchronous methods: instead
|
||||
* of the final value, the asynchronous method returns a promise of having a value at some point in
|
||||
* the future.
|
||||
*
|
||||
* <p>Promises provide a few advantages over callback objects:
|
||||
* <ul>
|
||||
@ -58,14 +57,15 @@ import org.slf4j.LoggerFactory;
|
||||
* a file download promise, then a promise of character frequency, then a promise of lowest
|
||||
* frequency character which is finally consumed and result is printed on console.
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @see CompletableFuture
|
||||
*/
|
||||
public class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
|
||||
private static final String DEFAULT_URL = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/promise/README.md";
|
||||
private static final String DEFAULT_URL =
|
||||
"https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/promise/README.md";
|
||||
private final ExecutorService executor;
|
||||
private final CountDownLatch stopLatch;
|
||||
|
||||
@ -76,12 +76,13 @@ public class App {
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args arguments
|
||||
* @throws InterruptedException if main thread is interrupted.
|
||||
* @throws ExecutionException if an execution error occurs.
|
||||
* @throws ExecutionException if an execution error occurs.
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException, ExecutionException {
|
||||
App app = new App();
|
||||
var app = new App();
|
||||
try {
|
||||
app.promiseUsage();
|
||||
} finally {
|
||||
@ -100,13 +101,12 @@ public class App {
|
||||
* consume the result in a Consumer<Character>
|
||||
*/
|
||||
private void calculateLowestFrequencyChar() {
|
||||
lowestFrequencyChar()
|
||||
.thenAccept(
|
||||
charFrequency -> {
|
||||
LOGGER.info("Char with lowest frequency is: {}", charFrequency);
|
||||
taskCompleted();
|
||||
}
|
||||
);
|
||||
lowestFrequencyChar().thenAccept(
|
||||
charFrequency -> {
|
||||
LOGGER.info("Char with lowest frequency is: {}", charFrequency);
|
||||
taskCompleted();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -114,13 +114,12 @@ public class App {
|
||||
* in a Consumer<Integer>
|
||||
*/
|
||||
private void calculateLineCount() {
|
||||
countLines()
|
||||
.thenAccept(
|
||||
count -> {
|
||||
LOGGER.info("Line count is: {}", count);
|
||||
taskCompleted();
|
||||
}
|
||||
);
|
||||
countLines().thenAccept(
|
||||
count -> {
|
||||
LOGGER.info("Line count is: {}", count);
|
||||
taskCompleted();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -128,17 +127,15 @@ public class App {
|
||||
* then promise to apply function to calculate lowest character frequency.
|
||||
*/
|
||||
private Promise<Character> lowestFrequencyChar() {
|
||||
return characterFrequency()
|
||||
.thenApply(Utility::lowestFrequencyChar);
|
||||
return characterFrequency().thenApply(Utility::lowestFrequencyChar);
|
||||
}
|
||||
|
||||
/*
|
||||
* Download the file at DEFAULT_URL and when that promise is fulfilled,
|
||||
* then promise to apply function to calculate character frequency.
|
||||
*/
|
||||
private Promise<Map<Character, Integer>> characterFrequency() {
|
||||
return download(DEFAULT_URL)
|
||||
.thenApply(Utility::characterFrequency);
|
||||
private Promise<Map<Character, Long>> characterFrequency() {
|
||||
return download(DEFAULT_URL).thenApply(Utility::characterFrequency);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -146,8 +143,7 @@ public class App {
|
||||
* then promise to apply function to count lines in that file.
|
||||
*/
|
||||
private Promise<Integer> countLines() {
|
||||
return download(DEFAULT_URL)
|
||||
.thenApply(Utility::countLines);
|
||||
return download(DEFAULT_URL).thenApply(Utility::countLines);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -32,10 +32,10 @@ import java.util.function.Function;
|
||||
/**
|
||||
* A Promise represents a proxy for a value not necessarily known when the promise is created. It
|
||||
* allows you to associate dependent promises to an asynchronous action's eventual success value or
|
||||
* failure reason. This lets asynchronous methods return values like synchronous methods: instead
|
||||
* of the final value, the asynchronous method returns a promise of having a value at some point
|
||||
* in the future.
|
||||
*
|
||||
* failure reason. This lets asynchronous methods return values like synchronous methods: instead of
|
||||
* the final value, the asynchronous method returns a promise of having a value at some point in the
|
||||
* future.
|
||||
*
|
||||
* @param <T> type of result.
|
||||
*/
|
||||
public class Promise<T> extends PromiseSupport<T> {
|
||||
@ -51,6 +51,7 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
|
||||
/**
|
||||
* Fulfills the promise with the provided value.
|
||||
*
|
||||
* @param value the fulfilled value that can be accessed using {@link #get()}.
|
||||
*/
|
||||
@Override
|
||||
@ -61,8 +62,9 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
|
||||
/**
|
||||
* Fulfills the promise with exception due to error in execution.
|
||||
* @param exception the exception will be wrapped in {@link ExecutionException}
|
||||
* when accessing the value using {@link #get()}.
|
||||
*
|
||||
* @param exception the exception will be wrapped in {@link ExecutionException} when accessing the
|
||||
* value using {@link #get()}.
|
||||
*/
|
||||
@Override
|
||||
public void fulfillExceptionally(Exception exception) {
|
||||
@ -86,10 +88,10 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the task using the executor in other thread and fulfills the promise returned
|
||||
* once the task completes either successfully or with an exception.
|
||||
*
|
||||
* @param task the task that will provide the value to fulfill the promise.
|
||||
* Executes the task using the executor in other thread and fulfills the promise returned once the
|
||||
* task completes either successfully or with an exception.
|
||||
*
|
||||
* @param task the task that will provide the value to fulfill the promise.
|
||||
* @param executor the executor in which the task should be run.
|
||||
* @return a promise that represents the result of running the task provided.
|
||||
*/
|
||||
@ -105,21 +107,23 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with
|
||||
* result of this promise as argument to the action provided.
|
||||
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with result
|
||||
* of this promise as argument to the action provided.
|
||||
*
|
||||
* @param action action to be executed.
|
||||
* @return a new promise.
|
||||
*/
|
||||
public Promise<Void> thenAccept(Consumer<? super T> action) {
|
||||
Promise<Void> dest = new Promise<>();
|
||||
var dest = new Promise<Void>();
|
||||
fulfillmentAction = new ConsumeAction(this, dest, action);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the exception handler on this promise.
|
||||
* @param exceptionHandler a consumer that will handle the exception occurred while fulfilling
|
||||
* the promise.
|
||||
*
|
||||
* @param exceptionHandler a consumer that will handle the exception occurred while fulfilling the
|
||||
* promise.
|
||||
* @return this
|
||||
*/
|
||||
public Promise<T> onError(Consumer<? super Throwable> exceptionHandler) {
|
||||
@ -128,8 +132,9 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with
|
||||
* result of this promise as argument to the function provided.
|
||||
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with result
|
||||
* of this promise as argument to the function provided.
|
||||
*
|
||||
* @param func function to be executed.
|
||||
* @return a new promise.
|
||||
*/
|
||||
@ -140,8 +145,8 @@ public class Promise<T> extends PromiseSupport<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesses the value from source promise and calls the consumer, then fulfills the
|
||||
* destination promise.
|
||||
* Accesses the value from source promise and calls the consumer, then fulfills the destination
|
||||
* promise.
|
||||
*/
|
||||
private class ConsumeAction implements Runnable {
|
||||
|
||||
|
@ -27,16 +27,15 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A really simplified implementation of future that allows completing it successfully with a value
|
||||
* A really simplified implementation of future that allows completing it successfully with a value
|
||||
* or exceptionally with an exception.
|
||||
*/
|
||||
class PromiseSupport<T> implements Future<T> {
|
||||
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PromiseSupport.class);
|
||||
|
||||
private static final int RUNNING = 1;
|
||||
@ -93,13 +92,12 @@ class PromiseSupport<T> implements Future<T> {
|
||||
}
|
||||
if (state == COMPLETED) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new ExecutionException(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long timeout, TimeUnit unit)
|
||||
throws ExecutionException, TimeoutException {
|
||||
public T get(long timeout, TimeUnit unit) throws ExecutionException {
|
||||
synchronized (lock) {
|
||||
while (state == RUNNING) {
|
||||
try {
|
||||
@ -110,10 +108,10 @@ class PromiseSupport<T> implements Future<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (state == COMPLETED) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new ExecutionException(exception);
|
||||
}
|
||||
}
|
@ -29,13 +29,13 @@ import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -48,86 +48,68 @@ public class Utility {
|
||||
|
||||
/**
|
||||
* Calculates character frequency of the file provided.
|
||||
*
|
||||
* @param fileLocation location of the file.
|
||||
* @return a map of character to its frequency, an empty map if file does not exist.
|
||||
*/
|
||||
public static Map<Character, Integer> characterFrequency(String fileLocation) {
|
||||
Map<Character, Integer> characterToFrequency = new HashMap<>();
|
||||
try (Reader reader = new FileReader(fileLocation);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader)) {
|
||||
for (String line; (line = bufferedReader.readLine()) != null;) {
|
||||
for (char c : line.toCharArray()) {
|
||||
if (!characterToFrequency.containsKey(c)) {
|
||||
characterToFrequency.put(c, 1);
|
||||
} else {
|
||||
characterToFrequency.put(c, characterToFrequency.get(c) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static Map<Character, Long> characterFrequency(String fileLocation) {
|
||||
try (var bufferedReader = new BufferedReader(new FileReader(fileLocation))) {
|
||||
return bufferedReader.lines()
|
||||
.flatMapToInt(String::chars)
|
||||
.mapToObj(x -> (char) x)
|
||||
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return characterToFrequency;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the character with the lowest frequency, if exists.
|
||||
*
|
||||
* @return the character, {@code Optional.empty()} otherwise.
|
||||
*/
|
||||
public static Character lowestFrequencyChar(Map<Character, Integer> charFrequency) {
|
||||
Character lowestFrequencyChar = null;
|
||||
Iterator<Entry<Character, Integer>> iterator = charFrequency.entrySet().iterator();
|
||||
Entry<Character, Integer> entry = iterator.next();
|
||||
int minFrequency = entry.getValue();
|
||||
lowestFrequencyChar = entry.getKey();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
entry = iterator.next();
|
||||
if (entry.getValue() < minFrequency) {
|
||||
minFrequency = entry.getValue();
|
||||
lowestFrequencyChar = entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return lowestFrequencyChar;
|
||||
public static Character lowestFrequencyChar(Map<Character, Long> charFrequency) {
|
||||
return charFrequency
|
||||
.entrySet()
|
||||
.stream()
|
||||
.min(Comparator.comparingLong(Entry::getValue))
|
||||
.map(Entry::getKey)
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of lines in a file.
|
||||
*
|
||||
* @return number of lines, 0 if file does not exist.
|
||||
*/
|
||||
public static Integer countLines(String fileLocation) {
|
||||
int lineCount = 0;
|
||||
try (Reader reader = new FileReader(fileLocation);
|
||||
BufferedReader bufferedReader = new BufferedReader(reader)) {
|
||||
while (bufferedReader.readLine() != null) {
|
||||
lineCount++;
|
||||
}
|
||||
try (var bufferedReader = new BufferedReader(new FileReader(fileLocation))) {
|
||||
return (int) bufferedReader.lines().count();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return lineCount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the contents from the given urlString, and stores it in a temporary directory.
|
||||
*
|
||||
* @return the absolute path of the file downloaded.
|
||||
*/
|
||||
public static String downloadFile(String urlString) throws IOException {
|
||||
LOGGER.info("Downloading contents from url: {}", urlString);
|
||||
URL url = new URL(urlString);
|
||||
File file = File.createTempFile("promise_pattern", null);
|
||||
try (Reader reader = new InputStreamReader(url.openStream());
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
FileWriter writer = new FileWriter(file)) {
|
||||
for (String line; (line = bufferedReader.readLine()) != null; ) {
|
||||
var url = new URL(urlString);
|
||||
var file = File.createTempFile("promise_pattern", null);
|
||||
try (var bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
|
||||
var writer = new FileWriter(file)) {
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
writer.write(line);
|
||||
writer.write("\n");
|
||||
}
|
||||
LOGGER.info("File downloaded at: {}", file.getAbsolutePath());
|
||||
return file.getAbsolutePath();
|
||||
} catch (IOException ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,10 @@
|
||||
|
||||
package com.iluwatar.promise;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test.
|
||||
*/
|
||||
public class AppTest {
|
||||
|
@ -23,8 +23,13 @@
|
||||
|
||||
package com.iluwatar.promise;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
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.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -33,15 +38,8 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
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.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests Promise class.
|
||||
@ -58,7 +56,7 @@ public class PromiseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void promiseIsFulfilledWithTheResultantValueOfExecutingTheTask()
|
||||
public void promiseIsFulfilledWithTheResultantValueOfExecutingTheTask()
|
||||
throws InterruptedException, ExecutionException {
|
||||
promise.fulfillInAsync(new NumberCrunchingTask(), executor);
|
||||
|
||||
@ -66,21 +64,20 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void promiseIsFulfilledWithAnExceptionIfTaskThrowsAnException()
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
public void promiseIsFulfilledWithAnExceptionIfTaskThrowsAnException()
|
||||
throws InterruptedException, TimeoutException {
|
||||
testWaitingForeverForPromiseToBeFulfilled();
|
||||
testWaitingSomeTimeForPromiseToBeFulfilled();
|
||||
}
|
||||
|
||||
private void testWaitingForeverForPromiseToBeFulfilled()
|
||||
throws InterruptedException, TimeoutException {
|
||||
Promise<Integer> promise = new Promise<>();
|
||||
private void testWaitingForeverForPromiseToBeFulfilled() throws InterruptedException {
|
||||
var promise = new Promise<Integer>();
|
||||
promise.fulfillInAsync(() -> {
|
||||
throw new RuntimeException("Barf!");
|
||||
}, executor);
|
||||
|
||||
|
||||
try {
|
||||
promise.get();
|
||||
fail("Fetching promise should result in exception if the task threw an exception");
|
||||
@ -88,7 +85,7 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
promise.get(1000, TimeUnit.SECONDS);
|
||||
fail("Fetching promise should result in exception if the task threw an exception");
|
||||
@ -97,14 +94,13 @@ public class PromiseTest {
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
}
|
||||
|
||||
private void testWaitingSomeTimeForPromiseToBeFulfilled()
|
||||
throws InterruptedException, TimeoutException {
|
||||
Promise<Integer> promise = new Promise<>();
|
||||
|
||||
private void testWaitingSomeTimeForPromiseToBeFulfilled() throws InterruptedException {
|
||||
var promise = new Promise<Integer>();
|
||||
promise.fulfillInAsync(() -> {
|
||||
throw new RuntimeException("Barf!");
|
||||
}, executor);
|
||||
|
||||
|
||||
try {
|
||||
promise.get(1000, TimeUnit.SECONDS);
|
||||
fail("Fetching promise should result in exception if the task threw an exception");
|
||||
@ -112,7 +108,7 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
promise.get();
|
||||
fail("Fetching promise should result in exception if the task threw an exception");
|
||||
@ -120,18 +116,15 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dependentPromiseIsFulfilledAfterTheConsumerConsumesTheResultOfThisPromise()
|
||||
public void dependentPromiseIsFulfilledAfterTheConsumerConsumesTheResultOfThisPromise()
|
||||
throws InterruptedException, ExecutionException {
|
||||
Promise<Void> dependentPromise = promise
|
||||
var dependentPromise = promise
|
||||
.fulfillInAsync(new NumberCrunchingTask(), executor)
|
||||
.thenAccept(value -> {
|
||||
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
|
||||
});
|
||||
|
||||
.thenAccept(value -> assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value));
|
||||
|
||||
dependentPromise.get();
|
||||
assertTrue(dependentPromise.isDone());
|
||||
@ -139,9 +132,9 @@ public class PromiseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dependentPromiseIsFulfilledWithAnExceptionIfConsumerThrowsAnException()
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Promise<Void> dependentPromise = promise
|
||||
public void dependentPromiseIsFulfilledWithAnExceptionIfConsumerThrowsAnException()
|
||||
throws InterruptedException {
|
||||
var dependentPromise = promise
|
||||
.fulfillInAsync(new NumberCrunchingTask(), executor)
|
||||
.thenAccept(value -> {
|
||||
throw new RuntimeException("Barf!");
|
||||
@ -155,7 +148,7 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
dependentPromise.get(1000, TimeUnit.SECONDS);
|
||||
fail("Fetching dependent promise should result in exception "
|
||||
@ -167,12 +160,12 @@ public class PromiseTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dependentPromiseIsFulfilledAfterTheFunctionTransformsTheResultOfThisPromise()
|
||||
public void dependentPromiseIsFulfilledAfterTheFunctionTransformsTheResultOfThisPromise()
|
||||
throws InterruptedException, ExecutionException {
|
||||
Promise<String> dependentPromise = promise
|
||||
var dependentPromise = promise
|
||||
.fulfillInAsync(new NumberCrunchingTask(), executor)
|
||||
.thenApply(value -> {
|
||||
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
|
||||
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
|
||||
return String.valueOf(value);
|
||||
});
|
||||
|
||||
@ -181,11 +174,11 @@ public class PromiseTest {
|
||||
assertTrue(dependentPromise.isDone());
|
||||
assertFalse(dependentPromise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void dependentPromiseIsFulfilledWithAnExceptionIfTheFunctionThrowsException()
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Promise<String> dependentPromise = promise
|
||||
public void dependentPromiseIsFulfilledWithAnExceptionIfTheFunctionThrowsException()
|
||||
throws InterruptedException {
|
||||
var dependentPromise = promise
|
||||
.fulfillInAsync(new NumberCrunchingTask(), executor)
|
||||
.thenApply(value -> {
|
||||
throw new RuntimeException("Barf!");
|
||||
@ -199,7 +192,7 @@ public class PromiseTest {
|
||||
assertTrue(promise.isDone());
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
dependentPromise.get(1000, TimeUnit.SECONDS);
|
||||
fail("Fetching dependent promise should result in exception "
|
||||
@ -209,26 +202,26 @@ public class PromiseTest {
|
||||
assertFalse(promise.isCancelled());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void fetchingAnAlreadyFulfilledPromiseReturnsTheFulfilledValueImmediately()
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Promise<Integer> promise = new Promise<>();
|
||||
public void fetchingAnAlreadyFulfilledPromiseReturnsTheFulfilledValueImmediately()
|
||||
throws ExecutionException {
|
||||
var promise = new Promise<Integer>();
|
||||
promise.fulfill(NumberCrunchingTask.CRUNCHED_NUMBER);
|
||||
|
||||
|
||||
promise.get(1000, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void exceptionHandlerIsCalledWhenPromiseIsFulfilledExceptionally() {
|
||||
Promise<Object> promise = new Promise<>();
|
||||
Consumer<Throwable> exceptionHandler = mock(Consumer.class);
|
||||
var promise = new Promise<>();
|
||||
var exceptionHandler = mock(Consumer.class);
|
||||
promise.onError(exceptionHandler);
|
||||
|
||||
Exception exception = new Exception("barf!");
|
||||
|
||||
var exception = new Exception("barf!");
|
||||
promise.fulfillExceptionally(exception);
|
||||
|
||||
|
||||
verify(exceptionHandler).accept(eq(exception));
|
||||
}
|
||||
|
||||
|
@ -49,36 +49,36 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
/* set up */
|
||||
Prototype charProto = new Character();
|
||||
var charProto = new Character();
|
||||
charProto.set(Stats.STRENGTH, 10);
|
||||
charProto.set(Stats.AGILITY, 10);
|
||||
charProto.set(Stats.ARMOR, 10);
|
||||
charProto.set(Stats.ATTACK_POWER, 10);
|
||||
|
||||
Character mageProto = new Character(Type.MAGE, charProto);
|
||||
var mageProto = new Character(Type.MAGE, charProto);
|
||||
mageProto.set(Stats.INTELLECT, 15);
|
||||
mageProto.set(Stats.SPIRIT, 10);
|
||||
|
||||
Character warProto = new Character(Type.WARRIOR, charProto);
|
||||
var warProto = new Character(Type.WARRIOR, charProto);
|
||||
warProto.set(Stats.RAGE, 15);
|
||||
warProto.set(Stats.ARMOR, 15); // boost default armor for warrior
|
||||
|
||||
Character rogueProto = new Character(Type.ROGUE, charProto);
|
||||
var rogueProto = new Character(Type.ROGUE, charProto);
|
||||
rogueProto.set(Stats.ENERGY, 15);
|
||||
rogueProto.set(Stats.AGILITY, 15); // boost default agility for rogue
|
||||
|
||||
/* usage */
|
||||
Character mag = new Character("Player_1", mageProto);
|
||||
var mag = new Character("Player_1", mageProto);
|
||||
mag.set(Stats.ARMOR, 8);
|
||||
LOGGER.info(mag.toString());
|
||||
|
||||
Character warrior = new Character("Player_2", warProto);
|
||||
var warrior = new Character("Player_2", warProto);
|
||||
LOGGER.info(warrior.toString());
|
||||
|
||||
Character rogue = new Character("Player_3", rogueProto);
|
||||
var rogue = new Character("Player_3", rogueProto);
|
||||
LOGGER.info(rogue.toString());
|
||||
|
||||
Character rogueDouble = new Character("Player_4", rogue);
|
||||
var rogueDouble = new Character("Player_4", rogue);
|
||||
rogueDouble.set(Stats.ATTACK_POWER, 12);
|
||||
LOGGER.info(rogueDouble.toString());
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public class Character implements Prototype {
|
||||
|
||||
@Override
|
||||
public Integer get(Stats stat) {
|
||||
boolean containsValue = properties.containsKey(stat);
|
||||
var containsValue = properties.containsKey(stat);
|
||||
if (containsValue) {
|
||||
return properties.get(stat);
|
||||
} else {
|
||||
@ -118,7 +118,7 @@ public class Character implements Prototype {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
var builder = new StringBuilder();
|
||||
if (name != null) {
|
||||
builder.append("Player: ").append(name).append('\n');
|
||||
}
|
||||
@ -128,8 +128,8 @@ public class Character implements Prototype {
|
||||
}
|
||||
|
||||
builder.append("Stats:\n");
|
||||
for (Stats stat : Stats.values()) {
|
||||
Integer value = this.get(stat);
|
||||
for (var stat : Stats.values()) {
|
||||
var value = this.get(stat);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -26,15 +26,12 @@ package com.iluwatar.property;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,15 @@
|
||||
|
||||
package com.iluwatar.property;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.iluwatar.property.Character.Type;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Date: 12/28/15 - 7:46 PM
|
||||
*
|
||||
@ -40,13 +41,13 @@ public class CharacterTest {
|
||||
|
||||
@Test
|
||||
public void testPrototypeStats() throws Exception {
|
||||
final Character prototype = new Character();
|
||||
final var prototype = new Character();
|
||||
|
||||
for (final Stats stat : Stats.values()) {
|
||||
for (final var stat : Stats.values()) {
|
||||
assertFalse(prototype.has(stat));
|
||||
assertNull(prototype.get(stat));
|
||||
|
||||
final Integer expectedValue = stat.ordinal();
|
||||
final var expectedValue = stat.ordinal();
|
||||
prototype.set(stat, expectedValue);
|
||||
assertTrue(prototype.has(stat));
|
||||
assertEquals(expectedValue, prototype.get(stat));
|
||||
@ -59,15 +60,13 @@ public class CharacterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterStats() throws Exception {
|
||||
final Character prototype = new Character();
|
||||
for (final Stats stat : Stats.values()) {
|
||||
prototype.set(stat, stat.ordinal());
|
||||
}
|
||||
public void testCharacterStats() {
|
||||
final var prototype = new Character();
|
||||
Arrays.stream(Stats.values()).forEach(stat -> prototype.set(stat, stat.ordinal()));
|
||||
|
||||
final Character mage = new Character(Type.MAGE, prototype);
|
||||
for (final Stats stat : Stats.values()) {
|
||||
final Integer expectedValue = stat.ordinal();
|
||||
final var mage = new Character(Type.MAGE, prototype);
|
||||
for (final var stat : Stats.values()) {
|
||||
final var expectedValue = stat.ordinal();
|
||||
assertTrue(mage.has(stat));
|
||||
assertEquals(expectedValue, mage.get(stat));
|
||||
}
|
||||
@ -75,17 +74,17 @@ public class CharacterTest {
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
final Character prototype = new Character();
|
||||
final var prototype = new Character();
|
||||
prototype.set(Stats.ARMOR, 1);
|
||||
prototype.set(Stats.AGILITY, 2);
|
||||
prototype.set(Stats.INTELLECT, 3);
|
||||
assertEquals("Stats:\n - AGILITY:2\n - ARMOR:1\n - INTELLECT:3\n", prototype.toString());
|
||||
|
||||
final Character stupid = new Character(Type.ROGUE, prototype);
|
||||
final var stupid = new Character(Type.ROGUE, prototype);
|
||||
stupid.remove(Stats.INTELLECT);
|
||||
assertEquals("Character type: ROGUE\nStats:\n - AGILITY:2\n - ARMOR:1\n", stupid.toString());
|
||||
|
||||
final Character weak = new Character("weak", prototype);
|
||||
final var weak = new Character("weak", prototype);
|
||||
weak.remove(Stats.ARMOR);
|
||||
assertEquals("Player: weak\nStats:\n - AGILITY:2\n - INTELLECT:3\n", weak.toString());
|
||||
|
||||
@ -93,32 +92,32 @@ public class CharacterTest {
|
||||
|
||||
@Test
|
||||
public void testName() {
|
||||
final Character prototype = new Character();
|
||||
final var prototype = new Character();
|
||||
prototype.set(Stats.ARMOR, 1);
|
||||
prototype.set(Stats.INTELLECT, 2);
|
||||
assertNull(prototype.name());
|
||||
|
||||
final Character stupid = new Character(Type.ROGUE, prototype);
|
||||
final var stupid = new Character(Type.ROGUE, prototype);
|
||||
stupid.remove(Stats.INTELLECT);
|
||||
assertNull(stupid.name());
|
||||
|
||||
final Character weak = new Character("weak", prototype);
|
||||
final var weak = new Character("weak", prototype);
|
||||
weak.remove(Stats.ARMOR);
|
||||
assertEquals("weak", weak.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testType() {
|
||||
final Character prototype = new Character();
|
||||
final var prototype = new Character();
|
||||
prototype.set(Stats.ARMOR, 1);
|
||||
prototype.set(Stats.INTELLECT, 2);
|
||||
assertNull(prototype.type());
|
||||
|
||||
final Character stupid = new Character(Type.ROGUE, prototype);
|
||||
final var stupid = new Character(Type.ROGUE, prototype);
|
||||
stupid.remove(Stats.INTELLECT);
|
||||
assertEquals(Type.ROGUE, stupid.type());
|
||||
|
||||
final Character weak = new Character("weak", prototype);
|
||||
final var weak = new Character("weak", prototype);
|
||||
weak.remove(Stats.ARMOR);
|
||||
assertNull(weak.type());
|
||||
}
|
||||
|
@ -52,11 +52,11 @@ class Sheep implements Cloneable {
|
||||
Then it can be cloned like below
|
||||
|
||||
```java
|
||||
Sheep original = new Sheep("Jolly");
|
||||
var original = new Sheep("Jolly");
|
||||
System.out.println(original.getName()); // Jolly
|
||||
|
||||
// Clone and modify what is required
|
||||
Sheep cloned = original.clone();
|
||||
var cloned = original.clone();
|
||||
cloned.setName("Dolly");
|
||||
System.out.println(cloned.getName()); // Dolly
|
||||
```
|
||||
|
@ -46,24 +46,23 @@ public class App {
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
HeroFactory factory = new HeroFactoryImpl(
|
||||
var factory = new HeroFactoryImpl(
|
||||
new ElfMage("cooking"),
|
||||
new ElfWarlord("cleaning"),
|
||||
new ElfBeast("protecting")
|
||||
);
|
||||
Mage mage = factory.createMage();
|
||||
Warlord warlord = factory.createWarlord();
|
||||
Beast beast = factory.createBeast();
|
||||
var mage = factory.createMage();
|
||||
var warlord = factory.createWarlord();
|
||||
var beast = factory.createBeast();
|
||||
LOGGER.info(mage.toString());
|
||||
LOGGER.info(warlord.toString());
|
||||
LOGGER.info(beast.toString());
|
||||
|
||||
factory =
|
||||
new HeroFactoryImpl(
|
||||
new OrcMage("axe"),
|
||||
new OrcWarlord("sword"),
|
||||
new OrcBeast("laser")
|
||||
);
|
||||
factory = new HeroFactoryImpl(
|
||||
new OrcMage("axe"),
|
||||
new OrcWarlord("sword"),
|
||||
new OrcBeast("laser")
|
||||
);
|
||||
mage = factory.createMage();
|
||||
warlord = factory.createWarlord();
|
||||
beast = factory.createBeast();
|
||||
|
@ -28,9 +28,11 @@ package com.iluwatar.prototype;
|
||||
*/
|
||||
public abstract class Beast implements Prototype {
|
||||
|
||||
public Beast() { }
|
||||
public Beast() {
|
||||
}
|
||||
|
||||
public Beast(Beast source) { }
|
||||
public Beast(Beast source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Beast copy();
|
||||
|
@ -60,15 +60,11 @@ public class ElfBeast extends Beast {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ElfBeast other = (ElfBeast) obj;
|
||||
var other = (ElfBeast) obj;
|
||||
if (helpType == null) {
|
||||
if (other.helpType != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!helpType.equals(other.helpType)) {
|
||||
return false;
|
||||
return other.helpType == null;
|
||||
}
|
||||
return true;
|
||||
return helpType.equals(other.helpType);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,14 +60,10 @@ public class ElfMage extends Mage {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ElfMage other = (ElfMage) obj;
|
||||
var other = (ElfMage) obj;
|
||||
if (helpType == null) {
|
||||
if (other.helpType != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!helpType.equals(other.helpType)) {
|
||||
return false;
|
||||
return other.helpType == null;
|
||||
}
|
||||
return true;
|
||||
return helpType.equals(other.helpType);
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +60,10 @@ public class ElfWarlord extends Warlord {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ElfWarlord other = (ElfWarlord) obj;
|
||||
var other = (ElfWarlord) obj;
|
||||
if (helpType == null) {
|
||||
if (other.helpType != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!helpType.equals(other.helpType)) {
|
||||
return false;
|
||||
return other.helpType == null;
|
||||
}
|
||||
return true;
|
||||
return helpType.equals(other.helpType);
|
||||
}
|
||||
}
|
@ -28,9 +28,11 @@ package com.iluwatar.prototype;
|
||||
*/
|
||||
public abstract class Mage implements Prototype {
|
||||
|
||||
public Mage() { }
|
||||
public Mage() {
|
||||
}
|
||||
|
||||
public Mage(Mage source) { }
|
||||
public Mage(Mage source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Mage copy();
|
||||
|
@ -60,15 +60,11 @@ public class OrcBeast extends Beast {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrcBeast other = (OrcBeast) obj;
|
||||
var other = (OrcBeast) obj;
|
||||
if (weapon == null) {
|
||||
if (other.weapon != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!weapon.equals(other.weapon)) {
|
||||
return false;
|
||||
return other.weapon == null;
|
||||
}
|
||||
return true;
|
||||
return weapon.equals(other.weapon);
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,14 +60,10 @@ public class OrcMage extends Mage {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrcMage other = (OrcMage) obj;
|
||||
var other = (OrcMage) obj;
|
||||
if (weapon == null) {
|
||||
if (other.weapon != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!weapon.equals(other.weapon)) {
|
||||
return false;
|
||||
return other.weapon == null;
|
||||
}
|
||||
return true;
|
||||
return weapon.equals(other.weapon);
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +60,10 @@ public class OrcWarlord extends Warlord {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrcWarlord other = (OrcWarlord) obj;
|
||||
var other = (OrcWarlord) obj;
|
||||
if (weapon == null) {
|
||||
if (other.weapon != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!weapon.equals(other.weapon)) {
|
||||
return false;
|
||||
return other.weapon == null;
|
||||
}
|
||||
return true;
|
||||
return weapon.equals(other.weapon);
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,11 @@ package com.iluwatar.prototype;
|
||||
*/
|
||||
public abstract class Warlord implements Prototype {
|
||||
|
||||
public Warlord() { }
|
||||
public Warlord() {
|
||||
}
|
||||
|
||||
public Warlord(Warlord source) { }
|
||||
public Warlord(Warlord source) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Warlord copy();
|
||||
|
@ -26,15 +26,12 @@ package com.iluwatar.prototype;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,37 +23,40 @@
|
||||
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* Date: 12/28/15 - 8:45 PM
|
||||
*
|
||||
* @param <P> Prototype
|
||||
* @author Jeroen Meulemeester
|
||||
*/
|
||||
public class PrototypeTest<P extends Prototype> {
|
||||
static Collection<Object[]> dataProvider() {
|
||||
return List.of(
|
||||
new Object[]{new OrcBeast("axe"), "Orcish wolf attacks with axe"},
|
||||
new Object[]{new OrcMage("sword"), "Orcish mage attacks with sword"},
|
||||
new Object[]{new OrcWarlord("laser"), "Orcish warlord attacks with laser"},
|
||||
new Object[]{new ElfBeast("cooking"), "Elven eagle helps in cooking"},
|
||||
new Object[]{new ElfMage("cleaning"), "Elven mage helps in cleaning"},
|
||||
new Object[]{new ElfWarlord("protecting"), "Elven warlord helps in protecting"}
|
||||
new Object[]{new OrcBeast("axe"), "Orcish wolf attacks with axe"},
|
||||
new Object[]{new OrcMage("sword"), "Orcish mage attacks with sword"},
|
||||
new Object[]{new OrcWarlord("laser"), "Orcish warlord attacks with laser"},
|
||||
new Object[]{new ElfBeast("cooking"), "Elven eagle helps in cooking"},
|
||||
new Object[]{new ElfMage("cleaning"), "Elven mage helps in cleaning"},
|
||||
new Object[]{new ElfWarlord("protecting"), "Elven warlord helps in protecting"}
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("dataProvider")
|
||||
public void testPrototype(P testedPrototype, String expectedToString) throws Exception {
|
||||
public void testPrototype(P testedPrototype, String expectedToString) {
|
||||
assertEquals(expectedToString, testedPrototype.toString());
|
||||
|
||||
final Object clone = testedPrototype.copy();
|
||||
final var clone = testedPrototype.copy();
|
||||
assertNotNull(clone);
|
||||
assertNotSame(clone, testedPrototype);
|
||||
assertSame(testedPrototype.getClass(), clone.getClass());
|
||||
|
@ -100,7 +100,7 @@ public class WizardTowerProxy implements WizardTower {
|
||||
And here is tower entering scenario
|
||||
|
||||
```java
|
||||
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
|
||||
var proxy = new WizardTowerProxy(new IvoryTower());
|
||||
proxy.enter(new Wizard("Red wizard")); // Red wizard enters the tower.
|
||||
proxy.enter(new Wizard("White wizard")); // White wizard enters the tower.
|
||||
proxy.enter(new Wizard("Black wizard")); // Black wizard enters the tower.
|
||||
|
@ -44,7 +44,7 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
|
||||
var proxy = new WizardTowerProxy(new IvoryTower());
|
||||
proxy.enter(new Wizard("Red wizard"));
|
||||
proxy.enter(new Wizard("White wizard"));
|
||||
proxy.enter(new Wizard("Black wizard"));
|
||||
|
@ -26,15 +26,12 @@ package com.iluwatar.proxy;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
App.main(new String[]{});
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,15 @@
|
||||
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.iluwatar.proxy.utils.InMemoryAppender;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link IvoryTower}
|
||||
*/
|
||||
@ -49,18 +50,16 @@ public class IvoryTowerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnter() throws Exception {
|
||||
final Wizard[] wizards = new Wizard[]{
|
||||
public void testEnter() {
|
||||
final var wizards = List.of(
|
||||
new Wizard("Gandalf"),
|
||||
new Wizard("Dumbledore"),
|
||||
new Wizard("Oz"),
|
||||
new Wizard("Merlin")
|
||||
};
|
||||
);
|
||||
|
||||
IvoryTower tower = new IvoryTower();
|
||||
for (Wizard wizard : wizards) {
|
||||
tower.enter(wizard);
|
||||
}
|
||||
var tower = new IvoryTower();
|
||||
wizards.forEach(tower::enter);
|
||||
|
||||
assertTrue(appender.logContains("Gandalf enters the tower."));
|
||||
assertTrue(appender.logContains("Dumbledore enters the tower."));
|
||||
|
@ -23,20 +23,19 @@
|
||||
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link Wizard}
|
||||
*/
|
||||
public class WizardTest {
|
||||
|
||||
@Test
|
||||
public void testToString() throws Exception {
|
||||
final String[] wizardNames = {"Gandalf", "Dumbledore", "Oz", "Merlin"};
|
||||
for (String name : wizardNames) {
|
||||
assertEquals(name, new Wizard(name).toString());
|
||||
}
|
||||
public void testToString() {
|
||||
List.of("Gandalf", "Dumbledore", "Oz", "Merlin")
|
||||
.forEach(name -> assertEquals(name, new Wizard(name).toString()));
|
||||
}
|
||||
}
|
@ -23,14 +23,15 @@
|
||||
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.iluwatar.proxy.utils.InMemoryAppender;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link WizardTowerProxy}
|
||||
*/
|
||||
@ -50,17 +51,15 @@ public class WizardTowerProxyTest {
|
||||
|
||||
@Test
|
||||
public void testEnter() throws Exception {
|
||||
final Wizard[] wizards = new Wizard[]{
|
||||
final var wizards = List.of(
|
||||
new Wizard("Gandalf"),
|
||||
new Wizard("Dumbledore"),
|
||||
new Wizard("Oz"),
|
||||
new Wizard("Merlin")
|
||||
};
|
||||
);
|
||||
|
||||
final WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
|
||||
for (Wizard wizard : wizards) {
|
||||
proxy.enter(wizard);
|
||||
}
|
||||
final var proxy = new WizardTowerProxy(new IvoryTower());
|
||||
wizards.forEach(proxy::enter);
|
||||
|
||||
assertTrue(appender.logContains("Gandalf enters the tower."));
|
||||
assertTrue(appender.logContains("Dumbledore enters the tower."));
|
||||
|
@ -26,10 +26,9 @@ package com.iluwatar.proxy.utils;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
@ -54,7 +53,7 @@ public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
|
||||
}
|
||||
|
||||
public boolean logContains(String message) {
|
||||
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
|
||||
return log.stream().map(ILoggingEvent::getFormattedMessage).anyMatch(message::equals);
|
||||
}
|
||||
|
||||
public int getLogSize() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user