Merge pull request #515 from dbryla/master

#502 Added logging framework to repository
This commit is contained in:
Ilkka Seppälä 2016-11-18 20:47:17 +02:00 committed by GitHub
commit 68ec24c62e
215 changed files with 2927 additions and 2450 deletions

2
.gitignore vendored
View File

@ -15,5 +15,5 @@ datanucleus.log
/bin/ /bin/
/bin/ /bin/
/bin/ /bin/
*.log
data-mapper/src/main/resources/log4j.xml data-mapper/src/main/resources/log4j.xml

View File

@ -27,6 +27,8 @@ import com.iluwatar.abstractdocument.domain.HasModel;
import com.iluwatar.abstractdocument.domain.HasParts; import com.iluwatar.abstractdocument.domain.HasParts;
import com.iluwatar.abstractdocument.domain.HasPrice; import com.iluwatar.abstractdocument.domain.HasPrice;
import com.iluwatar.abstractdocument.domain.HasType; import com.iluwatar.abstractdocument.domain.HasType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -44,11 +46,13 @@ import java.util.Map;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Executes the App * Executes the App
*/ */
public App() { public App() {
System.out.println("Constructing parts and car"); LOGGER.info("Constructing parts and car");
Map<String, Object> carProperties = new HashMap<>(); Map<String, Object> carProperties = new HashMap<>();
carProperties.put(HasModel.PROPERTY, "300SL"); carProperties.put(HasModel.PROPERTY, "300SL");
@ -68,12 +72,11 @@ public class App {
Car car = new Car(carProperties); Car car = new Car(carProperties);
System.out.println("Here is our car:"); LOGGER.info("Here is our car:");
System.out.println("-> model: " + car.getModel().get()); LOGGER.info("-> model: {}", car.getModel().get());
System.out.println("-> price: " + car.getPrice().get()); LOGGER.info("-> price: {}", car.getPrice().get());
System.out.println("-> parts: "); LOGGER.info("-> parts: ");
car.getParts().forEach(p -> System.out car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", p.getType().get(), p.getModel().get(), p.getPrice().get()));
.println("\t" + p.getType().get() + "/" + p.getModel().get() + "/" + p.getPrice().get()));
} }
/** /**

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.abstractfactory; package com.iluwatar.abstractfactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
@ -39,6 +42,8 @@ package com.iluwatar.abstractfactory;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private King king; private King king;
private Castle castle; private Castle castle;
private Army army; private Army army;
@ -98,17 +103,17 @@ public class App {
App app = new App(); App app = new App();
System.out.println("Elf Kingdom"); LOGGER.info("Elf Kingdom");
app.createKingdom(new ElfKingdomFactory()); app.createKingdom(new ElfKingdomFactory());
System.out.println(app.getArmy().getDescription()); LOGGER.info(app.getArmy().getDescription());
System.out.println(app.getCastle().getDescription()); LOGGER.info(app.getCastle().getDescription());
System.out.println(app.getKing().getDescription()); LOGGER.info(app.getKing().getDescription());
System.out.println("\nOrc Kingdom"); LOGGER.info("Orc Kingdom");
app.createKingdom(new OrcKingdomFactory()); app.createKingdom(new OrcKingdomFactory());
System.out.println(app.getArmy().getDescription()); LOGGER.info(app.getArmy().getDescription());
System.out.println(app.getCastle().getDescription()); LOGGER.info(app.getCastle().getDescription());
System.out.println(app.getKing().getDescription()); LOGGER.info(app.getKing().getDescription());
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.adapter; package com.iluwatar.adapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip} * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
@ -33,6 +36,8 @@ package com.iluwatar.adapter;
*/ */
public class BattleFishingBoat implements BattleShip { public class BattleFishingBoat implements BattleShip {
private static final Logger LOGGER = LoggerFactory.getLogger(BattleFishingBoat.class);
private FishingBoat boat; private FishingBoat boat;
public BattleFishingBoat() { public BattleFishingBoat() {
@ -41,7 +46,7 @@ public class BattleFishingBoat implements BattleShip {
@Override @Override
public void fire() { public void fire() {
System.out.println("fire!"); LOGGER.info("fire!");
} }
@Override @Override

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.adapter; package com.iluwatar.adapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Device class (adaptee in the pattern). We want to reuse this class * Device class (adaptee in the pattern). We want to reuse this class
@ -29,12 +32,14 @@ package com.iluwatar.adapter;
*/ */
public class FishingBoat { public class FishingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
public void sail() { public void sail() {
System.out.println("The Boat is moving to that place"); LOGGER.info("The Boat is moving to that place");
} }
public void fish() { public void fish() {
System.out.println("fishing ..."); LOGGER.info("fishing ...");
} }
} }

View File

@ -27,6 +27,8 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
@ -37,6 +39,8 @@ import java.io.IOException;
@Component @Component
public class ProductInformationClientImpl implements ProductInformationClient { public class ProductInformationClientImpl implements ProductInformationClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInformationClientImpl.class);
@Override @Override
public String getProductTitle() { public String getProductTitle() {
String response = null; String response = null;
@ -46,7 +50,7 @@ public class ProductInformationClientImpl implements ProductInformationClient {
response = EntityUtils.toString(httpResponse.getEntity()); response = EntityUtils.toString(httpResponse.getEntity());
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Exception caught.", e);
} }
return response; return response;
} }

View File

@ -27,6 +27,8 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
@ -37,6 +39,8 @@ import java.io.IOException;
@Component @Component
public class ProductInventoryClientImpl implements ProductInventoryClient { public class ProductInventoryClientImpl implements ProductInventoryClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInventoryClientImpl.class);
@Override @Override
public int getProductInventories() { public int getProductInventories() {
String response = "0"; String response = "0";
@ -46,7 +50,7 @@ public class ProductInventoryClientImpl implements ProductInventoryClient {
response = EntityUtils.toString(httpResponse.getEntity()); response = EntityUtils.toString(httpResponse.getEntity());
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Exception caught.", e);
} }
return Integer.parseInt(response); return Integer.parseInt(response);
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.async.method.invocation; package com.iluwatar.async.method.invocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
@ -54,6 +57,8 @@ import java.util.concurrent.Callable;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -120,6 +125,6 @@ public class App {
} }
private static void log(String msg) { private static void log(String msg) {
System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg)); LOGGER.info(msg);
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.bridge; package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Excalibur * Excalibur
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/ */
public class Excalibur extends BlindingMagicWeaponImpl { public class Excalibur extends BlindingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class);
@Override @Override
public void wieldImp() { public void wieldImp() {
System.out.println("wielding Excalibur"); LOGGER.info("wielding Excalibur");
} }
@Override @Override
public void swingImp() { public void swingImp() {
System.out.println("swinging Excalibur"); LOGGER.info("swinging Excalibur");
} }
@Override @Override
public void unwieldImp() { public void unwieldImp() {
System.out.println("unwielding Excalibur"); LOGGER.info("unwielding Excalibur");
} }
@Override @Override
public void blindImp() { public void blindImp() {
System.out.println("bright light streams from Excalibur blinding the enemy"); LOGGER.info("bright light streams from Excalibur blinding the enemy");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.bridge; package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Mjollnir * Mjollnir
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/ */
public class Mjollnir extends FlyingMagicWeaponImpl { public class Mjollnir extends FlyingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class);
@Override @Override
public void wieldImp() { public void wieldImp() {
System.out.println("wielding Mjollnir"); LOGGER.info("wielding Mjollnir");
} }
@Override @Override
public void swingImp() { public void swingImp() {
System.out.println("swinging Mjollnir"); LOGGER.info("swinging Mjollnir");
} }
@Override @Override
public void unwieldImp() { public void unwieldImp() {
System.out.println("unwielding Mjollnir"); LOGGER.info("unwielding Mjollnir");
} }
@Override @Override
public void flyImp() { public void flyImp() {
System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand"); LOGGER.info("Mjollnir hits the enemy in the air and returns back to the owner's hand");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.bridge; package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Stormbringer * Stormbringer
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/ */
public class Stormbringer extends SoulEatingMagicWeaponImpl { public class Stormbringer extends SoulEatingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Stormbringer.class);
@Override @Override
public void wieldImp() { public void wieldImp() {
System.out.println("wielding Stormbringer"); LOGGER.info("wielding Stormbringer");
} }
@Override @Override
public void swingImp() { public void swingImp() {
System.out.println("swinging Stormbringer"); LOGGER.info("swinging Stormbringer");
} }
@Override @Override
public void unwieldImp() { public void unwieldImp() {
System.out.println("unwielding Stormbringer"); LOGGER.info("unwielding Stormbringer");
} }
@Override @Override
public void eatSoulImp() { public void eatSoulImp() {
System.out.println("Stormbringer devours the enemy's soul"); LOGGER.info("Stormbringer devours the enemy's soul");
} }
} }

View File

@ -23,6 +23,8 @@
package com.iluwatar.builder; package com.iluwatar.builder;
import com.iluwatar.builder.Hero.Builder; import com.iluwatar.builder.Hero.Builder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
@ -50,6 +52,8 @@ import com.iluwatar.builder.Hero.Builder;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -60,18 +64,18 @@ public class App {
Hero mage = Hero mage =
new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK) new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK)
.withWeapon(Weapon.DAGGER).build(); .withWeapon(Weapon.DAGGER).build();
System.out.println(mage); LOGGER.info(mage.toString());
Hero warrior = Hero warrior =
new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND) new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
.withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD) .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
.build(); .build();
System.out.println(warrior); LOGGER.info(warrior.toString());
Hero thief = Hero thief =
new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD) new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD)
.withWeapon(Weapon.BOW).build(); .withWeapon(Weapon.BOW).build();
System.out.println(thief); LOGGER.info(thief.toString());
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.business.delegate; package com.iluwatar.business.delegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Service EJB implementation * Service EJB implementation
@ -29,8 +32,10 @@ package com.iluwatar.business.delegate;
*/ */
public class EjbService implements BusinessService { public class EjbService implements BusinessService {
private static final Logger LOGGER = LoggerFactory.getLogger(EjbService.class);
@Override @Override
public void doProcessing() { public void doProcessing() {
System.out.println("EjbService is now processing"); LOGGER.info("EjbService is now processing");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.business.delegate; package com.iluwatar.business.delegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Service JMS implementation * Service JMS implementation
@ -29,8 +32,10 @@ package com.iluwatar.business.delegate;
*/ */
public class JmsService implements BusinessService { public class JmsService implements BusinessService {
private static final Logger LOGGER = LoggerFactory.getLogger(JmsService.class);
@Override @Override
public void doProcessing() { public void doProcessing() {
System.out.println("JmsService is now processing"); LOGGER.info("JmsService is now processing");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.caching; package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing * The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
@ -60,6 +63,9 @@ package com.iluwatar.caching;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -82,13 +88,13 @@ public class App {
* Read-through and write-through * Read-through and write-through
*/ */
public void useReadAndWriteThroughStrategy() { public void useReadAndWriteThroughStrategy() {
System.out.println("# CachingPolicy.THROUGH"); LOGGER.info("# CachingPolicy.THROUGH");
AppManager.initCachingPolicy(CachingPolicy.THROUGH); AppManager.initCachingPolicy(CachingPolicy.THROUGH);
UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy."); UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy.");
AppManager.save(userAccount1); AppManager.save(userAccount1);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("001"); AppManager.find("001");
AppManager.find("001"); AppManager.find("001");
} }
@ -97,21 +103,21 @@ public class App {
* Read-through and write-around * Read-through and write-around
*/ */
public void useReadThroughAndWriteAroundStrategy() { public void useReadThroughAndWriteAroundStrategy() {
System.out.println("# CachingPolicy.AROUND"); LOGGER.info("# CachingPolicy.AROUND");
AppManager.initCachingPolicy(CachingPolicy.AROUND); AppManager.initCachingPolicy(CachingPolicy.AROUND);
UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl."); UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl.");
AppManager.save(userAccount2); AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("002"); AppManager.find("002");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
userAccount2 = AppManager.find("002"); userAccount2 = AppManager.find("002");
userAccount2.setUserName("Jane G."); userAccount2.setUserName("Jane G.");
AppManager.save(userAccount2); AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("002"); AppManager.find("002");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("002"); AppManager.find("002");
} }
@ -119,7 +125,7 @@ public class App {
* Read-through and write-behind * Read-through and write-behind
*/ */
public void useReadThroughAndWriteBehindStrategy() { public void useReadThroughAndWriteBehindStrategy() {
System.out.println("# CachingPolicy.BEHIND"); LOGGER.info("# CachingPolicy.BEHIND");
AppManager.initCachingPolicy(CachingPolicy.BEHIND); AppManager.initCachingPolicy(CachingPolicy.BEHIND);
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food."); UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
@ -129,23 +135,23 @@ public class App {
AppManager.save(userAccount3); AppManager.save(userAccount3);
AppManager.save(userAccount4); AppManager.save(userAccount4);
AppManager.save(userAccount5); AppManager.save(userAccount5);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("003"); AppManager.find("003");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child."); UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child.");
AppManager.save(userAccount6); AppManager.save(userAccount6);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("004"); AppManager.find("004");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
} }
/** /**
* Cache-Aside * Cache-Aside
*/ */
public void useCacheAsideStategy() { public void useCacheAsideStategy() {
System.out.println("# CachingPolicy.ASIDE"); LOGGER.info("# CachingPolicy.ASIDE");
AppManager.initCachingPolicy(CachingPolicy.ASIDE); AppManager.initCachingPolicy(CachingPolicy.ASIDE);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food."); UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats."); UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
@ -154,10 +160,10 @@ public class App {
AppManager.save(userAccount4); AppManager.save(userAccount4);
AppManager.save(userAccount5); AppManager.save(userAccount5);
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("003"); AppManager.find("003");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
AppManager.find("004"); AppManager.find("004");
System.out.println(AppManager.printCacheContent()); LOGGER.info(AppManager.printCacheContent());
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.caching; package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
/** /**
@ -31,6 +34,8 @@ import java.util.List;
*/ */
public class CacheStore { public class CacheStore {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheStore.class);
static LruCache cache; static LruCache cache;
private CacheStore() { private CacheStore() {
@ -52,10 +57,10 @@ public class CacheStore {
*/ */
public static UserAccount readThrough(String userId) { public static UserAccount readThrough(String userId) {
if (cache.contains(userId)) { if (cache.contains(userId)) {
System.out.println("# Cache Hit!"); LOGGER.info("# Cache Hit!");
return cache.get(userId); return cache.get(userId);
} }
System.out.println("# Cache Miss!"); LOGGER.info("# Cache Miss!");
UserAccount userAccount = DbManager.readFromDb(userId); UserAccount userAccount = DbManager.readFromDb(userId);
cache.set(userId, userAccount); cache.set(userId, userAccount);
return userAccount; return userAccount;
@ -91,13 +96,13 @@ public class CacheStore {
*/ */
public static UserAccount readThroughWithWriteBackPolicy(String userId) { public static UserAccount readThroughWithWriteBackPolicy(String userId) {
if (cache.contains(userId)) { if (cache.contains(userId)) {
System.out.println("# Cache Hit!"); LOGGER.info("# Cache Hit!");
return cache.get(userId); return cache.get(userId);
} }
System.out.println("# Cache Miss!"); LOGGER.info("# Cache Miss!");
UserAccount userAccount = DbManager.readFromDb(userId); UserAccount userAccount = DbManager.readFromDb(userId);
if (cache.isFull()) { if (cache.isFull()) {
System.out.println("# Cache is FULL! Writing LRU data to DB..."); LOGGER.info("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDb = cache.getLruData(); UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb); DbManager.upsertDb(toBeWrittenToDb);
} }
@ -110,7 +115,7 @@ public class CacheStore {
*/ */
public static void writeBehind(UserAccount userAccount) { public static void writeBehind(UserAccount userAccount) {
if (cache.isFull() && !cache.contains(userAccount.getUserId())) { if (cache.isFull() && !cache.contains(userAccount.getUserId())) {
System.out.println("# Cache is FULL! Writing LRU data to DB..."); LOGGER.info("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDb = cache.getLruData(); UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb); DbManager.upsertDb(toBeWrittenToDb);
} }
@ -130,7 +135,7 @@ public class CacheStore {
* Writes remaining content in the cache into the DB. * Writes remaining content in the cache into the DB.
*/ */
public static void flushCache() { public static void flushCache() {
System.out.println("# flushCache..."); LOGGER.info("# flushCache...");
if (null == cache) { if (null == cache) {
return; return;
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.caching; package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -38,6 +41,8 @@ import java.util.Map;
*/ */
public class LruCache { public class LruCache {
private static final Logger LOGGER = LoggerFactory.getLogger(LruCache.class);
class Node { class Node {
String userId; String userId;
UserAccount userAccount; UserAccount userAccount;
@ -115,7 +120,7 @@ public class LruCache {
} else { } else {
Node newNode = new Node(userId, userAccount); Node newNode = new Node(userId, userAccount);
if (cache.size() >= capacity) { if (cache.size() >= capacity) {
System.out.println("# Cache is FULL! Removing " + end.userId + " from cache..."); LOGGER.info("# Cache is FULL! Removing {} from cache...", end.userId);
cache.remove(end.userId); // remove LRU data from cache. cache.remove(end.userId); // remove LRU data from cache.
remove(end); remove(end);
setHead(newNode); setHead(newNode);
@ -136,7 +141,7 @@ public class LruCache {
public void invalidate(String userId) { public void invalidate(String userId) {
Node toBeRemoved = cache.remove(userId); Node toBeRemoved = cache.remove(userId);
if (toBeRemoved != null) { if (toBeRemoved != null) {
System.out.println("# " + userId + " has been updated! Removing older version from cache..."); LOGGER.info("# {} has been updated! Removing older version from cache...", userId);
remove(toBeRemoved); remove(toBeRemoved);
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Callback pattern is more native for functional languages where functions are treated as * Callback pattern is more native for functional languages where functions are treated as
@ -31,6 +34,8 @@ package com.iluwatar.callback;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -39,7 +44,7 @@ public class App {
Callback callback = new Callback() { Callback callback = new Callback() {
@Override @Override
public void call() { public void call() {
System.out.println("I'm done now."); LOGGER.info("I'm done now.");
} }
}; };
task.executeWith(callback); task.executeWith(callback);

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* This example generates the exact same output as {@link App} however the callback has been * This example generates the exact same output as {@link App} however the callback has been
@ -30,12 +33,14 @@ package com.iluwatar.callback;
*/ */
public class LambdasApp { public class LambdasApp {
private static final Logger LOGGER = LoggerFactory.getLogger(LambdasApp.class);
/** /**
* Program entry point * Program entry point
*/ */
public static void main(String[] args) { public static void main(String[] args) {
Task task = new SimpleTask(); Task task = new SimpleTask();
Callback c = () -> System.out.println("I'm done now."); Callback c = () -> LOGGER.info("I'm done now.");
task.executeWith(c); task.executeWith(c);
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Implementation of task that need to be executed * Implementation of task that need to be executed
@ -29,8 +32,10 @@ package com.iluwatar.callback;
*/ */
public class SimpleTask extends Task { public class SimpleTask extends Task {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTask.class);
@Override @Override
public void execute() { public void execute() {
System.out.println("Perform some important activity and after call the callback method."); LOGGER.info("Perform some important activity and after call the callback method.");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.chain; package com.iluwatar.chain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* RequestHandler * RequestHandler
@ -29,6 +32,8 @@ package com.iluwatar.chain;
*/ */
public abstract class RequestHandler { public abstract class RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
private RequestHandler next; private RequestHandler next;
public RequestHandler(RequestHandler next) { public RequestHandler(RequestHandler next) {
@ -45,7 +50,7 @@ public abstract class RequestHandler {
} }
protected void printHandling(Request req) { protected void printHandling(Request req) {
System.out.println(this + " handling request \"" + req + "\""); LOGGER.info("{} handling request \"{}\"", this, req);
} }
@Override @Override

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.command; package com.iluwatar.command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Base class for spell targets. * Base class for spell targets.
@ -29,6 +32,8 @@ package com.iluwatar.command;
*/ */
public abstract class Target { public abstract class Target {
private static final Logger LOGGER = LoggerFactory.getLogger(Target.class);
private Size size; private Size size;
private Visibility visibility; private Visibility visibility;
@ -56,8 +61,6 @@ public abstract class Target {
* Print status * Print status
*/ */
public void printStatus() { public void printStatus() {
System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(), LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility());
getVisibility()));
System.out.println();
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.command; package com.iluwatar.command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Deque; import java.util.Deque;
import java.util.LinkedList; import java.util.LinkedList;
@ -32,6 +35,8 @@ import java.util.LinkedList;
*/ */
public class Wizard { public class Wizard {
private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class);
private Deque<Command> undoStack = new LinkedList<>(); private Deque<Command> undoStack = new LinkedList<>();
private Deque<Command> redoStack = new LinkedList<>(); private Deque<Command> redoStack = new LinkedList<>();
@ -41,7 +46,7 @@ public class Wizard {
* Cast spell * Cast spell
*/ */
public void castSpell(Command command, Target target) { public void castSpell(Command command, Target target) {
System.out.println(this + " casts " + command + " at " + target); LOGGER.info("{} casts {} at {}", this, command, target);
command.execute(target); command.execute(target);
undoStack.offerLast(command); undoStack.offerLast(command);
} }
@ -53,7 +58,7 @@ public class Wizard {
if (!undoStack.isEmpty()) { if (!undoStack.isEmpty()) {
Command previousSpell = undoStack.pollLast(); Command previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell); redoStack.offerLast(previousSpell);
System.out.println(this + " undoes " + previousSpell); LOGGER.info("{} undoes {}", this, previousSpell);
previousSpell.undo(); previousSpell.undo();
} }
} }
@ -65,7 +70,7 @@ public class Wizard {
if (!redoStack.isEmpty()) { if (!redoStack.isEmpty()) {
Command previousSpell = redoStack.pollLast(); Command previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell); undoStack.offerLast(previousSpell);
System.out.println(this + " redoes " + previousSpell); LOGGER.info("{} redoes {}", this, previousSpell);
previousSpell.redo(); previousSpell.redo();
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.composite; package com.iluwatar.composite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* The Composite pattern is a partitioning design pattern. The Composite pattern describes that a * The Composite pattern is a partitioning design pattern. The Composite pattern describes that a
* group of objects is to be treated in the same way as a single instance of an object. The intent * group of objects is to be treated in the same way as a single instance of an object. The intent
@ -35,20 +38,22 @@ package com.iluwatar.composite;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Message from the orcs: "); LOGGER.info("Message from the orcs: ");
LetterComposite orcMessage = new Messenger().messageFromOrcs(); LetterComposite orcMessage = new Messenger().messageFromOrcs();
orcMessage.print(); orcMessage.print();
System.out.println("\n"); LOGGER.info("\n");
System.out.println("Message from the elves: "); LOGGER.info("Message from the elves: ");
LetterComposite elfMessage = new Messenger().messageFromElves(); LetterComposite elfMessage = new Messenger().messageFromElves();
elfMessage.print(); elfMessage.print();

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.decorator; package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Decorator pattern is a more flexible alternative to subclassing. The Decorator class * The Decorator pattern is a more flexible alternative to subclassing. The Decorator class
@ -36,6 +39,8 @@ package com.iluwatar.decorator;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -44,17 +49,17 @@ public class App {
public static void main(String[] args) { public static void main(String[] args) {
// simple troll // simple troll
System.out.println("A simple looking troll approaches."); LOGGER.info("A simple looking troll approaches.");
Hostile troll = new Troll(); Hostile troll = new Troll();
troll.attack(); troll.attack();
troll.fleeBattle(); troll.fleeBattle();
System.out.printf("Simple troll power %d.\n", troll.getAttackPower()); LOGGER.info("Simple troll power {}.\n", troll.getAttackPower());
// change the behavior of the simple troll by adding a decorator // change the behavior of the simple troll by adding a decorator
System.out.println("\nA smart looking troll surprises you."); LOGGER.info("A smart looking troll surprises you.");
Hostile smart = new SmartHostile(troll); Hostile smart = new SmartHostile(troll);
smart.attack(); smart.attack();
smart.fleeBattle(); smart.fleeBattle();
System.out.printf("Smart troll power %d.\n", smart.getAttackPower()); LOGGER.info("Smart troll power {}.\n", smart.getAttackPower());
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.decorator; package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface * SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface
* are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile} * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile}
@ -30,6 +33,8 @@ package com.iluwatar.decorator;
*/ */
public class SmartHostile implements Hostile { public class SmartHostile implements Hostile {
private static final Logger LOGGER = LoggerFactory.getLogger(SmartHostile.class);
private Hostile decorated; private Hostile decorated;
public SmartHostile(Hostile decorated) { public SmartHostile(Hostile decorated) {
@ -38,7 +43,7 @@ public class SmartHostile implements Hostile {
@Override @Override
public void attack() { public void attack() {
System.out.println("It throws a rock at you!"); LOGGER.info("It throws a rock at you!");
decorated.attack(); decorated.attack();
} }
@ -50,7 +55,7 @@ public class SmartHostile implements Hostile {
@Override @Override
public void fleeBattle() { public void fleeBattle() {
System.out.println("It calls for help!"); LOGGER.info("It calls for help!");
decorated.fleeBattle(); decorated.fleeBattle();
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.decorator; package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Troll implements {@link Hostile} interface directly. * Troll implements {@link Hostile} interface directly.
@ -29,9 +32,11 @@ package com.iluwatar.decorator;
*/ */
public class Troll implements Hostile { public class Troll implements Hostile {
private static final Logger LOGGER = LoggerFactory.getLogger(Troll.class);
@Override @Override
public void attack() { public void attack() {
System.out.println("The troll swings at you with a club!"); LOGGER.info("The troll swings at you with a club!");
} }
@Override @Override
@ -41,6 +46,6 @@ public class Troll implements Hostile {
@Override @Override
public void fleeBattle() { public void fleeBattle() {
System.out.println("The troll shrieks in horror and runs away!"); LOGGER.info("The troll shrieks in horror and runs away!");
} }
} }

View File

@ -22,16 +22,18 @@
*/ */
package com.iluwatar.decorator; package com.iluwatar.decorator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream; import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
/** /**
* Date: 12/7/15 - 7:26 PM * Date: 12/7/15 - 7:26 PM
@ -40,31 +42,16 @@ import static org.mockito.internal.verification.VerificationModeFactory.times;
*/ */
public class TrollTest { public class TrollTest {
/** private InMemoryAppender appender;
* The mocked standard out stream, required since the actions don't have any influence on other
* objects, except for writing to the std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before @Before
public void setUp() { public void setUp() {
System.setOut(this.stdOutMock); appender = new InMemoryAppender(Troll.class);
} }
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After @After
public void tearDown() { public void tearDown() {
System.setOut(this.stdOutOrig); appender.stop();
} }
@Test @Test
@ -73,12 +60,34 @@ public class TrollTest {
assertEquals(10, troll.getAttackPower()); assertEquals(10, troll.getAttackPower());
troll.attack(); troll.attack();
verify(this.stdOutMock, times(1)).println(eq("The troll swings at you with a club!")); assertEquals("The troll swings at you with a club!", appender.getLastMessage());
troll.fleeBattle(); troll.fleeBattle();
verify(this.stdOutMock, times(1)).println(eq("The troll shrieks in horror and runs away!")); assertEquals("The troll shrieks in horror and runs away!", appender.getLastMessage());
verifyNoMoreInteractions(this.stdOutMock); assertEquals(2, appender.getLogSize());
} }
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getMessage();
}
public int getLogSize() {
return log.size();
}
}
} }

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers; package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer; import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Specialised Implementation of {@link Printer} for a Canon Printer, in * Specialised Implementation of {@link Printer} for a Canon Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/ */
public class CanonPrinter implements Printer { public class CanonPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(CanonPrinter.class);
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void print(String message) { public void print(String message) {
System.out.print("Canon Printer : " + message); LOGGER.info("Canon Printer : {}", message);
} }
} }

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers; package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer; import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Specialised Implementation of {@link Printer} for a Epson Printer, in * Specialised Implementation of {@link Printer} for a Epson Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/ */
public class EpsonPrinter implements Printer { public class EpsonPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(EpsonPrinter.class);
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void print(String message) { public void print(String message) {
System.out.print("Epson Printer : " + message); LOGGER.info("Epson Printer : {}", message);
} }
} }

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers; package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer; import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Specialised Implementation of {@link Printer} for a HP Printer, in * Specialised Implementation of {@link Printer} for a HP Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/ */
public class HpPrinter implements Printer { public class HpPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(HpPrinter.class);
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void print(String message) { public void print(String message) {
System.out.print("HP Printer : " + message); LOGGER.info("HP Printer : {}", message);
} }
} }

View File

@ -22,28 +22,44 @@
*/ */
package com.iluwatar.delegation.simple; package com.iluwatar.delegation.simple;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import com.iluwatar.delegation.simple.printers.CanonPrinter; import com.iluwatar.delegation.simple.printers.CanonPrinter;
import com.iluwatar.delegation.simple.printers.EpsonPrinter; import com.iluwatar.delegation.simple.printers.EpsonPrinter;
import com.iluwatar.delegation.simple.printers.HpPrinter; import com.iluwatar.delegation.simple.printers.HpPrinter;
import org.junit.Rule; import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule; import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public class DelegateTest { public class DelegateTest {
private static final String MESSAGE = "Test Message Printed"; private InMemoryAppender appender;
@Rule @Before
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog(); public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
private static final String MESSAGE = "Test Message Printed";
@Test @Test
public void testCanonPrinter() throws Exception { public void testCanonPrinter() throws Exception {
PrinterController printerController = new PrinterController(new CanonPrinter()); PrinterController printerController = new PrinterController(new CanonPrinter());
printerController.print(MESSAGE); printerController.print(MESSAGE);
assertEquals("Canon Printer : Test Message Printed", systemOutRule.getLog()); assertEquals("Canon Printer : Test Message Printed", appender.getLastMessage());
} }
@Test @Test
@ -51,7 +67,7 @@ public class DelegateTest {
PrinterController printerController = new PrinterController(new HpPrinter()); PrinterController printerController = new PrinterController(new HpPrinter());
printerController.print(MESSAGE); printerController.print(MESSAGE);
assertEquals("HP Printer : Test Message Printed", systemOutRule.getLog()); assertEquals("HP Printer : Test Message Printed", appender.getLastMessage());
} }
@Test @Test
@ -59,7 +75,30 @@ public class DelegateTest {
PrinterController printerController = new PrinterController(new EpsonPrinter()); PrinterController printerController = new PrinterController(new EpsonPrinter());
printerController.print(MESSAGE); printerController.print(MESSAGE);
assertEquals("Epson Printer : Test Message Printed", systemOutRule.getLog()); assertEquals("Epson Printer : Test Message Printed", appender.getLastMessage());
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.dependency.injection; package com.iluwatar.dependency.injection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Tobacco abstraction * Tobacco abstraction
@ -29,8 +32,10 @@ package com.iluwatar.dependency.injection;
*/ */
public abstract class Tobacco { public abstract class Tobacco {
private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class);
public void smoke(Wizard wizard) { public void smoke(Wizard wizard) {
System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
.getClass().getSimpleName())); this.getClass().getSimpleName());
} }
} }

View File

@ -22,18 +22,31 @@
*/ */
package com.iluwatar.dependency.injection; package com.iluwatar.dependency.injection;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.mockito.Mockito.times; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/10/15 - 8:40 PM * Date: 12/10/15 - 8:40 PM
* *
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class AdvancedWizardTest extends StdOutTest { public class AdvancedWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/** /**
* Test if the {@link AdvancedWizard} smokes whatever instance of {@link Tobacco} is passed to him * Test if the {@link AdvancedWizard} smokes whatever instance of {@link Tobacco} is passed to him
@ -51,11 +64,12 @@ public class AdvancedWizardTest extends StdOutTest {
advancedWizard.smoke(); advancedWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ... // Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("AdvancedWizard smoking " + tobacco.getClass().getSimpleName()); assertEquals("AdvancedWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage());
}
// ... and nothing else is happening. // ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock()); assertEquals(tobaccos.length, appender.getLogSize());
}
} }

View File

@ -25,19 +25,31 @@ package com.iluwatar.dependency.injection;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.mockito.Mockito.times; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/10/15 - 8:57 PM * Date: 12/10/15 - 8:57 PM
* *
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class GuiceWizardTest extends StdOutTest { public class GuiceWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/** /**
* Test if the {@link GuiceWizard} smokes whatever instance of {@link Tobacco} is passed to him * Test if the {@link GuiceWizard} smokes whatever instance of {@link Tobacco} is passed to him
@ -55,12 +67,11 @@ public class GuiceWizardTest extends StdOutTest {
guiceWizard.smoke(); guiceWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ... // Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobacco.getClass().getSimpleName()); assertEquals("GuiceWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage());
// ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock());
} }
// ... and nothing else is happening.
assertEquals(tobaccos.length, appender.getLogSize());
} }
/** /**
@ -89,12 +100,11 @@ public class GuiceWizardTest extends StdOutTest {
guiceWizard.smoke(); guiceWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ... // Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobaccoClass.getSimpleName()); assertEquals("GuiceWizard smoking " + tobaccoClass.getSimpleName(), appender.getLastMessage());
// ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock());
} }
// ... and nothing else is happening.
assertEquals(tobaccos.length, appender.getLogSize());
} }
} }

View File

@ -22,16 +22,31 @@
*/ */
package com.iluwatar.dependency.injection; package com.iluwatar.dependency.injection;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.mockito.Mockito.*; import static org.junit.Assert.assertEquals;
/** /**
* Date: 12/10/15 - 8:26 PM * Date: 12/10/15 - 8:26 PM
* *
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class SimpleWizardTest extends StdOutTest { public class SimpleWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/** /**
* Test if the {@link SimpleWizard} does the only thing it can do: Smoke it's {@link * Test if the {@link SimpleWizard} does the only thing it can do: Smoke it's {@link
@ -41,8 +56,8 @@ public class SimpleWizardTest extends StdOutTest {
public void testSmoke() { public void testSmoke() {
final SimpleWizard simpleWizard = new SimpleWizard(); final SimpleWizard simpleWizard = new SimpleWizard();
simpleWizard.smoke(); simpleWizard.smoke();
verify(getStdOutMock(), times(1)).println("SimpleWizard smoking OldTobyTobacco"); assertEquals("SimpleWizard smoking OldTobyTobacco", appender.getLastMessage());
verifyNoMoreInteractions(getStdOutMock()); assertEquals(1, appender.getLogSize());
} }
} }

View File

@ -1,75 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.dependency.injection;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since the actions of the wizard don't
* have any influence on any other accessible objects, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.dependency.injection.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;
public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.doublechecked.locking; package com.iluwatar.doublechecked.locking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -40,6 +43,8 @@ import java.util.concurrent.TimeUnit;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -58,7 +63,7 @@ public class App {
try { try {
executorService.awaitTermination(5, TimeUnit.SECONDS); executorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println("Error waiting for ExecutorService shutdown"); LOGGER.error("Error waiting for ExecutorService shutdown");
} }
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.doublechecked.locking; package com.iluwatar.doublechecked.locking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -35,6 +38,8 @@ import java.util.concurrent.locks.ReentrantLock;
*/ */
public class Inventory { public class Inventory {
private static final Logger LOGGER = LoggerFactory.getLogger(Inventory.class);
private final int inventorySize; private final int inventorySize;
private final List<Item> items; private final List<Item> items;
private final Lock lock; private final Lock lock;
@ -57,8 +62,7 @@ public class Inventory {
try { try {
if (items.size() < inventorySize) { if (items.size() < inventorySize) {
items.add(item); items.add(item);
System.out.println(Thread.currentThread() + ": items.size()=" + items.size() LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items.size(), inventorySize);
+ ", inventorySize=" + inventorySize);
return true; return true;
} }
} finally { } finally {

View File

@ -0,0 +1,52 @@
<!--
The MIT License
Copyright (c) 2014 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>double-checked-locking.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>double-checked-locking-%d.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<logger name="com.iluwatar" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="FILE"/>
</logger>
<root level="WARN">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

View File

@ -22,24 +22,23 @@
*/ */
package com.iluwatar.doublechecked.locking; package com.iluwatar.doublechecked.locking;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.slf4j.LoggerFactory;
import java.io.PrintStream; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/10/15 - 9:34 PM * Date: 12/10/15 - 9:34 PM
@ -48,31 +47,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/ */
public class InventoryTest { public class InventoryTest {
/** private InMemoryAppender appender;
* The mocked standard out {@link PrintStream}, used to verify a steady increasing size of the
* {@link Inventory} while adding items from multiple threads concurrently
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before @Before
public void setUp() { public void setUp() {
System.setOut(this.stdOutMock); appender = new InMemoryAppender(Inventory.class);
} }
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After @After
public void tearDown() { public void tearDown() {
System.setOut(this.stdOutOrig); appender.stop();
} }
/** /**
@ -112,21 +96,32 @@ public class InventoryTest {
assertNotNull(items); assertNotNull(items);
assertEquals(INVENTORY_SIZE, items.size()); assertEquals(INVENTORY_SIZE, items.size());
// Capture all stdOut messages ... assertEquals(INVENTORY_SIZE, appender.getLogSize());
final ArgumentCaptor<String> stdOutCaptor = ArgumentCaptor.forClass(String.class);
verify(this.stdOutMock, times(INVENTORY_SIZE)).println(stdOutCaptor.capture());
// ... verify if we got all 1000
final List<String> values = stdOutCaptor.getAllValues();
assertEquals(INVENTORY_SIZE, values.size());
// ... and check if the inventory size is increasing continuously // ... and check if the inventory size is increasing continuously
for (int i = 0; i < values.size(); i++) { for (int i = 0; i < items.size(); i++) {
assertNotNull(values.get(i)); assertTrue(appender.log.get(i).getFormattedMessage().contains("items.size()=" + (i + 1)));
assertTrue(values.get(i).contains("items.size()=" + (i + 1))); }
} }
verifyNoMoreInteractions(this.stdOutMock);
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.doubledispatch; package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -45,6 +48,8 @@ import java.util.List;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -58,8 +63,8 @@ public class App {
objects.add(new SpaceStationMir(1, 1, 2, 2)); objects.add(new SpaceStationMir(1, 1, 2, 2));
objects.add(new Meteoroid(10, 10, 15, 15)); objects.add(new Meteoroid(10, 10, 15, 15));
objects.add(new SpaceStationIss(12, 12, 14, 14)); objects.add(new SpaceStationIss(12, 12, 14, 14));
objects.stream().forEach(o -> System.out.println(o)); objects.stream().forEach(o -> LOGGER.info(o.toString()));
System.out.println(""); LOGGER.info("");
// collision check // collision check
objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> {
@ -67,10 +72,10 @@ public class App {
o1.collision(o2); o1.collision(o2);
} }
})); }));
System.out.println(""); LOGGER.info("");
// output eventual object statuses // output eventual object statuses
objects.stream().forEach(o -> System.out.println(o)); objects.stream().forEach(o -> LOGGER.info(o.toString()));
System.out.println(""); LOGGER.info("");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.doubledispatch; package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Meteoroid game object * Meteoroid game object
@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch;
*/ */
public class Meteoroid extends GameObject { public class Meteoroid extends GameObject {
private static final Logger LOGGER = LoggerFactory.getLogger(Meteoroid.class);
public Meteoroid(int left, int top, int right, int bottom) { public Meteoroid(int left, int top, int right, int bottom) {
super(left, top, right, bottom); super(left, top, right, bottom);
} }
@ -40,25 +45,21 @@ public class Meteoroid extends GameObject {
@Override @Override
public void collisionResolve(FlamingAsteroid asteroid) { public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this LOGGER.info("{} hits {}.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName());
.getClass().getSimpleName()));
} }
@Override @Override
public void collisionResolve(Meteoroid meteoroid) { public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this LOGGER.info("{} hits {}.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName());
.getClass().getSimpleName()));
} }
@Override @Override
public void collisionResolve(SpaceStationMir mir) { public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass() LOGGER.info("{} hits {}.", mir.getClass().getSimpleName(), this.getClass().getSimpleName());
.getSimpleName()));
} }
@Override @Override
public void collisionResolve(SpaceStationIss iss) { public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass() LOGGER.info("{} hits {}.", iss.getClass().getSimpleName(), this.getClass().getSimpleName());
.getSimpleName()));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.doubledispatch; package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Space station Mir game object * Space station Mir game object
@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch;
*/ */
public class SpaceStationMir extends GameObject { public class SpaceStationMir extends GameObject {
private static final Logger LOGGER = LoggerFactory.getLogger(SpaceStationMir.class);
public SpaceStationMir(int left, int top, int right, int bottom) { public SpaceStationMir(int left, int top, int right, int bottom) {
super(left, top, right, bottom); super(left, top, right, bottom);
} }
@ -40,31 +45,30 @@ public class SpaceStationMir extends GameObject {
@Override @Override
public void collisionResolve(FlamingAsteroid asteroid) { public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid LOGGER.info("{} hits {}. {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(),
.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass() this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName());
.getSimpleName(), this.getClass().getSimpleName()));
setDamaged(true); setDamaged(true);
setOnFire(true); setOnFire(true);
} }
@Override @Override
public void collisionResolve(Meteoroid meteoroid) { public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass() LOGGER.info("{} hits {}. {} is damaged!", meteoroid.getClass().getSimpleName(),
.getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName())); this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true); setDamaged(true);
} }
@Override @Override
public void collisionResolve(SpaceStationMir mir) { public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(), LOGGER.info("{} hits {}. {} is damaged!", mir.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName())); this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true); setDamaged(true);
} }
@Override @Override
public void collisionResolve(SpaceStationIss iss) { public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(), LOGGER.info("{} hits {}. {} is damaged!", iss.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName())); this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true); setDamaged(true);
} }
} }

View File

@ -22,17 +22,9 @@
*/ */
package com.iluwatar.doubledispatch; package com.iluwatar.doubledispatch;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import java.util.Objects; import java.util.Objects;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/10/15 - 8:37 PM * Date: 12/10/15 - 8:37 PM
@ -41,43 +33,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/ */
public abstract class CollisionTest<O extends GameObject> { public abstract class CollisionTest<O extends GameObject> {
/**
* The mocked standard out {@link PrintStream}, required if some of the actions on the tested
* object don't have a direct influence on any other accessible objects, except for writing to
* std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
/** /**
* Get the tested object * Get the tested object
* *
@ -106,9 +61,6 @@ public abstract class CollisionTest<O extends GameObject> {
tested.collision(other); tested.collision(other);
verify(getStdOutMock(), times(1)).println(description);
verifyNoMoreInteractions(getStdOutMock());
testOnFire(other, tested, otherOnFire); testOnFire(other, tested, otherOnFire);
testDamaged(other, tested, otherDamaged); testDamaged(other, tested, otherDamaged);

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.event.aggregator; package com.iluwatar.event.aggregator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* KingJoffrey observes events from {@link KingsHand}. * KingJoffrey observes events from {@link KingsHand}.
@ -29,8 +32,10 @@ package com.iluwatar.event.aggregator;
*/ */
public class KingJoffrey implements EventObserver { public class KingJoffrey implements EventObserver {
private static final Logger LOGGER = LoggerFactory.getLogger(KingJoffrey.class);
@Override @Override
public void onEvent(Event e) { public void onEvent(Event e) {
System.out.println("Received event from the King's Hand: " + e.toString()); LOGGER.info("Received event from the King's Hand: {}", e.toString());
} }
} }

View File

@ -22,17 +22,18 @@
*/ */
package com.iluwatar.event.aggregator; package com.iluwatar.event.aggregator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream; import java.util.LinkedList;
import java.util.List;
import static org.mockito.Mockito.mock; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/12/15 - 3:04 PM * Date: 12/12/15 - 3:04 PM
@ -41,31 +42,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/ */
public class KingJoffreyTest { public class KingJoffreyTest {
/** private InMemoryAppender appender;
* The mocked standard out {@link PrintStream}, required since {@link KingJoffrey} does nothing
* except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before @Before
public void setUp() { public void setUp() {
System.setOut(this.stdOutMock); appender = new InMemoryAppender(KingJoffrey.class);
} }
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After @After
public void tearDown() { public void tearDown() {
System.setOut(this.stdOutOrig); appender.stop();
} }
/** /**
@ -75,15 +61,38 @@ public class KingJoffreyTest {
public void testOnEvent() { public void testOnEvent() {
final KingJoffrey kingJoffrey = new KingJoffrey(); final KingJoffrey kingJoffrey = new KingJoffrey();
for (final Event event : Event.values()) { for (int i = 0; i < Event.values().length; ++i) {
verifyZeroInteractions(this.stdOutMock); assertEquals(i, appender.getLogSize());
Event event = Event.values()[i];
kingJoffrey.onEvent(event); kingJoffrey.onEvent(event);
final String expectedMessage = "Received event from the King's Hand: " + event.toString(); final String expectedMessage = "Received event from the King's Hand: " + event.toString();
verify(this.stdOutMock, times(1)).println(expectedMessage); assertEquals(expectedMessage, appender.getLastMessage());
verifyNoMoreInteractions(this.stdOutMock); assertEquals(i + 1, appender.getLogSize());
} }
} }
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}
} }

View File

@ -16,6 +16,9 @@
*/ */
package com.iluwatar.event.asynchronous; package com.iluwatar.event.asynchronous;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Properties; import java.util.Properties;
@ -48,6 +51,8 @@ import java.util.Scanner;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static final String PROP_FILE_NAME = "config.properties"; public static final String PROP_FILE_NAME = "config.properties";
boolean interactiveMode = false; boolean interactiveMode = false;
@ -77,7 +82,7 @@ public class App {
try { try {
prop.load(inputStream); prop.load(inputStream);
} catch (IOException e) { } catch (IOException e) {
System.out.println(PROP_FILE_NAME + " was not found. Defaulting to non-interactive mode."); LOGGER.error("{} was not found. Defaulting to non-interactive mode.", PROP_FILE_NAME, e);
} }
String property = prop.getProperty("INTERACTIVE_MODE"); String property = prop.getProperty("INTERACTIVE_MODE");
if (property.equalsIgnoreCase("YES")) { if (property.equalsIgnoreCase("YES")) {
@ -106,27 +111,27 @@ public class App {
try { try {
// Create an Asynchronous event. // Create an Asynchronous event.
int aEventId = eventManager.createAsync(60); int aEventId = eventManager.createAsync(60);
System.out.println("Async Event [" + aEventId + "] has been created."); LOGGER.info("Async Event [{}] has been created.", aEventId);
eventManager.start(aEventId); eventManager.start(aEventId);
System.out.println("Async Event [" + aEventId + "] has been started."); LOGGER.info("Async Event [{}] has been started.", aEventId);
// Create a Synchronous event. // Create a Synchronous event.
int sEventId = eventManager.create(60); int sEventId = eventManager.create(60);
System.out.println("Sync Event [" + sEventId + "] has been created."); LOGGER.info("Sync Event [{}] has been created.", sEventId);
eventManager.start(sEventId); eventManager.start(sEventId);
System.out.println("Sync Event [" + sEventId + "] has been started."); LOGGER.info("Sync Event [{}] has been started.", sEventId);
eventManager.status(aEventId); eventManager.status(aEventId);
eventManager.status(sEventId); eventManager.status(sEventId);
eventManager.cancel(aEventId); eventManager.cancel(aEventId);
System.out.println("Async Event [" + aEventId + "] has been stopped."); LOGGER.info("Async Event [{}] has been stopped.", aEventId);
eventManager.cancel(sEventId); eventManager.cancel(sEventId);
System.out.println("Sync Event [" + sEventId + "] has been stopped."); LOGGER.info("Sync Event [{}] has been stopped.", sEventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) { | InvalidOperationException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
@ -139,58 +144,58 @@ public class App {
Scanner s = new Scanner(System.in); Scanner s = new Scanner(System.in);
int option = -1; int option = -1;
while (option != 4) { while (option != 4) {
System.out.println("Hello. Would you like to boil some eggs?"); LOGGER.info("Hello. Would you like to boil some eggs?");
System.out.println("(1) BOIL AN EGG \n(2) STOP BOILING THIS EGG \n(3) HOW ARE MY EGGS? \n(4) EXIT"); LOGGER.info("(1) BOIL AN EGG \n(2) STOP BOILING THIS EGG \n(3) HOW ARE MY EGGS? \n(4) EXIT");
System.out.print("Choose [1,2,3,4]: "); LOGGER.info("Choose [1,2,3,4]: ");
option = s.nextInt(); option = s.nextInt();
if (option == 1) { if (option == 1) {
s.nextLine(); s.nextLine();
System.out.print("Boil multiple eggs at once (A) or boil them one-by-one (S)?: "); LOGGER.info("Boil multiple eggs at once (A) or boil them one-by-one (S)?: ");
String eventType = s.nextLine(); String eventType = s.nextLine();
System.out.print("How long should this egg be boiled for (in seconds)?: "); LOGGER.info("How long should this egg be boiled for (in seconds)?: ");
int eventTime = s.nextInt(); int eventTime = s.nextInt();
if (eventType.equalsIgnoreCase("A")) { if (eventType.equalsIgnoreCase("A")) {
try { try {
int eventId = eventManager.createAsync(eventTime); int eventId = eventManager.createAsync(eventTime);
eventManager.start(eventId); eventManager.start(eventId);
System.out.println("Egg [" + eventId + "] is being boiled."); LOGGER.info("Egg [{}] is being boiled.", eventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} else if (eventType.equalsIgnoreCase("S")) { } else if (eventType.equalsIgnoreCase("S")) {
try { try {
int eventId = eventManager.create(eventTime); int eventId = eventManager.create(eventTime);
eventManager.start(eventId); eventManager.start(eventId);
System.out.println("Egg [" + eventId + "] is being boiled."); LOGGER.info("Egg [{}] is being boiled.", eventId);
} catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException } catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException
| EventDoesNotExistException e) { | EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} else { } else {
System.out.println("Unknown event type."); LOGGER.info("Unknown event type.");
} }
} else if (option == 2) { } else if (option == 2) {
System.out.print("Which egg?: "); LOGGER.info("Which egg?: ");
int eventId = s.nextInt(); int eventId = s.nextInt();
try { try {
eventManager.cancel(eventId); eventManager.cancel(eventId);
System.out.println("Egg [" + eventId + "] is removed from boiler."); LOGGER.info("Egg [{}] is removed from boiler.", eventId);
} catch (EventDoesNotExistException e) { } catch (EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} else if (option == 3) { } else if (option == 3) {
s.nextLine(); s.nextLine();
System.out.print("Just one egg (O) OR all of them (A) ?: "); LOGGER.info("Just one egg (O) OR all of them (A) ?: ");
String eggChoice = s.nextLine(); String eggChoice = s.nextLine();
if (eggChoice.equalsIgnoreCase("O")) { if (eggChoice.equalsIgnoreCase("O")) {
System.out.print("Which egg?: "); LOGGER.info("Which egg?: ");
int eventId = s.nextInt(); int eventId = s.nextInt();
try { try {
eventManager.status(eventId); eventManager.status(eventId);
} catch (EventDoesNotExistException e) { } catch (EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} else if (eggChoice.equalsIgnoreCase("A")) { } else if (eggChoice.equalsIgnoreCase("A")) {
eventManager.statusOfAllEvents(); eventManager.statusOfAllEvents();

View File

@ -16,6 +16,9 @@
*/ */
package com.iluwatar.event.asynchronous; package com.iluwatar.event.asynchronous;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Each Event runs as a separate/individual thread. * Each Event runs as a separate/individual thread.
@ -23,6 +26,8 @@ package com.iluwatar.event.asynchronous;
*/ */
public class Event implements IEvent, Runnable { public class Event implements IEvent, Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(Event.class);
private int eventId; private int eventId;
private int eventTime; private int eventTime;
private boolean isSynchronous; private boolean isSynchronous;
@ -63,9 +68,9 @@ public class Event implements IEvent, Runnable {
@Override @Override
public void status() { public void status() {
if (!isComplete) { if (!isComplete) {
System.out.println("[" + eventId + "] is not done."); LOGGER.info("[{}] is not done.", eventId);
} else { } else {
System.out.println("[" + eventId + "] is done."); LOGGER.info("[{}] is done.", eventId);
} }
} }

View File

@ -16,10 +16,12 @@
*/ */
package com.iluwatar.event.asynchronous; package com.iluwatar.event.asynchronous;
import static org.junit.Assert.assertTrue;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertTrue;
/** /**
* *
@ -29,6 +31,8 @@ import org.junit.Test;
public class EventAsynchronousTest { public class EventAsynchronousTest {
App app; App app;
private static final Logger LOGGER = LoggerFactory.getLogger(EventAsynchronousTest.class);
@Before @Before
public void setUp() { public void setUp() {
app = new App(); app = new App();
@ -46,7 +50,7 @@ public class EventAsynchronousTest {
eventManager.cancel(aEventId); eventManager.cancel(aEventId);
assertTrue(eventManager.getEventPool().size() == 0); assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
@ -63,7 +67,7 @@ public class EventAsynchronousTest {
assertTrue(eventManager.getEventPool().size() == 0); assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) { | InvalidOperationException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
@ -76,7 +80,7 @@ public class EventAsynchronousTest {
sEventId = eventManager.create(60); sEventId = eventManager.create(60);
eventManager.start(sEventId); eventManager.start(sEventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
@ -101,7 +105,7 @@ public class EventAsynchronousTest {
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) { | InvalidOperationException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
@ -129,7 +133,7 @@ public class EventAsynchronousTest {
assertTrue(eventManager.getEventPool().size() == 0); assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage()); LOGGER.error(e.getMessage());
} }
} }
} }

View File

@ -24,17 +24,19 @@ package com.iluwatar.eda.handler;
import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserCreatedEvent;
import com.iluwatar.eda.framework.Handler; import com.iluwatar.eda.framework.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Handles the {@link UserCreatedEvent} message. * Handles the {@link UserCreatedEvent} message.
*/ */
public class UserCreatedEventHandler implements Handler<UserCreatedEvent> { public class UserCreatedEventHandler implements Handler<UserCreatedEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserCreatedEventHandler.class);
@Override @Override
public void onEvent(UserCreatedEvent event) { public void onEvent(UserCreatedEvent event) {
LOGGER.info("User '{}' has been Created!", event.getUser().getUsername());
System.out.println(String.format(
"User '%s' has been Created!", event.getUser().getUsername()));
} }
} }

View File

@ -24,16 +24,18 @@ package com.iluwatar.eda.handler;
import com.iluwatar.eda.event.UserUpdatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent;
import com.iluwatar.eda.framework.Handler; import com.iluwatar.eda.framework.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Handles the {@link UserUpdatedEvent} message. * Handles the {@link UserUpdatedEvent} message.
*/ */
public class UserUpdatedEventHandler implements Handler<UserUpdatedEvent> { public class UserUpdatedEventHandler implements Handler<UserUpdatedEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserUpdatedEventHandler.class);
@Override @Override
public void onEvent(UserUpdatedEvent event) { public void onEvent(UserUpdatedEvent event) {
LOGGER.info("User '{}' has been Updated!", event.getUser().getUsername());
System.out.println(String.format(
"User '%s' has been Updated!", event.getUser().getUsername()));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.facade; package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* DwarvenCartOperator is one of the goldmine subsystems. * DwarvenCartOperator is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/ */
public class DwarvenCartOperator extends DwarvenMineWorker { public class DwarvenCartOperator extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenCartOperator.class);
@Override @Override
public void work() { public void work() {
System.out.println(name() + " moves gold chunks out of the mine."); LOGGER.info("{} moves gold chunks out of the mine.", name());
} }
@Override @Override

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.facade; package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* DwarvenGoldDigger is one of the goldmine subsystems. * DwarvenGoldDigger is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/ */
public class DwarvenGoldDigger extends DwarvenMineWorker { public class DwarvenGoldDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenGoldDigger.class);
@Override @Override
public void work() { public void work() {
System.out.println(name() + " digs for gold."); LOGGER.info("{} digs for gold.", name());
} }
@Override @Override

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.facade; package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* DwarvenMineWorker is one of the goldmine subsystems. * DwarvenMineWorker is one of the goldmine subsystems.
@ -29,20 +32,22 @@ package com.iluwatar.facade;
*/ */
public abstract class DwarvenMineWorker { public abstract class DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenMineWorker.class);
public void goToSleep() { public void goToSleep() {
System.out.println(name() + " goes to sleep."); LOGGER.info("{} goes to sleep.", name());
} }
public void wakeUp() { public void wakeUp() {
System.out.println(name() + " wakes up."); LOGGER.info("{} wakes up.", name());
} }
public void goHome() { public void goHome() {
System.out.println(name() + " goes home."); LOGGER.info("{} goes home.", name());
} }
public void goToMine() { public void goToMine() {
System.out.println(name() + " goes to the mine."); LOGGER.info("{} goes to the mine.", name());
} }
private void action(Action action) { private void action(Action action) {
@ -63,7 +68,7 @@ public abstract class DwarvenMineWorker {
work(); work();
break; break;
default: default:
System.out.println("Undefined action"); LOGGER.info("Undefined action");
break; break;
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.facade; package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* DwarvenTunnelDigger is one of the goldmine subsystems. * DwarvenTunnelDigger is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/ */
public class DwarvenTunnelDigger extends DwarvenMineWorker { public class DwarvenTunnelDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenTunnelDigger.class);
@Override @Override
public void work() { public void work() {
System.out.println(name() + " creates another promising tunnel."); LOGGER.info("{} creates another promising tunnel.", name());
} }
@Override @Override

View File

@ -22,17 +22,19 @@
*/ */
package com.iluwatar.facade; package com.iluwatar.facade;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream; import java.util.LinkedList;
import java.util.List;
import static org.mockito.Matchers.eq; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.internal.verification.VerificationModeFactory.times;
/** /**
* Date: 12/9/15 - 9:40 PM * Date: 12/9/15 - 9:40 PM
@ -41,32 +43,16 @@ import static org.mockito.internal.verification.VerificationModeFactory.times;
*/ */
public class DwarvenGoldmineFacadeTest { public class DwarvenGoldmineFacadeTest {
/** private InMemoryAppender appender;
* The mocked standard out {@link PrintStream}, required since the actions on the gold mine facade
* don't have any influence on any other accessible objects, except for writing to std-out using
* {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before @Before
public void setUp() { public void setUp() {
System.setOut(this.stdOutMock); appender = new InMemoryAppender();
} }
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After @After
public void tearDown() { public void tearDown() {
System.setOut(this.stdOutOrig); appender.stop();
} }
/** /**
@ -82,44 +68,68 @@ public class DwarvenGoldmineFacadeTest {
goldMine.startNewDay(); goldMine.startNewDay();
// On the start of a day, all workers should wake up ... // On the start of a day, all workers should wake up ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger wakes up.")); assertTrue(appender.logContains("Dwarf gold digger wakes up."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator wakes up.")); assertTrue(appender.logContains("Dwarf cart operator wakes up."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger wakes up.")); assertTrue(appender.logContains("Dwarven tunnel digger wakes up."));
// ... and go to the mine // ... and go to the mine
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes to the mine.")); assertTrue(appender.logContains("Dwarf gold digger goes to the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to the mine.")); assertTrue(appender.logContains("Dwarf cart operator goes to the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes to the mine.")); assertTrue(appender.logContains("Dwarven tunnel digger goes to the mine."));
// No other actions were invoked, so the workers shouldn't have done (printed) anything else // No other actions were invoked, so the workers shouldn't have done (printed) anything else
verifyNoMoreInteractions(this.stdOutMock); assertEquals(6, appender.getLogSize());
// Now do some actual work, start digging gold! // Now do some actual work, start digging gold!
goldMine.digOutGold(); goldMine.digOutGold();
// Since we gave the dig command, every worker should be doing it's job ... // Since we gave the dig command, every worker should be doing it's job ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger digs for gold.")); assertTrue(appender.logContains("Dwarf gold digger digs for gold."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator moves gold chunks out of the mine.")); assertTrue(appender.logContains("Dwarf cart operator moves gold chunks out of the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger creates another promising tunnel.")); assertTrue(appender.logContains("Dwarven tunnel digger creates another promising tunnel."));
// Again, they shouldn't be doing anything else. // Again, they shouldn't be doing anything else.
verifyNoMoreInteractions(this.stdOutMock); assertEquals(9, appender.getLogSize());
// Enough gold, lets end the day. // Enough gold, lets end the day.
goldMine.endDay(); goldMine.endDay();
// Check if the workers go home ... // Check if the workers go home ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes home.")); assertTrue(appender.logContains("Dwarf gold digger goes home."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes home.")); assertTrue(appender.logContains("Dwarf cart operator goes home."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes home.")); assertTrue(appender.logContains("Dwarven tunnel digger goes home."));
// ... and go to sleep. We need well rested workers the next day :) // ... and go to sleep. We need well rested workers the next day :)
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes to sleep.")); assertTrue(appender.logContains("Dwarf gold digger goes to sleep."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to sleep.")); assertTrue(appender.logContains("Dwarf cart operator goes to sleep."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes to sleep.")); assertTrue(appender.logContains("Dwarven tunnel digger goes to sleep."));
// Every worker should be sleeping now, no other actions allowed // Every worker should be sleeping now, no other actions allowed
verifyNoMoreInteractions(this.stdOutMock); assertEquals(15, appender.getLogSize());
} }
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
public boolean logContains(String message) {
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
}
}
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Factory-kit is a creational pattern which defines a factory of immutable content * Factory-kit is a creational pattern which defines a factory of immutable content
* with separated builder and factory interfaces to deal with the problem of * with separated builder and factory interfaces to deal with the problem of
@ -36,6 +39,9 @@ package com.iluwatar.factorykit;
* be mapped explicitly with desired class type in the factory instance. * be mapped explicitly with desired class type in the factory instance.
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point. * Program entry point.
* *
@ -49,6 +55,6 @@ public class App {
builder.add(WeaponType.BOW, Bow::new); builder.add(WeaponType.BOW, Bow::new);
}); });
Weapon axe = factory.create(WeaponType.AXE); Weapon axe = factory.create(WeaponType.AXE);
System.out.println(axe); LOGGER.info(axe.toString());
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.factory.method; package com.iluwatar.factory.method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Factory Method is a creational design pattern which uses factory methods to deal with the * The Factory Method is a creational design pattern which uses factory methods to deal with the
@ -38,6 +41,8 @@ package com.iluwatar.factory.method;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private final Blacksmith blacksmith; private final Blacksmith blacksmith;
/** /**
@ -70,8 +75,8 @@ public class App {
private void manufactureWeapons() { private void manufactureWeapons() {
Weapon weapon; Weapon weapon;
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
System.out.println(weapon); LOGGER.info(weapon.toString());
weapon = blacksmith.manufactureWeapon(WeaponType.AXE); weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
System.out.println(weapon); LOGGER.info(weapon.toString());
} }
} }

View File

@ -27,6 +27,8 @@ import com.iluwatar.featuretoggle.pattern.Service;
import com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion; import com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion;
import com.iluwatar.featuretoggle.user.User; import com.iluwatar.featuretoggle.user.User;
import com.iluwatar.featuretoggle.user.UserGroup; import com.iluwatar.featuretoggle.user.UserGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties; import java.util.Properties;
@ -45,6 +47,8 @@ import java.util.Properties;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Block 1 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature * Block 1 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature
* toggle to enabled. * toggle to enabled.
@ -70,7 +74,7 @@ public class App {
properties.put("enhancedWelcome", true); properties.put("enhancedWelcome", true);
Service service = new PropertiesFeatureToggleVersion(properties); Service service = new PropertiesFeatureToggleVersion(properties);
final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code"));
System.out.println(welcomeMessage); LOGGER.info(welcomeMessage);
// --------------------------------------------- // ---------------------------------------------
@ -78,7 +82,7 @@ public class App {
turnedOff.put("enhancedWelcome", false); turnedOff.put("enhancedWelcome", false);
Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff); Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff);
final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code")); final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code"));
System.out.println(welcomeMessageturnedOff); LOGGER.info(welcomeMessageturnedOff);
// -------------------------------------------- // --------------------------------------------
@ -90,7 +94,7 @@ public class App {
final String welcomeMessagePaidUser = service.getWelcomeMessage(paidUser); final String welcomeMessagePaidUser = service.getWelcomeMessage(paidUser);
final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser); final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser);
System.out.println(welcomeMessageFreeUser); LOGGER.info(welcomeMessageFreeUser);
System.out.println(welcomeMessagePaidUser); LOGGER.info(welcomeMessagePaidUser);
} }
} }

View File

@ -35,6 +35,8 @@ import java.util.function.Predicate;
import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable; import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable;
import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable; import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. * The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API.
@ -50,6 +52,8 @@ import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -74,9 +78,7 @@ public class App {
.fromCopyOf(integerList) .fromCopyOf(integerList)
.filter(number -> number % 2 == 0) .filter(number -> number % 2 == 0)
.first() .first()
.ifPresent( .ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber));
evenNumber -> System.out.println(String.format("The first even number is: %d",
evenNumber)));
List<String> transformedList = List<String> transformedList =
@ -97,9 +99,7 @@ public class App {
.filter(negatives()) .filter(negatives())
.first(2) .first(2)
.last() .last()
.ifPresent( .ifPresent(lastOfFirstTwo -> LOGGER.info("The last of the first two negatives is: {}", lastOfFirstTwo));
lastOfFirstTwo -> System.out.println(String.format(
"The last of the first two negatives is: %d", lastOfFirstTwo)));
} }
private static Function<Integer, String> transformToString() { private static Function<Integer, String> transformToString() {
@ -126,6 +126,6 @@ public class App {
joiner.add(iterator.next().toString()); joiner.add(iterator.next().toString());
} }
System.out.println(joiner); LOGGER.info(joiner.toString());
} }
} }

View File

@ -25,6 +25,8 @@ package com.iluwatar.flux.view;
import com.iluwatar.flux.action.Content; import com.iluwatar.flux.action.Content;
import com.iluwatar.flux.store.ContentStore; import com.iluwatar.flux.store.ContentStore;
import com.iluwatar.flux.store.Store; import com.iluwatar.flux.store.Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
@ -33,6 +35,8 @@ import com.iluwatar.flux.store.Store;
*/ */
public class ContentView implements View { public class ContentView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ContentView.class);
private Content content = Content.PRODUCTS; private Content content = Content.PRODUCTS;
@Override @Override
@ -44,6 +48,6 @@ public class ContentView implements View {
@Override @Override
public void render() { public void render() {
System.out.println(content.toString()); LOGGER.info(content.toString());
} }
} }

View File

@ -26,6 +26,8 @@ import com.iluwatar.flux.action.MenuItem;
import com.iluwatar.flux.dispatcher.Dispatcher; import com.iluwatar.flux.dispatcher.Dispatcher;
import com.iluwatar.flux.store.MenuStore; import com.iluwatar.flux.store.MenuStore;
import com.iluwatar.flux.store.Store; import com.iluwatar.flux.store.Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
@ -34,6 +36,8 @@ import com.iluwatar.flux.store.Store;
*/ */
public class MenuView implements View { public class MenuView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(MenuView.class);
private MenuItem selected = MenuItem.HOME; private MenuItem selected = MenuItem.HOME;
@Override @Override
@ -47,9 +51,9 @@ public class MenuView implements View {
public void render() { public void render() {
for (MenuItem item : MenuItem.values()) { for (MenuItem item : MenuItem.values()) {
if (selected.equals(item)) { if (selected.equals(item)) {
System.out.println(String.format("* %s", item.toString())); LOGGER.info("* {}", item);
} else { } else {
System.out.println(item.toString()); LOGGER.info(item.toString());
} }
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -33,6 +36,8 @@ import java.util.List;
*/ */
public class AlchemistShop { public class AlchemistShop {
private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class);
private List<Potion> topShelf; private List<Potion> topShelf;
private List<Potion> bottomShelf; private List<Potion> bottomShelf;
@ -88,13 +93,13 @@ public class AlchemistShop {
*/ */
public void enumerate() { public void enumerate() {
System.out.println("Enumerating top shelf potions\n"); LOGGER.info("Enumerating top shelf potions\n");
for (Potion p : topShelf) { for (Potion p : topShelf) {
p.drink(); p.drink();
} }
System.out.println("\nEnumerating bottom shelf potions\n"); LOGGER.info("Enumerating bottom shelf potions\n");
for (Potion p : bottomShelf) { for (Potion p : bottomShelf) {
p.drink(); p.drink();

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* HealingPotion * HealingPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/ */
public class HealingPotion implements Potion { public class HealingPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(HealingPotion.class);
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel healed. (Potion=" + System.identityHashCode(this) + ")"); LOGGER.info("You feel healed. (Potion={})", System.identityHashCode(this));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* HolyWaterPotion * HolyWaterPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/ */
public class HolyWaterPotion implements Potion { public class HolyWaterPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(HolyWaterPotion.class);
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel blessed. (Potion=" + System.identityHashCode(this) + ")"); LOGGER.info("You feel blessed. (Potion={})", System.identityHashCode(this));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* InvisibilityPotion * InvisibilityPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/ */
public class InvisibilityPotion implements Potion { public class InvisibilityPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(InvisibilityPotion.class);
@Override @Override
public void drink() { public void drink() {
System.out.println("You become invisible. (Potion=" + System.identityHashCode(this) + ")"); LOGGER.info("You become invisible. (Potion={})", System.identityHashCode(this));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* PoisonPotion * PoisonPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/ */
public class PoisonPotion implements Potion { public class PoisonPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(PoisonPotion.class);
@Override @Override
public void drink() { public void drink() {
System.out.println("Urgh! This is poisonous. (Potion=" + System.identityHashCode(this) + ")"); LOGGER.info("Urgh! This is poisonous. (Potion={})", System.identityHashCode(this));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.flyweight; package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* StrengthPotion * StrengthPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/ */
public class StrengthPotion implements Potion { public class StrengthPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(StrengthPotion.class);
@Override @Override
public void drink() { public void drink() {
System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")"); LOGGER.info("You feel strong. (Potion={})", System.identityHashCode(this));
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* View for archers. * View for archers.
@ -29,8 +32,10 @@ package com.iluwatar.front.controller;
*/ */
public class ArcherView implements View { public class ArcherView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ArcherView.class);
@Override @Override
public void display() { public void display() {
System.out.println("Displaying archers"); LOGGER.info("Displaying archers");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* View for catapults. * View for catapults.
@ -29,8 +32,10 @@ package com.iluwatar.front.controller;
*/ */
public class CatapultView implements View { public class CatapultView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(CatapultView.class);
@Override @Override
public void display() { public void display() {
System.out.println("Displaying catapults"); LOGGER.info("Displaying catapults");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* View for errors. * View for errors.
@ -29,8 +32,10 @@ package com.iluwatar.front.controller;
*/ */
public class ErrorView implements View { public class ErrorView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorView.class);
@Override @Override
public void display() { public void display() {
System.out.println("Error 500"); LOGGER.error("Error 500");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.mockito.Mockito.verify; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/** /**
* Date: 12/13/15 - 1:39 PM * Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class CommandTest extends StdOutTest { public class CommandTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters @Parameters
public static List<Object[]> data() { public static List<Object[]> data() {
@ -75,10 +88,10 @@ public class CommandTest extends StdOutTest {
@Test @Test
public void testDisplay() { public void testDisplay() {
final FrontController frontController = new FrontController(); final FrontController frontController = new FrontController();
verifyZeroInteractions(getStdOutMock()); assertEquals(0, appender.getLogSize());
frontController.handleRequest(request); frontController.handleRequest(request);
verify(getStdOutMock()).println(displayMessage); assertEquals(displayMessage, appender.getLastMessage());
verifyNoMoreInteractions(getStdOutMock()); assertEquals(1, appender.getLogSize());
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.mockito.Mockito.verify; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/** /**
* Date: 12/13/15 - 1:39 PM * Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class FrontControllerTest extends StdOutTest { public class FrontControllerTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters @Parameters
public static List<Object[]> data() { public static List<Object[]> data() {
@ -74,10 +87,10 @@ public class FrontControllerTest extends StdOutTest {
@Test @Test
public void testDisplay() { public void testDisplay() {
verifyZeroInteractions(getStdOutMock()); assertEquals(0, appender.getLogSize());
this.command.process(); this.command.process();
verify(getStdOutMock()).println(displayMessage); assertEquals(displayMessage, appender.getLastMessage());
verifyNoMoreInteractions(getStdOutMock()); assertEquals(1, appender.getLogSize());
} }
} }

View File

@ -1,76 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.front.controller;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since the actions of the views don't have
* any influence on any other accessible objects, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.front.controller; package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.mockito.Mockito.verify; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/** /**
* Date: 12/13/15 - 1:39 PM * Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class ViewTest extends StdOutTest { public class ViewTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters @Parameters
public static List<Object[]> data() { public static List<Object[]> data() {
@ -74,10 +87,10 @@ public class ViewTest extends StdOutTest {
@Test @Test
public void testDisplay() { public void testDisplay() {
verifyZeroInteractions(getStdOutMock()); assertEquals(0, appender.getLogSize());
this.view.display(); this.view.display();
verify(getStdOutMock()).println(displayMessage); assertEquals(displayMessage, appender.getLastMessage());
verifyNoMoreInteractions(getStdOutMock()); assertEquals(1, appender.getLogSize());
} }
} }

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.front.controller.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;
public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.halfsynchalfasync; package com.iluwatar.halfsynchalfasync;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
/** /**
@ -66,6 +69,8 @@ import java.util.concurrent.LinkedBlockingQueue;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -128,7 +133,7 @@ public class App {
@Override @Override
public void onPostCall(Long result) { public void onPostCall(Long result) {
// Handle the result of computation // Handle the result of computation
System.out.println(result); LOGGER.info(result.toString());
} }
@Override @Override
@ -141,7 +146,7 @@ public class App {
try { try {
Thread.sleep(i); Thread.sleep(i);
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println(e); LOGGER.error("Exception caught.", e);
} }
return i * (i + 1) / 2; return i * (i + 1) / 2;
} }

View File

@ -30,6 +30,8 @@ import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.module.LotteryModule; import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
import com.iluwatar.hexagonal.sampledata.SampleData; import com.iluwatar.hexagonal.sampledata.SampleData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Scanner; import java.util.Scanner;
@ -38,6 +40,8 @@ import java.util.Scanner;
*/ */
public class ConsoleAdministration { public class ConsoleAdministration {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleAdministration.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -53,29 +57,29 @@ public class ConsoleAdministration {
printMainMenu(); printMainMenu();
String cmd = readString(scanner); String cmd = readString(scanner);
if (cmd.equals("1")) { if (cmd.equals("1")) {
administartion.getAllSubmittedTickets().forEach((k,v)->System.out.println("Key: " + k + " Value: " + v)); administartion.getAllSubmittedTickets().forEach((k,v)->LOGGER.info("Key: {}, Value: {}", k, v));
} else if (cmd.equals("2")) { } else if (cmd.equals("2")) {
LotteryNumbers numbers = administartion.performLottery(); LotteryNumbers numbers = administartion.performLottery();
System.out.println("The winning numbers: " + numbers.getNumbersAsString()); LOGGER.info("The winning numbers: {}", numbers.getNumbersAsString());
System.out.println("Time to reset the database for next round, eh?"); LOGGER.info("Time to reset the database for next round, eh?");
} else if (cmd.equals("3")) { } else if (cmd.equals("3")) {
administartion.resetLottery(); administartion.resetLottery();
System.out.println("The lottery ticket database was cleared."); LOGGER.info("The lottery ticket database was cleared.");
} else if (cmd.equals("4")) { } else if (cmd.equals("4")) {
exit = true; exit = true;
} else { } else {
System.out.println("Unknown command: " + cmd); LOGGER.info("Unknown command: {}", cmd);
} }
} }
} }
private static void printMainMenu() { private static void printMainMenu() {
System.out.println(""); LOGGER.info("");
System.out.println("### Lottery Administration Console ###"); LOGGER.info("### Lottery Administration Console ###");
System.out.println("(1) Show all submitted tickets"); LOGGER.info("(1) Show all submitted tickets");
System.out.println("(2) Perform lottery draw"); LOGGER.info("(2) Perform lottery draw");
System.out.println("(3) Reset lottery ticket database"); LOGGER.info("(3) Reset lottery ticket database");
System.out.println("(4) Exit"); LOGGER.info("(4) Exit");
} }
private static String readString(Scanner scanner) { private static String readString(Scanner scanner) {

View File

@ -23,42 +23,42 @@
package com.iluwatar.hexagonal.eventlog; package com.iluwatar.hexagonal.eventlog;
import com.iluwatar.hexagonal.domain.PlayerDetails; import com.iluwatar.hexagonal.domain.PlayerDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Standard output event log * Standard output event log
*/ */
public class StdOutEventLog implements LotteryEventLog { public class StdOutEventLog implements LotteryEventLog {
private static final Logger LOGGER = LoggerFactory.getLogger(StdOutEventLog.class);
@Override @Override
public void ticketSubmitted(PlayerDetails details) { public void ticketSubmitted(PlayerDetails details) {
System.out.println(String.format("Lottery ticket for %s was submitted. Bank account %s was charged for 3 credits.", LOGGER.info("Lottery ticket for {} was submitted. Bank account {} was charged for 3 credits.",
details.getEmail(), details.getBankAccount())); details.getEmail(), details.getBankAccount());
} }
@Override @Override
public void ticketDidNotWin(PlayerDetails details) { public void ticketDidNotWin(PlayerDetails details) {
System.out.println(String.format("Lottery ticket for %s was checked and unfortunately did not win this time.", LOGGER.info("Lottery ticket for {} was checked and unfortunately did not win this time.", details.getEmail());
details.getEmail()));
} }
@Override @Override
public void ticketWon(PlayerDetails details, int prizeAmount) { public void ticketWon(PlayerDetails details, int prizeAmount) {
System.out LOGGER.info("Lottery ticket for {} has won! The bank account {} was deposited with {} credits.",
.println(String.format("Lottery ticket for %s has won! The bank account %s was deposited with %d credits.", details.getEmail(), details.getBankAccount(), prizeAmount);
details.getEmail(), details.getBankAccount(), prizeAmount));
} }
@Override @Override
public void prizeError(PlayerDetails details, int prizeAmount) { public void prizeError(PlayerDetails details, int prizeAmount) {
System.out LOGGER.error("Lottery ticket for {} has won! Unfortunately the bank credit transfer of {} failed.",
.println(String.format("Lottery ticket for %s has won! Unfortunately the bank credit transfer of %d failed.", details.getEmail(), prizeAmount);
details.getEmail(), prizeAmount));
} }
@Override @Override
public void ticketSubmitError(PlayerDetails details) { public void ticketSubmitError(PlayerDetails details) {
System.out.println( LOGGER.error("Lottery ticket for {} could not be submitted because the credit transfer of 3 credits failed.",
String.format("Lottery ticket for %s could not be submitted because the credit transfer of 3 credits failed.", details.getEmail());
details.getEmail()));
} }
} }

View File

@ -33,6 +33,8 @@ import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.domain.PlayerDetails; import com.iluwatar.hexagonal.domain.PlayerDetails;
import com.iluwatar.hexagonal.module.LotteryModule; import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
@ -44,6 +46,7 @@ import java.util.Set;
*/ */
public class ConsoleLottery { public class ConsoleLottery {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleLottery.class);
/** /**
* Program entry point * Program entry point
@ -59,25 +62,25 @@ public class ConsoleLottery {
printMainMenu(); printMainMenu();
String cmd = readString(scanner); String cmd = readString(scanner);
if (cmd.equals("1")) { if (cmd.equals("1")) {
System.out.println("What is the account number?"); LOGGER.info("What is the account number?");
String account = readString(scanner); String account = readString(scanner);
System.out.println(String.format("The account %s has %d credits.", account, bank.getFunds(account))); LOGGER.info("The account {} has {} credits.", account, bank.getFunds(account));
} else if (cmd.equals("2")) { } else if (cmd.equals("2")) {
System.out.println("What is the account number?"); LOGGER.info("What is the account number?");
String account = readString(scanner); String account = readString(scanner);
System.out.println("How many credits do you want to deposit?"); LOGGER.info("How many credits do you want to deposit?");
String amount = readString(scanner); String amount = readString(scanner);
bank.setFunds(account, Integer.parseInt(amount)); bank.setFunds(account, Integer.parseInt(amount));
System.out.println(String.format("The account %s now has %d credits.", account, bank.getFunds(account))); LOGGER.info("The account {} now has {} credits.", account, bank.getFunds(account));
} else if (cmd.equals("3")) { } else if (cmd.equals("3")) {
System.out.println("What is your email address?"); LOGGER.info("What is your email address?");
String email = readString(scanner); String email = readString(scanner);
System.out.println("What is your bank account number?"); LOGGER.info("What is your bank account number?");
String account = readString(scanner); String account = readString(scanner);
System.out.println("What is your phone number?"); LOGGER.info("What is your phone number?");
String phone = readString(scanner); String phone = readString(scanner);
PlayerDetails details = new PlayerDetails(email, account, phone); PlayerDetails details = new PlayerDetails(email, account, phone);
System.out.println("Give 4 comma separated lottery numbers?"); LOGGER.info("Give 4 comma separated lottery numbers?");
String numbers = readString(scanner); String numbers = readString(scanner);
try { try {
String[] parts = numbers.split(","); String[] parts = numbers.split(",");
@ -89,17 +92,17 @@ public class ConsoleLottery {
LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers); LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers);
Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket); Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket);
if (id.isPresent()) { if (id.isPresent()) {
System.out.println("Submitted lottery ticket with id: " + id.get()); LOGGER.info("Submitted lottery ticket with id: {}", id.get());
} else { } else {
System.out.println("Failed submitting lottery ticket - please try again."); LOGGER.info("Failed submitting lottery ticket - please try again.");
} }
} catch (Exception e) { } catch (Exception e) {
System.out.println("Failed submitting lottery ticket - please try again."); LOGGER.info("Failed submitting lottery ticket - please try again.");
} }
} else if (cmd.equals("4")) { } else if (cmd.equals("4")) {
System.out.println("What is the ID of the lottery ticket?"); LOGGER.info("What is the ID of the lottery ticket?");
String id = readString(scanner); String id = readString(scanner);
System.out.println("Give the 4 comma separated winning numbers?"); LOGGER.info("Give the 4 comma separated winning numbers?");
String numbers = readString(scanner); String numbers = readString(scanner);
try { try {
String[] parts = numbers.split(","); String[] parts = numbers.split(",");
@ -110,31 +113,31 @@ public class ConsoleLottery {
LotteryTicketCheckResult result = service.checkTicketForPrize( LotteryTicketCheckResult result = service.checkTicketForPrize(
new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers)); new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers));
if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) { if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) {
System.out.println("Congratulations! The lottery ticket has won!"); LOGGER.info("Congratulations! The lottery ticket has won!");
} else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) { } else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) {
System.out.println("Unfortunately the lottery ticket did not win."); LOGGER.info("Unfortunately the lottery ticket did not win.");
} else { } else {
System.out.println("Such lottery ticket has not been submitted."); LOGGER.info("Such lottery ticket has not been submitted.");
} }
} catch (Exception e) { } catch (Exception e) {
System.out.println("Failed checking the lottery ticket - please try again."); LOGGER.info("Failed checking the lottery ticket - please try again.");
} }
} else if (cmd.equals("5")) { } else if (cmd.equals("5")) {
exit = true; exit = true;
} else { } else {
System.out.println("Unknown command"); LOGGER.info("Unknown command");
} }
} }
} }
private static void printMainMenu() { private static void printMainMenu() {
System.out.println(""); LOGGER.info("");
System.out.println("### Lottery Service Console ###"); LOGGER.info("### Lottery Service Console ###");
System.out.println("(1) Query lottery account funds"); LOGGER.info("(1) Query lottery account funds");
System.out.println("(2) Add funds to lottery account"); LOGGER.info("(2) Add funds to lottery account");
System.out.println("(3) Submit ticket"); LOGGER.info("(3) Submit ticket");
System.out.println("(4) Check ticket"); LOGGER.info("(4) Check ticket");
System.out.println("(5) Exit"); LOGGER.info("(5) Exit");
} }
private static String readString(Scanner scanner) { private static String readString(Scanner scanner) {

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.interpreter; package com.iluwatar.interpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Stack; import java.util.Stack;
/** /**
@ -37,6 +40,8 @@ import java.util.Stack;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* *
* Program entry point. * Program entry point.
@ -56,21 +61,21 @@ public class App {
if (isOperator(s)) { if (isOperator(s)) {
Expression rightExpression = stack.pop(); Expression rightExpression = stack.pop();
Expression leftExpression = stack.pop(); Expression leftExpression = stack.pop();
System.out.println(String.format("popped from stack left: %d right: %d", LOGGER.info("popped from stack left: {} right: {}",
leftExpression.interpret(), rightExpression.interpret())); leftExpression.interpret(), rightExpression.interpret());
Expression operator = getOperatorInstance(s, leftExpression, rightExpression); Expression operator = getOperatorInstance(s, leftExpression, rightExpression);
System.out.println(String.format("operator: %s", operator)); LOGGER.info("operator: {}", operator);
int result = operator.interpret(); int result = operator.interpret();
NumberExpression resultExpression = new NumberExpression(result); NumberExpression resultExpression = new NumberExpression(result);
stack.push(resultExpression); stack.push(resultExpression);
System.out.println(String.format("push result to stack: %d", resultExpression.interpret())); LOGGER.info("push result to stack: {}", resultExpression.interpret());
} else { } else {
Expression i = new NumberExpression(s); Expression i = new NumberExpression(s);
stack.push(i); stack.push(i);
System.out.println(String.format("push to stack: %d", i.interpret())); LOGGER.info("push to stack: {}", i.interpret());
} }
} }
System.out.println(String.format("result: %d", stack.pop().interpret())); LOGGER.info("result: {}", stack.pop().interpret());
} }
public static boolean isOperator(String s) { public static boolean isOperator(String s) {

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.iterator; package com.iluwatar.iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* The Iterator pattern is a design pattern in which an iterator is used to traverse a container and * The Iterator pattern is a design pattern in which an iterator is used to traverse a container and
@ -34,6 +37,8 @@ package com.iluwatar.iterator;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -44,28 +49,28 @@ public class App {
ItemIterator ringIterator = chest.iterator(ItemType.RING); ItemIterator ringIterator = chest.iterator(ItemType.RING);
while (ringIterator.hasNext()) { while (ringIterator.hasNext()) {
System.out.println(ringIterator.next()); LOGGER.info(ringIterator.next().toString());
} }
System.out.println("----------"); LOGGER.info("----------");
ItemIterator potionIterator = chest.iterator(ItemType.POTION); ItemIterator potionIterator = chest.iterator(ItemType.POTION);
while (potionIterator.hasNext()) { while (potionIterator.hasNext()) {
System.out.println(potionIterator.next()); LOGGER.info(potionIterator.next().toString());
} }
System.out.println("----------"); LOGGER.info("----------");
ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON); ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON);
while (weaponIterator.hasNext()) { while (weaponIterator.hasNext()) {
System.out.println(weaponIterator.next()); LOGGER.info(weaponIterator.next().toString());
} }
System.out.println("----------"); LOGGER.info("----------");
ItemIterator it = chest.iterator(ItemType.ANY); ItemIterator it = chest.iterator(ItemType.ANY);
while (it.hasNext()) { while (it.hasNext()) {
System.out.println(it.next()); LOGGER.info(it.next().toString());
} }
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.layers; package com.iluwatar.layers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* View implementation for displaying cakes * View implementation for displaying cakes
@ -29,6 +32,8 @@ package com.iluwatar.layers;
*/ */
public class CakeViewImpl implements View { public class CakeViewImpl implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class);
private CakeBakingService cakeBakingService; private CakeBakingService cakeBakingService;
public CakeViewImpl(CakeBakingService cakeBakingService) { public CakeViewImpl(CakeBakingService cakeBakingService) {
@ -36,6 +41,6 @@ public class CakeViewImpl implements View {
} }
public void render() { public void render() {
cakeBakingService.getAllCakes().stream().forEach(cake -> System.out.println(cake)); cakeBakingService.getAllCakes().stream().forEach(cake -> LOGGER.info(cake.toString()));
} }
} }

View File

@ -0,0 +1,57 @@
<!--
The MIT License
Copyright (c) 2014 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>layers.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>layers-%d.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<logger name="com.iluwatar" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="FILE"/>
</logger>
<logger name="org.hibernate" additivity="false">
<level value="ERROR"/>
<appender-ref ref="STDOUT"/>
</logger>
<root level="WARN">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

View File

@ -22,11 +22,19 @@
*/ */
package com.iluwatar.layers; package com.iluwatar.layers;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
/** /**
@ -34,7 +42,19 @@ import static org.mockito.Mockito.*;
* *
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class CakeViewImplTest extends StdOutTest { public class CakeViewImplTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(CakeViewImpl.class);
}
@After
public void tearDown() {
appender.stop();
}
/** /**
* Verify if the cake view renders the expected result * Verify if the cake view renders the expected result
@ -56,11 +76,34 @@ public class CakeViewImplTest extends StdOutTest {
final CakeViewImpl cakeView = new CakeViewImpl(bakingService); final CakeViewImpl cakeView = new CakeViewImpl(bakingService);
verifyZeroInteractions(getStdOutMock()); assertEquals(0, appender.getLogSize());
cakeView.render(); cakeView.render();
verify(getStdOutMock(), times(1)).println(cake); assertEquals(cake.toString(), appender.getLastMessage());
} }
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}
} }

View File

@ -1,76 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.layers;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import static org.mockito.Mockito.mock;
/**
* Date: 12/10/15 - 8:37 PM
*
* @author Jeroen Meulemeester
*/
public abstract class StdOutTest {
/**
* The mocked standard out {@link PrintStream}, required since the actions of the views don't have
* any influence on any other accessible objects, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/**
* Get the mocked stdOut {@link PrintStream}
*
* @return The stdOut print stream mock, renewed before each test
*/
final PrintStream getStdOutMock() {
return this.stdOutMock;
}
}

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.lazy.loading; package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Lazy loading idiom defers object creation until needed. * Lazy loading idiom defers object creation until needed.
@ -33,6 +36,9 @@ package com.iluwatar.lazy.loading;
* *
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
* *
@ -43,16 +49,16 @@ public class App {
// Simple lazy loader - not thread safe // Simple lazy loader - not thread safe
HolderNaive holderNaive = new HolderNaive(); HolderNaive holderNaive = new HolderNaive();
Heavy heavy = holderNaive.getHeavy(); Heavy heavy = holderNaive.getHeavy();
System.out.println("heavy=" + heavy); LOGGER.info("heavy={}", heavy);
// Thread safe lazy loader, but with heavy synchronization on each access // Thread safe lazy loader, but with heavy synchronization on each access
HolderThreadSafe holderThreadSafe = new HolderThreadSafe(); HolderThreadSafe holderThreadSafe = new HolderThreadSafe();
Heavy another = holderThreadSafe.getHeavy(); Heavy another = holderThreadSafe.getHeavy();
System.out.println("another=" + another); LOGGER.info("another={}", another);
// The most efficient lazy loader utilizing Java 8 features // The most efficient lazy loader utilizing Java 8 features
Java8Holder java8Holder = new Java8Holder(); Java8Holder java8Holder = new Java8Holder();
Heavy next = java8Holder.getHeavy(); Heavy next = java8Holder.getHeavy();
System.out.println("next=" + next); LOGGER.info("next={}", next);
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.lazy.loading; package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Heavy objects are expensive to create. * Heavy objects are expensive to create.
@ -29,16 +32,18 @@ package com.iluwatar.lazy.loading;
*/ */
public class Heavy { public class Heavy {
private static final Logger LOGGER = LoggerFactory.getLogger(Heavy.class);
/** /**
* Constructor * Constructor
*/ */
public Heavy() { public Heavy() {
System.out.println("Creating Heavy ..."); LOGGER.info("Creating Heavy ...");
try { try {
Thread.sleep(1000); Thread.sleep(1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); LOGGER.error("Exception caught.", e);
} }
System.out.println("... Heavy created"); LOGGER.info("... Heavy created");
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.lazy.loading; package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Simple implementation of the lazy loading idiom. However, this is not thread safe. * Simple implementation of the lazy loading idiom. However, this is not thread safe.
@ -29,13 +32,15 @@ package com.iluwatar.lazy.loading;
*/ */
public class HolderNaive { public class HolderNaive {
private static final Logger LOGGER = LoggerFactory.getLogger(HolderNaive.class);
private Heavy heavy; private Heavy heavy;
/** /**
* Constructor * Constructor
*/ */
public HolderNaive() { public HolderNaive() {
System.out.println("HolderNaive created"); LOGGER.info("HolderNaive created");
} }
/** /**

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.lazy.loading; package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Same as HolderNaive but with added synchronization. This implementation is thread safe, but each * Same as HolderNaive but with added synchronization. This implementation is thread safe, but each
@ -30,13 +33,15 @@ package com.iluwatar.lazy.loading;
*/ */
public class HolderThreadSafe { public class HolderThreadSafe {
private static final Logger LOGGER = LoggerFactory.getLogger(HolderThreadSafe.class);
private Heavy heavy; private Heavy heavy;
/** /**
* Constructor * Constructor
*/ */
public HolderThreadSafe() { public HolderThreadSafe() {
System.out.println("HolderThreadSafe created"); LOGGER.info("HolderThreadSafe created");
} }
/** /**

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.lazy.loading; package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier; import java.util.function.Supplier;
/** /**
@ -32,10 +35,12 @@ import java.util.function.Supplier;
*/ */
public class Java8Holder { public class Java8Holder {
private static final Logger LOGGER = LoggerFactory.getLogger(Java8Holder.class);
private Supplier<Heavy> heavy = () -> createAndCacheHeavy(); private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
public Java8Holder() { public Java8Holder() {
System.out.println("Java8Holder created"); LOGGER.info("Java8Holder created");
} }
public Heavy getHeavy() { public Heavy getHeavy() {

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.mediator; package com.iluwatar.mediator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* Abstract base class for party members. * Abstract base class for party members.
@ -29,23 +32,25 @@ package com.iluwatar.mediator;
*/ */
public abstract class PartyMemberBase implements PartyMember { public abstract class PartyMemberBase implements PartyMember {
private static final Logger LOGGER = LoggerFactory.getLogger(PartyMemberBase.class);
protected Party party; protected Party party;
@Override @Override
public void joinedParty(Party party) { public void joinedParty(Party party) {
System.out.println(this + " joins the party"); LOGGER.info("{} joins the party", this);
this.party = party; this.party = party;
} }
@Override @Override
public void partyAction(Action action) { public void partyAction(Action action) {
System.out.println(this + " " + action.getDescription()); LOGGER.info("{} {}", this, action.getDescription());
} }
@Override @Override
public void act(Action action) { public void act(Action action) {
if (party != null) { if (party != null) {
System.out.println(this + " " + action.toString()); LOGGER.info("{} {}", this, action);
party.act(this, action); party.act(this, action);
} }
} }

View File

@ -22,22 +22,25 @@
*/ */
package com.iluwatar.mediator; package com.iluwatar.mediator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/** /**
* Date: 12/19/15 - 10:13 PM * Date: 12/19/15 - 10:13 PM
@ -57,34 +60,6 @@ public class PartyMemberTest {
); );
} }
/**
* The mocked standard out {@link PrintStream}, required since some actions on a {@link
* PartyMember} have any influence on any other accessible objects, except for writing to std-out
* using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before
public void setUp() {
System.setOut(this.stdOutMock);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
}
/** /**
* The factory, used to create a new instance of the tested party member * The factory, used to create a new instance of the tested party member
*/ */
@ -99,6 +74,18 @@ public class PartyMemberTest {
this.memberSupplier = memberSupplier; this.memberSupplier = memberSupplier;
} }
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(PartyMemberBase.class);
}
@After
public void tearDown() {
appender.stop();
}
/** /**
* Verify if a party action triggers the correct output to the std-Out * Verify if a party action triggers the correct output to the std-Out
*/ */
@ -108,10 +95,10 @@ public class PartyMemberTest {
for (final Action action : Action.values()) { for (final Action action : Action.values()) {
member.partyAction(action); member.partyAction(action);
verify(this.stdOutMock).println(member.toString() + " " + action.getDescription()); assertEquals(member.toString() + " " + action.getDescription(), appender.getLastMessage());
} }
verifyNoMoreInteractions(this.stdOutMock); assertEquals(Action.values().length, appender.getLogSize());
} }
/** /**
@ -122,19 +109,19 @@ public class PartyMemberTest {
final PartyMember member = this.memberSupplier.get(); final PartyMember member = this.memberSupplier.get();
member.act(Action.GOLD); member.act(Action.GOLD);
verifyZeroInteractions(this.stdOutMock); assertEquals(0, appender.getLogSize());
final Party party = mock(Party.class); final Party party = mock(Party.class);
member.joinedParty(party); member.joinedParty(party);
verify(this.stdOutMock).println(member.toString() + " joins the party"); assertEquals(member.toString() + " joins the party", appender.getLastMessage());
for (final Action action : Action.values()) { for (final Action action : Action.values()) {
member.act(action); member.act(action);
verify(this.stdOutMock).println(member.toString() + " " + action.toString()); assertEquals(member.toString() + " " + action.toString(), appender.getLastMessage());
verify(party).act(member, action); verify(party).act(member, action);
} }
verifyNoMoreInteractions(party, this.stdOutMock); assertEquals(Action.values().length + 1, appender.getLogSize());
} }
/** /**
@ -147,4 +134,27 @@ public class PartyMemberTest {
assertEquals(memberClass.getSimpleName(), member.toString()); assertEquals(memberClass.getSimpleName(), member.toString());
} }
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
}
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.memento; package com.iluwatar.memento;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Stack; import java.util.Stack;
/** /**
@ -45,6 +48,8 @@ import java.util.Stack;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -52,22 +57,22 @@ public class App {
Stack<StarMemento> states = new Stack<>(); Stack<StarMemento> states = new Stack<>();
Star star = new Star(StarType.SUN, 10000000, 500000); Star star = new Star(StarType.SUN, 10000000, 500000);
System.out.println(star); LOGGER.info(star.toString());
states.add(star.getMemento()); states.add(star.getMemento());
star.timePasses(); star.timePasses();
System.out.println(star); LOGGER.info(star.toString());
states.add(star.getMemento()); states.add(star.getMemento());
star.timePasses(); star.timePasses();
System.out.println(star); LOGGER.info(star.toString());
states.add(star.getMemento()); states.add(star.getMemento());
star.timePasses(); star.timePasses();
System.out.println(star); LOGGER.info(star.toString());
states.add(star.getMemento()); states.add(star.getMemento());
star.timePasses(); star.timePasses();
System.out.println(star); LOGGER.info(star.toString());
while (states.size() > 0) { while (states.size() > 0) {
star.setMemento(states.pop()); star.setMemento(states.pop());
System.out.println(star); LOGGER.info(star.toString());
} }
} }
} }

View File

@ -25,6 +25,8 @@ package com.iluwatar.message.channel;
import org.apache.camel.CamelContext; import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.impl.DefaultCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
@ -50,6 +52,8 @@ import org.apache.camel.impl.DefaultCamelContext;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point
*/ */
@ -66,7 +70,7 @@ public class App {
}); });
context.start(); context.start();
context.getRoutes().stream().forEach(r -> System.out.println(r)); context.getRoutes().stream().forEach(r -> LOGGER.info(r.toString()));
context.stop(); context.stop();
} }
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.model.view.controller; package com.iluwatar.model.view.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* *
* GiantView displays the giant * GiantView displays the giant
@ -29,7 +32,9 @@ package com.iluwatar.model.view.controller;
*/ */
public class GiantView { public class GiantView {
private static final Logger LOGGER = LoggerFactory.getLogger(GiantView.class);
public void displayGiant(GiantModel giant) { public void displayGiant(GiantModel giant) {
System.out.println(giant); LOGGER.info(giant.toString());
} }
} }

View File

@ -22,15 +22,19 @@
*/ */
package com.iluwatar.model.view.controller; package com.iluwatar.model.view.controller;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream; import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/** /**
* Date: 12/20/15 - 2:04 PM * Date: 12/20/15 - 2:04 PM
@ -39,32 +43,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/ */
public class GiantViewTest { public class GiantViewTest {
/** private InMemoryAppender appender;
* The mocked standard out {@link PrintStream}, required since the actions of the views don't have
* any influence on any other accessible objects, except for writing to std-out using {@link
* System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
/**
* Keep the original std-out so it can be restored after the test
*/
private final PrintStream stdOutOrig = System.out;
/**
* Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test
*/
@Before @Before
public void setUp() { public void setUp() {
System.setOut(this.stdOutMock); appender = new InMemoryAppender(GiantView.class);
} }
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After @After
public void tearDown() { public void tearDown() {
System.setOut(this.stdOutOrig); appender.stop();
} }
/** /**
@ -78,9 +66,29 @@ public class GiantViewTest {
final GiantModel model = mock(GiantModel.class); final GiantModel model = mock(GiantModel.class);
view.displayGiant(model); view.displayGiant(model);
verify(this.stdOutMock).println(model); assertEquals(model.toString(), appender.getLastMessage());
verifyNoMoreInteractions(model, this.stdOutMock); assertEquals(1, appender.getLogSize());
} }
public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getMessage();
}
public int getLogSize() {
return log.size();
}
}
} }

View File

@ -22,6 +22,9 @@
*/ */
package com.iluwatar.monad; package com.iluwatar.monad;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -42,6 +45,8 @@ import java.util.function.Predicate;
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point. * Program entry point.
* *
@ -49,7 +54,7 @@ public class App {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
User user = new User("user", 24, Sex.FEMALE, "foobar.com"); User user = new User("user", 24, Sex.FEMALE, "foobar.com");
System.out.println(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null") LOGGER.info(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null")
.validate(User::getName, name -> !name.isEmpty(), "name is empty") .validate(User::getName, name -> !name.isEmpty(), "name is empty")
.validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'") .validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'")
.validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get().toString()); .validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get().toString());

Some files were not shown because too many files have changed in this diff Show More